Статьи

Создание многостраничной волшебной формы в Drupal

Drupal предоставляет вам API для создания форм, просто указав детали формы. Он создаст исходный HTML-код самостоятельно, при условии, что вы просто укажите в нем нужные поля. Мы обсуждали детали построения формы в Drupal в предыдущей статье .

Обычно нам просто нужна простая форма с несколькими полями, но могут быть случаи, когда на одной странице может быть слишком много полей и форма может показаться запутанной и утомительной для заполнения. Это может не сделать лучший интерфейс для вашего сайта, и было бы хорошо разбить вашу форму на логические разделы, чтобы пользователю было легче заполнять информацию. Один из способов разбить форму на разные логические блоки — использовать набор полей, но обычно это работает только при небольшом количестве разделов. Другой способ организовать вашу форму — превратить ее в мастер или многостраничную форму, где пользователь заполняет детали на одной странице и затем переходит на следующую страницу. В этой статье мы рассмотрим, как создать многостраничную форму в Drupal.

Создание модуля многостраничной формы

Первое, что нам нужно сделать, это создать модуль в Drupal. Для этого создайте папку sites\all\modules\multipageform в вашей установке Drupal и добавьте в нее следующие файлы

multipageform.info

 name =  multipageform description =   This   module  creates a multipage form form using   Drupal . core =   7.x 

multipageform.module

 <? php /** * @file * This is the main module file. */ 

  /** * Implements hook_help(). */ 
 function  multipageform_help ( $path ,  $arg )   { 

   if   ( $path ==   'admin/help#multipageform' )   { $output =   '<h3>'   .  t ( 'About' )   .   '</h3>' ; $output .=   '<p>'   .  t ( 'The multipageform module shows how to create a multiple page form using Drupal.' )   .   '</p>' ; 
     return  $output ; 
   } 
 } 

После этого вы сможете увидеть новый модуль в списке модулей. Теперь вы можете включить модуль.

Определение количества страниц в форме и содержимого формы.

Когда наш модуль будет готов, давайте начнем определять многостраничную форму. Для этого первым делом создадим пункт меню, в котором будет отображаться наша форма. Нам нужно добавить меню ловушек в нашем модуле следующим образом

 /** * Implementation of hook_menu(). */ 
 function  multipageform_menu ()   { $items [ 'multipageform/form1' ]   =  array ( 
         'type'   =>  MENU_CALLBACK , 
         'access arguments'   =>  array ( 'access content' ), 
         'page callback'   =>   'drupal_get_form' , 
         'page arguments' => array ( 'multipageform_form1' )); 

   return  $items ; 
 }  

 

В приведенном выше коде мы создали пункт меню в multipageform/form1 и обратным вызовом страницы является функция drupal_get_form аргументом которой является наша функция drupal_get_form которая будет возвращать форму для ее отображения в Drupal.

Теперь мы определим функцию multipageform_form1 следующим образом

 function  multipageform_form1 ( $form ,   & $form_state )   { 


     if ( isset ( $form_state [ 'values' ]))   { $currstep =  $form_state [ 'step' ]   +   1 ; 
     } else   { $currstep =   0 ; 
     } $form_state [ 'step' ]   =  $currstep ; $allsteps =  getForm (); $currform =  $allsteps [ $currstep ]; 

     return  $currform ; 
 } 

 function  getForm ()   { $form =  array (); $step1 =  array (); $step1 [ 'name' ]= array ( 
         '#type' => 'textfield' , 
         '#title' => t ( 'Enter your name' ), 
         '#description' => t ( 'Your first name goes here' ) 
       ); $step1 [ 'last_name' ]= array ( 
         '#type' => 'textfield' , 
         '#title' => t ( 'Enter your Last name' ), 
         '#description' => t ( 'Your Last name goes here' ) 
       ); $step1 [ 'submit' ]= array ( 
         '#type' => 'submit' , 
         '#value' => t ( 'Next' ) 
       ); $form []   =  $step1 ; $step2 [ 'email' ]= array ( 
         '#type' => 'textfield' , 
         '#title' => t ( 'Enter your email' ), 
         '#description' => t ( 'Your email goes here' ) 
       ); $step2 [ 'country' ]= array ( 
         '#type' => 'select' , 
         '#title' => t ( 'Select your country' ), 
         '#options' => array ( 'USA' , 'UK' , 'France' , 'Japan' ) 
       ); $step2 [ 'submit' ]= array ( 
         '#type' => 'submit' , 
         '#value' => t ( 'Next' ) 
       ); $form []   =  $step2 ; $step3 [ 'birthdate' ]= array ( 
             '#type' => 'date' , 
             '#title' => t ( 'Birthdate' ), 
           ); $step3 [ 'submit' ]= array ( 
         '#type' => 'submit' , 
         '#value' => t ( 'Submit' ) 
       ); $form []   =  $step3 ; 

     return  $form ; 
 } 


 

В этой функции переменная $form_state будет содержать состояние нашей многостраничной формы. В состоянии мы будем хранить текущий шаг или страницу, на которой мы находимся, а также значения, которые были введены пользователем на предыдущих шагах.

Первое, что нужно определить в этой функции, это узнать, запустил ли пользователь новую форму или мы должны быть на каком-то другом шаге / странице формы. Для этого мы $form_state['step'] шаг, на котором мы находимся, в $form_state['step'] . Если эта переменная не установлена, то мы на нулевом этапе. В противном случае мы увеличиваем шаг на единицу. Затем мы сохраняем текущий шаг в $form_state для будущего использования.

