Drupal 7: отправка Webform через Ajax
На одном из проектов на Drupal 7 встала задача отправлять форму без перезагрузки страницы с уведомлением через модальное окно с подключенной Google Captcha, да ещё и кастомизированной темизацией. В статье буду приводить полученный код, и ссылки, которыми воспользовался в процессе.
Первая страница с которой началось моё изучение данной задачи это статья xandeadx:
Отправить Webform-у с помощью AJAX, в результате чего в своём кастомном модуле я реализовал следующие хуки:
/**
* Implements hook_form_FORM_ID_alter(): webform_client_form_17.
*/
function custom_form_webform_client_form_17_alter(&$form, &$form_state) {
$form['#attributes']['class'][] = 'support-form'; // добавляем класс формы
$form['actions']['submit']['#attributes']['class'] = ['theme-btn'];
// здесь всё, что касается ajax-а
$form['actions']['submit']['#ajax'] = array(
'callback' => 'custom_form_webform_client_form_ajax_submit',
'wrapper' => $form['#id'],
);
$form['#attached']['js'][] = drupal_get_path("module", "custom")."/js/custom.js" ;
//$form['actions']['submit']['#attributes']['class'][] = '';
// Удаляем #pre_render, иначе не будет работать ajax
unset($form['actions']['submit']['#pre_render']);
}
Приведённый ваше код добавлял ajax-обработчик для кнопки submit-а и в качестве обработчика указывал функцию custom_form_webform_client_form_ajax_submit. Также в папку с кастомным модулем мы добаляем файл custom.js. В данном обработчике в случае ошибок мы возвращаем саму форму, а в случае успешной отправки формы мы выполняем опять же через ajax кастомную функцию responseForm, которая очищает поля и показывает модальное окно с сообщением об успешной или неуспешной отправки формы. Код функции реализован в подключенном файле custom.js.
Код кастомной функции:
(function($) {
/**
* Special Effects AJAX framework command.
*/
Drupal.ajax.prototype.commands.responseForm = function(ajax, response, status) {
if (status == 'success'){
$('button.success').click();
$("#webform-client-form-17 input[type='text'], #webform-client-form-17 textarea").val('');
$("#webform-client-form-17 div.error").hide();
$("#webform-client-form-17 input.error").removeClass('error');
} else{
$('button.error').click();
}
}
}(jQuery));
Данный код $('button.success').click(); показывает модальное окно с сообщением о статусе отправленного сообщения, используя Bootstrap API.
HTML код:
Собственно после этого всё заработало!
Но у этого метода правда обнаружился недостаток один. Если форма отправляется с ошибками, то при повторной отправке в случае правильного заполнения форма не обнуляется. Поэтому функцию custom_form_webform_client_form_ajax_submit нужно немного переделать:
/**
* Ajax submit.
*/
function custom_form_webform_client_form_ajax_submit($form, &$form_state) {
if (form_get_errors()) {
return $form;
}
else {
// Выводим сообщеньку, если нужно
drupal_set_message(t('Your message has been successfully sent! Thank you!'));
// Смотрим кеш чистой формы
$form = form_get_cache($form_state['input']['form_build_id'], $form_state);
// Сбрасываем заполненные значения
$form_state['input'] = array();
// Грузим и возвращаем форму
return form_builder($form['#form_id'], $form, $form_state);
}
}
Также нужно обратить внимание на следующий момент. После выполнения AJAX-запроса может потребоваться заново задать те или иные настройки с помощью различных JS-скриптов. Например, маска для ввода телефона в полях форм, установленная с помощью плагина jquery.maskedinput.min.js слетает. Восстановить это можно следующим образом.
$(document).ajaxStop(function() {
jQuery("input[name='submitted[phone]']").mask("+7(999) 999-9999");
});
В этом случае форма корректно обнуляется и отправляется уже с нужным сообщением.
Ссылки которые оказали мне неоценимую помощь в понимании этого:
http://xandeadx.ru/blog/drupal/492
http://xandeadx.ru/blog/drupal/378
http://www.maged.me/blog/drupal-7-execute-javascript-code-after-ajax-call https://blogpost.pp.ua/drupal/118
http://drupalace.ru/lesson/zastavlyaem-lyubuyu-formu-vypolnyatsya-cherez-ajax-v-drupal-7