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