Pull to refresh

Загрузка и отправка формы по AJAX на Drupal 7

Reading time3 min
Views18K
image Недавно мне потребовалось реализовать сабмит формы по 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. Поскольку в момент отрисовки страницы этой формы еще нет, то друпал не подключит этот файл и его нужно подключить вручную.

Затем в хуке меню нужно добавим необходимые колбеки:

/**
 * 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.
Tags:
Hubs:
+3
Comments15

Articles