Как выполнить JS до и после AJAX события
Опубликовано пт, 17/07/2015 - 23:55
В данной статье мы рассмотрим проблемы вызова 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
На самом деле, задача сводится к замене порядка вызова команд 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).
Также можно повесить обработчик событий на аяксовую кнопку. Но будьте внимательны (!), onlcik() у вас работать не будет, т.к. это событие уже используется ajax фреймворком. Поэтому, навешивайте эвенты, отличные от onclick(), например, mousedown(), mouseup() и т.д.
Еще одна из проблем, которая может возникнуть - это предотвратить вызов ajax (например, сделать кнопку неактивной до тех пор, пока пользователь не заполнит определенное поле). Т.е. в данной ситуации можно сделать следующее:
- Добавить атрибут disable для кнопки ajax сразу при загрузке страницы.
- Добавить событие на изменение поля change() и отслеживать изменения текста в поле. Если данные введены - убирать атрибут disable, если поле пустое - добавлять его (атрибут) снова
Дополнительная информация по статье
- https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_command_invoke/7 - описание функции и входных аргументов для ajax_command_invoke() из официальной документации.
- https://api.drupal.org/api/drupal/includes!ajax.inc/function/ajax_command_after/7 - описание функции и входных аргументов для ajax_command_after() из официальной документации.
- https://api.drupal.org/api/drupal/includes!ajax.inc/7 - список функций, используемых Drupal Ajax фреймворком.