Последнее время появляются все больше и больше сайтов с попапами. Благодаря Эрлу Майлзу мы имеем замечательный инструмент - Ctools, представляющий мощный API для друпалера. Сегодня мы рассмотрим modal API и научимся с ним работать.
В качестве примера будем открывать форму обратной связи в модальном окне. Но прежде чем начать, я быстренько пробегусь по командам AJAX-фреймворка.
- ajax_command_after($selector, $html, $settings = NULL) – вставляет содержимое $html после селектора $selector;
- ajax_command_alert($text) – выводит алерт с текстом $text;
- ajax_command_append($selector, $html, $settings = NULL) – добавляет содержимое $html в конец элемента с селектором $selector;
- ajax_command_before($selector, $html, $settings = NULL) – вставляет содержимое $html перед селектором $selector;
- ajax_command_changed($selector, $asterisk = '') – помечает селектор $selector классом ajax-changed;
- ajax_command_css($selector, $argument) – устанавливает css свойства $argument у элемента с селектором $selector;
- ajax_command_data($selector, $name, $value) – изменяет внутренние данные элемента с селектором $selector;
- ajax_command_html($selector, $html, $settings = NULL) – изменяет содержимое элемента с селектором $selector на содержимое $html;
- ajax_command_insert($selector, $html, $settings = NULL) – вставляет содержимое $html в селектор $selector;
- ajax_command_invoke($selector, $method, array $arguments = array()) – выполняет jQuery метод $method для элемента с селектором $selector;
- ajax_command_prepend($selector, $html, $settings = NULL) – вставляет содержимое $html в начало элемента с селектором $selector;
- ajax_command_remove($selector) – удаляет элемент с селектором $selector;
- ajax_command_replace($selector, $html, $settings = NULL) – заменяет элемент с селектором $selector на содержимое $html;
- ajax_command_restripe($selector) – обновляет классы odd/event у строк таблицы с селектором $selector;
- ajax_command_settings($argument, $merge = FALSE) – передаёт данные в глобальный массив настроек Друпала Drupal.settings.
Это команды, которые предоставляет ядро Друпала. Модуль Ctools предоставляет дополнительные ajax команды. Для их использования необходимо вызвать функцию ctools_include('ajax'). Список этих команд:
- ctools_ajax_command_attr($selector, $name, $value) – меняет атрибут $name на значение $value у элемента с селектором $selector;
- ctools_ajax_command_redirect($url, $delay = 0, $options = array()) – отправляет клиента по адресу $url с задержкой $delay;
- ctools_ajax_command_reload() – перезагружает текущую страницу;
- ctools_ajax_command_submit($selector) – отправляет форму с селектором $selector.
Для работы с модальными окнами нам потребуются дополнительные ajax команды, которые также предоставляет модуль Ctools. Для их использования необходимо вызвать функцию ctools_include('modal'). Список этих команд:
- ctools_modal_command_dismiss() – закрывает модальное окно;
- ctools_modal_command_display($title, $html) – открывает модальное окно с заголовком $title и содержимым $html;
- ctools_modal_command_loading() – показывает экран загрузки в модальном окне;
- ctools_modal_form_wrapper($form_id, $form_state) – выводит форму $form_id в попапе.
Переходим к написанию модуля.
Шаг 1. Для начала нам нужно объявить страницу в hook_menu, к которой будет обращаться ajax:
/**
* Implementation of hook_menu()
*/
function example_menu() {
$items = array();
$items['example/%ctools_js/contact'] = array(
'title' => 'Contact',
'page callback' => 'example_contact_page_callback',
'page arguments' => array(1),
'access arguments' => array('access site-wide contact form'),
'delivery callback' => 'ajax_deliver',
'theme callback' => 'ajax_base_page_theme',
);
return $items;
}
Шаг 2. Далее нам нужно в page callback написать открытие модального окна:
/**
* @param null $js
* @return array
*/
function example_contact_page_callback($js = NULL) {
// Если у пользователя выключен JavaScript в браузере, то отправляют его на обычную форму обратной связи.
if (!$js) {
drupal_goto('contact');
}
// Подключаем библиотеку для работы с модальным окном с помощью ajax команд.
ctools_include('modal');
$form_state = array(
'title' => t('Contact'), // Используется для заголовка модального окна.
'ajax' => TRUE,
'build_info' => array(
'args' => array(),
),
);
// Подключаем файл, в котором описана функция формирующая форму.
form_load_include($form_state, 'inc', 'contact', 'contact.pages');
$commands = array();
// Формируем форму в модальном окне.
$commands = ctools_modal_form_wrapper('contact_site_form', $form_state);
// Если форма была успешно отправлена, то выводим сообщение об этом и закрываем модальное окно.
if (!empty($form_state['executed'])) {
$commands = array();
// Выводим сообщение об успешной отправке формы.
$commands[] = ajax_command_html('#messages-wrapper', theme('status_messages'));
// Закрываем модальное окно.
$commands[] = ctools_modal_command_dismiss();
}
return array('#type' => 'ajax', '#commands' => $commands);
}
Шаг 3. Необходимо создать блок, в котором будет выводится ссылка, по клику на которую будет открываться модальное окно:
/**
* Implements hook_block_info().
*/
function example_block_info() {
$blocks['example_contact'] = array(
'info' => t('Contact modal link'),
'cache' => DRUPAL_NO_CACHE,
);
return $blocks;
}
/**
* Implements hook_block_view().
*/
function example_block_view($delta = '') {
$block = array();
if ($delta == 'example_contact') {
// В этой функции подключаются необходимые библиотеки, js и css файлы (если нужны), а так же устанавливаются
// настройки для модального окна. Эту функцию мы опишем позже
_example_include_modal();
$block['content'] = ctools_modal_text_button(t('Contact'), 'example/nojs/contact', t('Contact'), 'ctools-modal-example-contact-style');
}
return $block;
}
Шаг 4. Необходимо написать подключение всех нужных библиотек, js и css файлов (если нужны), а также установить настройки для модального окна в функции "_example_include_modal":
function _example_include_modal() {
static $added = FALSE;
if ($added == FALSE) {
$added = TRUE;
// Include the CTools tools that we need.
ctools_include('modal');
ctools_include('ajax');
ctools_modal_add_js();
// Создаем массив с настройками для модального окна.
$example_style = array(
'example-contact-style' => array(
'modalSize' => array(
'type' => 'fixed', // Тип модального окна. фиксированный или резиновый.
'width' => 420, // Ширина модального окна.
'height' => 'auto', // Высота модального окна.
),
'modalOptions' => array(
'opacity' => (float) 0.3, // Прозрачность фона.
'background-color' => '#000000', // Цвет фона.
),
'closeText' => '', // Текст для закрытия модального окна.
'loadingText' => '', // Текст, отображаемый в момент загрузки модального окна.
'animation' => 'fadeIn', // Эффект появления модального окна.
'animationSpeed' => 'fast', // Скорость анимации.
),
);
// Подключаем настройки для модального окна.
drupal_add_js($example_style, 'setting');
}
}
В итоге мы получаем всплывающую в попапе форму обратной связи работающую без перезагрузки страницы.
P.S. Не забываем добавить нашему модулю зависимость от модулей Ctools и Contact.