Многим известно, что в Drupal'е есть собственный ajax-фреймворк, который использует в качестве ответов, так называемые, команды. Сами запросы могут быть инициированы разными способами:

  1. Присвоив класс use-ajax на любой тэг (на стороне сервера или на стороне клиента, но перед инициализацией Drupal js части). В базовом использовании этого варианта есть обязательное условие - тэг должен иметь атрибут href содержащий путь, на который будет выполнен ajax запрос.
  2. Определив параметр #ajax в форме (на стороне сервера).
  3. Присвоив параметр use-ajax-submit форме (тэг form). Это что-то среднее между п.1 и п.2.
  4. Инициировав new Drupal.ajax() (на стороне клиента)

Изменение поведения ajax-обработчика

Рассмотрим пример с ссылкой, на которой есть класс use-ajax. Мы будет изменять состояние bootstrap кнопки на момент выполнения запроса - пример.
Наша вымышленная страница содержит такой тэг:

<a class="use-ajax btn btn-primary" data-loading-text="Saving..." href="/save-something">Save</a>

Здесь data-loading-text="Saving..." говорит бутатрапу, что в момент выполнения запроса на кнопке должен отображаться текст "Saving...". Так ссылка уже будет работать как через ajax, но для нашего трюка необходимо присвоить id этому тэгу. Например, MYMODULE-save-link.

<a class="use-ajax btn btn-primary" data-loading-text="Saving..." href="/mymodule-callback" id="MYMODULE-save-link">Save</a>

Теперь перейдем к JS части.

/**
 * @file
 * Javascript for MYMODULE module.
 */
(function ($, Drupal) {
  "use strict";
  /**
   * Behavior for MYMODULE module
   */
  Drupal.behaviors.MYMODULE = {
    attach: function (context, settings) {
      if (typeof Drupal.ajax['MYMODULE-save-link'] != 'undefined') {
        var ajax = Drupal.ajax['MYMODULE-save-link'];
        // Сохраняем функции обратного вызова, назначенные друпалом.
        ajax.savedBeforeSend = ajax.beforeSend;
        ajax.savedSuccess = ajax.success;

        // Заменяем их на свои.
        ajax.beforeSend = function (xmlhttprequest, options) {
          // Изменяем состояние кнопки перед запросом.
          $(this.element).button('loading');
          // Но не забываем вызывать сохраненные функции. Они нужны для правильной работы.
          ajax.savedBeforeSend(xmlhttprequest, options);
        };

        ajax.success = function (response, status) {
         // Нативная функциональность должна выполняться раньше произвольной.
          var result = ajax.savedSuccess(response, status);
          // Сбрасываем состояние кнопки после завершения запроса.
          $(this.element).button('reset');
          return result;
        };
      }
    }
  };
})(jQuery, Drupal);

Чтобы все это заработало, на сайте необходимо иметь bootstrap.

Результат

Save-bootstrap

Другие посты