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!