Недавно мне потребовалось реализовать сабмит формы по AJAX. При этом форма должна загружаться в попапе. Казалось бы задача тривиальная, но оказалось что все же есть подводные камни.
Задача решается для Drupal 7. В качестве библиотеки для создания popup'ов используется fancybox.
Сперва нужно подключить необходимые библиотеки:
Файл jquery.form.js подключается друпалом каждый раз, когда на странице присутствует форма. Этот файл необходим для отправки формы по AJAX. Поскольку в момент отрисовки страницы этой формы еще нет, то друпал не подключит этот файл и его нужно подключить вручную.
Затем в хуке меню нужно добавим необходимые колбеки:
Первым колбеком станет страница на которой будет ссылка для загрузки формы, а второй колбек будет возвращать форму.
Для того чтобы вызывать форму, добавляем ссылку на страницу:
Важно не забыть подключить библиотеку друпала для работы с AJAX.
Еще один важный момент — навесить на событие fancybox'а afterShow функцию для обработки формы на javascript:
Функция отрисовки формы крайне проста:
Для ответа используется функция ajax_deliver. Функция ajax_command_replace позволяет добавить в ответ AJAX запроса команду, заменяющую контент по указанному врапперу.
Таким образом можно показать сообщение об ошибке:
Или сообщение об успешной отправке:
В данном случае форма просто добавляет сообщение в watchdog.
И напоследок — не забудьте добавить специальный класс кнопке сабмита формы, для того чтобы форму можно было отправлять по AJAX.
Полный код примера можно скачать тут
Реальный проект где используется такая отправка форм через popup — модуль comment abuse.
Задача решается для 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. Поскольку в момент отрисовки страницы этой формы еще нет, то друпал не подключит этот файл и его нужно подключить вручную.
Затем в хуке меню нужно добавим необходимые колбеки:
/**
* Implements hook_menu().
*/
function simple_ajax_popup_menu() {
$items = array();
$items['test'] = array(
'type' => MENU_SUGGESTED_ITEM,
'title' => t('Test page'),
'page callback' => 'simple_ajax_popup_page',
'access arguments' => array('access content'),
);
$items['callback'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'simple_ajax_popup',
'access arguments' => array('access content'),
);
return $items;
}
Первым колбеком станет страница на которой будет ссылка для загрузки формы, а второй колбек будет возвращать форму.
Для того чтобы вызывать форму, добавляем ссылку на страницу:
function simple_ajax_popup_page() {
drupal_add_library('system', 'drupal.ajax');
return l(
'AJAX form',
'callback',
array(
'attributes' => array('class' => array('fancybox', 'fancybox.ajax')),
)
);
}
Важно не забыть подключить библиотеку друпала для работы с AJAX.
Еще один важный момент — навесить на событие fancybox'а afterShow функцию для обработки формы на javascript:
function simpleAjaxPopupFormProcess() {
Drupal.attachBehaviors('#simple_ajax_popup_form');
jQuery('#simple_ajax_popup_form').ajaxForm();
}
Функция отрисовки формы крайне проста:
/**
* Return popup with form.
*/
function simple_ajax_popup() {
$form = drupal_render(drupal_get_form('simple_ajax_popup_form'));
print $form;
drupal_exit();
}
Для ответа используется функция ajax_deliver. Функция ajax_command_replace позволяет добавить в ответ AJAX запроса команду, заменяющую контент по указанному врапперу.
function simple_ajax_popup_form_submit($form, &$form_state) {
$form_state['rebuild'] = TRUE;
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));
drupal_exit();
}
Таким образом можно показать сообщение об ошибке:
Или сообщение об успешной отправке:
В данном случае форма просто добавляет сообщение в watchdog.
И напоследок — не забудьте добавить специальный класс кнопке сабмита формы, для того чтобы форму можно было отправлять по AJAX.
$form['form_wrapper']['submit'] = array(
'#type' => 'submit',
'#value' => 'Отправить.',
'#attributes' => array('class' => array('use-ajax-submit')),
);
Полный код примера можно скачать тут
Реальный проект где используется такая отправка форм через popup — модуль comment abuse.