Далее мы получим форму для текущего шага. Для этого мы должны определить элементы формы для всех шагов в массиве форм. Это делается в функции getForm . В getForm первый шаг имеет имя и фамилию как два элемента формы; на втором этапе есть адрес электронной почты и страна, а на третьем — день рождения. Здесь вы можете легко добавлять или удалять элементы или даже шаги в соответствии с формой, которую вы пытаетесь построить. Если вы перейдете по <your drupal url>/?q=multipageform/form1 вы увидите форму, как показано ниже

Хранение состояния формы.

Теперь нам нужно будет хранить состояние формы на каждом этапе, чтобы после завершения всех шагов мы могли сохранить значения в файле или базе данных.

Для этого мы должны определить функцию multipageform_form1_submit следующим образом

    function  multipageform_form1_submit ( $form ,   & $form_state )   { $form_state [ 'storedvalues' ][ $form_state [ 'step' ]]   =  $form_state [ 'values' ]; 
     if ( $form_state [ 'step' ]   +   1   !=  getNumberOfSteps ())   { $form_state [ 'rebuild' ]   =  TRUE ; 
     } else   { 

         //Reached end of multipage form 

     } 

 } 

 function  getNumberOfSteps ()   { 
     return  count ( getForm ()); 
 } 

В приведенном выше коде функция getNumberOfSteps возвращает количество шагов в форме на основе массива шагов, которые мы определили. Затем в функции multipageform_form1_submit мы получаем значения, представленные пользователем для текущего шага в $form_state['values']; , Мы сохраняем это значение для дальнейшего использования в form_state против текущего шага в выражении

 $form_state['storedvalues'][$form_state['step']] = $form_state['values']; 

Затем мы проверяем, является ли этот шаг последним. Если это не последний шаг, мы устанавливаем $form_state['rebuild']=TRUE чтобы форма перестраивалась, и наша функция multipageform_form1 сгенерирует форму со следующим шагом.

Теперь, если вы перейдете к URL-адресу формы, введите некоторые значения и нажмите «Далее», вы должны перейти ко второму и третьему шагу, как показано ниже.


Проверка многостраничной формы

Возможно, мы захотим проверять данные на каждом этапе на основе данных, которые мы собираем в форме, и на основании некоторых наших правил. Для этого нам нужно написать функцию multipageform_form1_validate следующим образом

    function  multipageform_form1_validate ( $form ,  $form_state )   { 

     switch   ( $form_state [ 'step' ])   { 
         case   '0' : 
             if ( empty ( $form_state [ 'values' ][ 'name' ])) form_set_error ( 'name' , 'Name cannot be empty' ); 
           else   if ( empty ( $form_state [ 'values' ][ 'last_name' ])) form_set_error ( 'last_name' , 'Last name cannot be empty' ); 
             break ; 

         case   '1' : 
             if ( filter_var ( $form_state [ 'values' ][ 'email' ],  FILTER_VALIDATE_EMAIL )   ==   false ) form_set_error ( 'email' , 'Email is not valid' ); 
             break ; 

         default : 
             break ; 
     } 

 } 

 

В приведенной выше функции первое, что мы должны определить, это какой шаг мы находимся. Мы делаем это, используя $form_state['step'] в котором мы $form_state['step'] текущий шаг формы.

Затем в блоке переключателей мы добавляем случаи всех шагов, в которых мы хотим получить некоторую проверку. В приведенном выше коде мы сделали проверки для шага 0 и шага 1. На шаге 0 мы проверяем, не являются ли имя и фамилия пустыми, и на шаге 1 мы проверяем, является ли электронная почта действительной. В случае, если мы находим ошибку, мы устанавливаем ошибку, используя функцию Drupal form_set_error которая не будет перемещать форму на следующий шаг и покажет ошибку пользователю:

Отправка многостраничной формы

После того, как все шаги завершены, вы захотите извлечь все значения, а затем, возможно, сохранить их в файле или в базе данных. Для этого вам нужно изменить функцию multipageform_form1_submit как multipageform_form1_submit ниже

 function  multipageform_form1_submit ( $form ,   & $form_state )   { $form_state [ 'storedvalues' ][ $form_state [ 'step' ]]   =  $form_state [ 'values' ]; 
     if ( $form_state [ 'step' ]   +   1   !=  getNumberOfSteps ())   { $form_state [ 'rebuild' ]   =  TRUE ; 
     } else   { $finalformvalues = array (); $currStep =   0 ; 
         foreach   ( getForm ()   as  $step )   { 
             foreach   ( $step as  $key =>  $value )   { 
                 if ( strcmp ( $key , "submit" )   !=   0 )   { $finalformvalues [ $key ]   =  $form_state [ 'storedvalues' ][ $currStep ][ $key ]; 
                 } 
             } $currStep ++; 
         } 
         //Store the values from $finalformvalues in database or file etc 

     } 

 } 

 

В вышеприведенной функции, как только мы обнаружим, что мы отправили последний шаг формы, мы получаем все ключи элемента формы для всех шагов, а затем получаем значения, введенные пользователем, которые мы сохранили в $form_state['storedvalues'] перед помещением их в массив $finalformvalues . Наконец, $finalformvalues будет содержать все значения для всех элементов формы для всех шагов. Это может быть затем обработано и сохранено.

Вывод

API форм Drupal позволяет создавать формы, не беспокоясь о том, как отобразить HTML-код. Кроме того, мы можем использовать описанный выше подход для создания более длинных форм, которые можно разбить на этапы, чтобы их было проще и логичнее обрабатывать пользователям. Drupal помогает нам легко переносить состояние на различных этапах формы, а также предоставляет хуки для проверки значений и уведомления пользователя в случае возникновения проблем. Все это можно легко сделать с помощью функциональности, предоставляемой Drupal. Получайте удовольствие, создавая следующую многостраничную форму в Drupal!