Недавно мне потребовалось реализовать сабмит формы по AJAX. При этом форма должна загружаться в попапе. Казалось бы задача тривиальная, но оказалось что все же есть подводные камни.
Задача решается для Drupal 7. В качестве библиотеки для создания popup'ов используется fancybox.
Сперва нужно подключить необходимые библиотеки:
$path = drupal_get_path('module', 'simple_ajax_popup');
drupal_add_js($path . '/misc/fancybox/source/jquery.fancybox.pack.js');
drupal_add_css($path . '/misc/fancybox/source/jquery.fancybox.css');
drupal_add_js($path . '/misc/simple_ajax_popup.js');
drupal_add_js('misc/jquery.form.js');
Файл jquery.form.js подключается друпалом каждый раз, когда на странице присутствует форма. Этот файл необходим для отправки формы по AJAX. Поскольку в момент отрисовки страницы этой формы еще нет, то друпал не подключит этот файл и его нужно подключить вручную.
Затем в хуке меню нужно добавить новый итем, который и будет загружать форму:
$items['simple-popup/form'] = array(
'page callback' => 'simple_ajax_popup',
'access callback' => TRUE,
);
Колбеком будет являться функция, которая будет возвращать либо саму форму либо результаты сабмита.
Для того чтобы вызывать колбек, в любом удобном месте помещаем ссылку:
print l(
'AJAX form',
'simple-popup/form',
array(
'attributes' => array('class' => array('fancybox', 'fancybox.ajax')),
)
);
Важно не забыть подключить библиотеку друпала для работы с AJAX
drupal_add_library('system', 'drupal.ajax');
А также навесить на событие fancybox'а afterShow функцию для обработки формы на javascript:
function simpleAjaxPopupFormProcess() {
Drupal.attachBehaviors('#simple_ajax_popup_form');
jQuery('#simple_ajax_popup_form').ajaxForm();
}
В самом колбеке разместим простой код, который будет проверять — отправлен ли POST запрос. Если нет то функция вернет форму, а если POST запрос был отправлен то обработает данные.
function simple_ajax_popup() {
// POST is empty - load popup.
if (empty($_POST)) {
$form = drupal_render(drupal_get_form('simple_ajax_popup_form'));
print $form;
exit();
}
// If we have POST - process fields values.
else {
// Validation.
$errors = simple_ajax_popup_form_validate($_POST);
// Show errors.
if ($errors) {
$commands = array();
$commands[] = ajax_command_replace(
'#popup-info-box',
$errors
);
ajax_deliver(array('#type' => 'ajax', '#commands' => $commands));
}
// Add message.
else {
watchdog('ajax message', $_POST['message']);
$commands = array();
$commands[] = ajax_command_replace(
'#simple-ajax-popup-form',
'<div class="messages status">Сообщение добавлено в системный журнал.</div>'
);
ajax_deliver(array('#type' => 'ajax', '#commands' => $commands));
}
}
}
Для ответа используется функция ajax_deliver. Функция ajax_command_replace позволяет добавить в ответ AJAX запроса команду, заменяющую контент по указанному врапперу.
Таким образом можно показать сообщение об ошибке:
Или сообщение об успешной отправке:
В данном случае форма просто добавляет сообщение в watchdog.
И напоследок — не забудьте добавить специальный класс кнопке сабмита формы, для того чтобы форму можно было отправлять по AJAX.
$form['form_wrapper']['submit'] = array(
'#type' => 'submit',
'#value' => t('Отправить.'),
'#attributes' => array('class' => array('use-ajax-submit')),
);
Полный код примера можно скачать тут
Реальный проект где используется такая отправка форм через popup — модуль comment abuse.
Автор: IlyinEugene