6

I'm trying to figure out AJAX in Drupal 8.

I have a custom module that works, using AJAX to change the content of a div when a link is clicked.

The API says:

Many different events can trigger Ajax responses, including:

Clicking a button Pressing a key Moving the mouse

How do I trigger the same process that Drupal's AJAX does when a function is called from a JavaScript object's event firing instead?

JavaScript Object

function calledOnSomeEvent(e) {
  String data = e.target.data;
  // do something to call AJAX with the data
}

The AJAX backend works with this route:

myModule.routing.yml

myModule.myRoute:
  path: '/nojs/myFunction/{myParameter}'
  defaults:
    _controller: '\Drupal\myModule\MyController::myFunctionCallback'
    _title: 'myFunction'
  requirements:
    _permission: 'access content'

HTML

<a href="nojs/myFunction/testData" class="use-ajax">Click for testData!</a>

My understanding is that Drupal injects some sort of event when that link is clicked, or the URL is just changed, and the controller is only activated when that URL is changed.

JavaScript

(function($, Drupal) {

  Drupal.AjaxCommands.prototype.myFunction = function(ajax, response, status){

    $('#targetDiv').html(response.data);
  }

})(jQuery, Drupal);

I omitted PHP code for the controller, which creates a command. The command renders the output to Drupal.AjaxCommands.prototype.myFunction, which updates the div.

Is an XMLHttpRequest the only way to make JavaScript interact with the route/PHP? If so, what path should be used?

I think there might be a way for JavaScript interact with Drupal's AJAX handler to call the same function that clicking the link changed with "use-ajax" does, since that's being handled in some way...

Any insight would be appreciated.

Thanks!

11

If you don't want to ajaxify the link with "use-ajax" and trigger an Ajax request programmatically use:

Drupal.ajax({url: endpoint}).execute();

This creates an Ajax object with the endpoint as url and executes it.

More options you'll find in the comments of Drupal.ajax in ajax.js:

/**
   * Provides Ajax page updating via jQuery $.ajax.
   *
   * This function is designed to improve developer experience by wrapping the
   * initialization of {@link Drupal.Ajax} objects and storing all created
   * objects in the {@link Drupal.ajax.instances} array.
   *
   * @example
   * Drupal.behaviors.myCustomAJAXStuff = {
   *   attach: function (context, settings) {
   *
   *     var ajaxSettings = {
   *       url: 'my/url/path',
   *       // If the old version of Drupal.ajax() needs to be used those
   *       // properties can be added
   *       base: 'myBase',
   *       element: $(context).find('.someElement')
   *     };
   *
   *     var myAjaxObject = Drupal.ajax(ajaxSettings);
   *
   *     // Declare a new Ajax command specifically for this Ajax object.
   *     myAjaxObject.commands.insert = function (ajax, response, status) {
   *       $('#my-wrapper').append(response.data);
   *       alert('New content was appended to #my-wrapper');
   *     };
   *
   *     // This command will remove this Ajax object from the page.
   *     myAjaxObject.commands.destroyObject = function (ajax, response, status) {
   *       Drupal.ajax.instances[this.instanceIndex] = null;
   *     };
   *
   *     // Programmatically trigger the Ajax request.
   *     myAjaxObject.execute();
   *   }
   * };
   *
   * @param {object} settings
   *   The settings object passed to {@link Drupal.Ajax} constructor.
   * @param {string} [settings.base]
   *   Base is passed to {@link Drupal.Ajax} constructor as the 'base'
   *   parameter.
   * @param {HTMLElement} [settings.element]
   *   Element parameter of {@link Drupal.Ajax} constructor, element on which
   *   event listeners will be bound.
   *
   * @return {Drupal.Ajax}
   *   The created Ajax object.
   *
   * @see Drupal.AjaxCommands
   */
  Drupal.ajax = function (settings) {

Your second question, is an XMLHttpRequest the only way to make JavaScript interact with the route/PHP? If so, what path should be used?

You can use a normal non drupal jQuery.ajax(), then you have no restrictions for the format, you can use json (which Drupal uses for it's own ajax) or any other format. You can set up a route for an arbitrary path and use this in $.ajax().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.