В предыдущем посте я приводил пример, демонстрирующий использование Ctools modal API с помощью одной формы. В этом же я сделаю акцент на использовании еще одного мощного инструмента, а именно, Ctools multistep wizard - как с так и без задействования modal API.
Отбросим лирику и воздержимся от упоминания того, что при разработке сайта с помощью данного инструмента можно делать и няшные формы создания ноды, и создания юзера, а также регистрации и т.п. А с использованием всплывающих окон (попап-ов) этот процесс перейдет на визуально новый уровень.
Итак, как обычно, начнем с hook_menu(). Объявляем страничку, с которой будем вызывать многошаговую форму и саму страницу формы:
/** * Implements hook_menu(). */ function multi_example_menu() { $items['example/%ctools_js/form'] = array( 'title' => 'Example form', 'page callback' => 'multi_example_form', 'page arguments' => array(1), 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); $items['example-link'] = array( 'title' => 'Example form link', 'page callback' => 'multi_example_link', 'page arguments' => array(1), 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); return $items; }
Функции, генерирующие объявленные страницы:
/** * Page callback: Handles multistep precessing. * * @return string * Multistep wizard output. * * @see multi_example_menu() */ function multi_example_form($js = NULL, $step = NULL) { if ($js) { ctools_include('modal'); ctools_include('ajax'); } // Define array for ctools multistep wizard. $form_info = array( 'id' => 'multi_example', 'path' => "example/" . ($js ? 'ajax' : 'nojs') . "/form/%step", 'show trail' => TRUE, 'show back' => TRUE, 'show cancel' => TRUE, 'show return' => FALSE, 'next callback' => 'multi_example_wizard_next', 'finish callback' => 'multi_example_wizard_finish', 'cancel callback' => 'multi_example_wizard_cancel', // Define forms order. 'order' => array( 'start' => t('Enter your info'), 'second' => t('What do you know?'), 'third' => t('What do think about drupal?'), 'fourth' => t('Do you like cookies?'), ), // Define forms 'forms' => array( 'start' => array( 'form id' => 'multi_example_form_start' ), 'second' => array( 'form id' => 'multi_example_form_second' ), 'third' => array( 'form id' => 'multi_example_form_third' ), 'fourth' => array( 'form id' => 'multi_example_form_fourth' ), ), ); // We're not using any real storage here, so we're going to set our // object_id to 1. When using wizard forms, id management turns // out to be one of the hardest parts. Editing an object with an id // is easy, but new objects don't usually have ids until somewhere // in creation. // // We skip all this here by just using an id of 1. $object_id = 1; if (empty($step)) { // We reset the form when $step is NULL because that means they have // for whatever reason started over. multi_example_cache_clear($object_id); $step = 'start'; } // This automatically gets defaults if there wasn't anything saved. $object = multi_example_cache_get($object_id); // live $form_state changes. $form_state = array( 'ajax' => $js, // Put our object and ID into the form state cache so we can easily find it. 'object_id' => $object_id, 'object' => &$object, ); // Send this all off to our form. This is like drupal_get_form only wizardy. ctools_include('wizard'); $form = ctools_wizard_multistep_form($form_info, $step, $form_state); $output = drupal_render($form); if ($js) { // If javascript is active, we have to use a render array. $commands = array(); if ($output === FALSE || !empty($form_state['complete'])) { // Dismiss the modal. $commands[] = ajax_command_html('#ctools-sample', render(multi_example_get_result($object))); $commands[] = ctools_modal_command_dismiss(); } elseif (!empty($form_state['cancel'])) { // If cancelling, return to the activity. $commands[] = ctools_modal_command_dismiss(); } else { $commands = ctools_modal_form_render($form_state, $output); } print ajax_render($commands); } else { if ($output === FALSE || !empty($form_state['complete'])) { return render(multi_example_get_result($object)) . "\n\r" . l(t('Back'), 'example-link'); } elseif (!empty($form_state['cancel'])) { drupal_goto('example-link'); } else { return $output; } } }