Как выполнить JS до и после AJAX события

Как выполнить JS до и после AJAX события

В данной статье мы рассмотрим проблемы вызова js эвентов до и после срабатывания ajax событий.

Содержание

Вызов js эвента после ajax

Задача легко решается с помощью Ajax API. Для этого нам понадобится функция ajax_command_invoke(). Эта функция вызывает invoke команду, т.е. jQuery-ский код на стороне клиента для элементов, у которых есть соответствующий селектор. Предназначен для простых команд jQuery, таких как: attr(), addClass(), removeClass(), toggleClass() и т.д.
Итак, код нашей простой формы следующий:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function MYMODULE_test_form() {
 $form['text'] = array(
   '#type'  => 'textfield',
   '#title'   => t('Text'),
   '#default_value' => '',
   '#maxlength' => 64,
   '#attributes' => array(
     'id' => 'MYSELECTOR',
   ),
 );
 
 $form['#attached']['js'][]  = drupal_get_path('module', 'MYMODULE') . '/js/MYMODULE.js';
 $form['actions']['submit'] = array(
   '#type'  => 'submit',
   '#value' => t('Ajax button'),
   '#ajax'  => array(
     'callback' => 'MYMODULE_ajax_callback',
   ),
 );
 
 return $form;
}

Опишем аякс колбэк. Здесь, для примера, получаем текущее время и передаем его для последующей вставки в html с помощью аякса и с помощью js функции.

1
2
3
4
5
6
function MYMODULE_ajax_callback($form, $form_state) {
 $date = new DateTime();
 $commands[] = ajax_command_after('#MYSELECTOR', $date->getTimestamp());
 $commands[] = ajax_command_invoke('#MYSELECTOR', 'myJsFunction', array($date));
 return array('#type' => 'ajax', '#commands' => $commands);
}

Js файл будет содержать следующий код:

1
2
3
4
5
6
(function($) {
 $.fn.myJsFunction = function(data) {
   var div = $('<div/>').text(data.date);
   div.insertAfter($('#MYSELECTOR'));
 };
})(jQuery);

Результат срабатывания событий приведен на изображении ниже.
js после ajax события

Вызов js эвента до ajax

На самом деле, задача сводится к замене порядка вызова команд ajax_command_after() и ajax_command_invoke(), т.е.

1
2
3
4
5
6
function MYMODULE_ajax_callback($form, $form_state) {
 $date = new DateTime();
 $commands[] = ajax_command_invoke('#MYSELECTOR', 'myJsFunction', array($date));
 $commands[] = ajax_command_after('#MYSELECTOR', $date->getTimestamp());
 return array('#type' => 'ajax', '#commands' => $commands);
}

Теперь мы получаем ситуацию, когда js отрабатывает первым и вставляет время в полном формате времени (напомним, ajax получает время в формате timestamp).
js до ajax события
Также можно повесить обработчик событий на аяксовую кнопку. Но будьте внимательны (!), onlcik() у вас работать не будет, т.к. это событие уже используется ajax фреймворком. Поэтому, навешивайте эвенты, отличные от onclick(), например, mousedown(), mouseup() и т.д.
Еще одна из проблем, которая может возникнуть - это предотвратить вызов ajax (например, сделать кнопку неактивной до тех пор, пока пользователь не заполнит определенное поле). Т.е. в данной ситуации можно сделать следующее:

  • Добавить атрибут disable для кнопки ajax сразу при загрузке страницы.
  • Добавить событие на изменение поля change() и отслеживать изменения текста в поле. Если данные введены - убирать атрибут disable, если поле пустое - добавлять его (атрибут) снова

Дополнительная информация по статье

  1. https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_command_invoke/7 - описание функции и входных аргументов для ajax_command_invoke() из официальной документации.
  2. https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_command_after/7 - описание функции и входных аргументов для ajax_command_after() из официальной документации.
  3. https://api.drupal.org/api/drupal/includes!ajax.inc/7 - список функций, используемых Drupal Ajax фреймворком.