Формы ввода данных Drupal

На сегодняшний день, поскольку в процессе работы людям приходится принимать и обрабатывать большое количество данных, веб-приложения стали неотъемлемой частью почти всех отраслей экономики.

Получение данных происходит при помощи HTML-форм, которые можно использовать для создания различных типов полей для ввода, например, таких как «текстовые поля», «переключатели» и прочее – для этого используются HTML-теги.

Эти формы трудно сохранять или обновлять, если они записываются непосредственно в HTML-коде. Drupal предлагает отличный способ задавать формы напрямую через PHP-код, а система самостоятельно генерирует конечные формы.

Благодаря этому Drupal облегчает вам работу по созданию и поддержке форм. В данной статье мы будем рассматривать, как можно создавать формы связи в Drupal. Окончательный код вы можете скопировать с Github.

Функция drupal_get_form — генерация форм в Drupal

Вся магия образования форм в Drupal основана на функции drupal_get_form. Результаты этой функции отображают форму массива в системе Drupal.

Она принимается в качестве аргумента form_id: уникальный идентификатор для определения формы, и, если функция на выходе получается с тем же именем, тогда вызывается функция для её построения. Больше информации о функции drupal_get_form вы можете получить здесь.

Создание базовой формы в Drupal

Давайте начнем с создания небольшого модуля, который будет генерировать меню обратного вызова, а затем в этом меню обратного вызова создадим форму при помощи функции drupal_get_form. Чтобы создать модуль, необходимо в папке, где установлен Drupal, создать дополнительную директорию sitesallmodulesdrupalform и добавить сюда два файла: drupalform.info и drupalform.module со следующим кодом:

drupalform.info

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

drupalform.module

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

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

  if ($path == 'admin/help#rupalform') {
    $output = '<h3>' . t('About') . '</h3>';
    $output .= '<p>' . t('The drupalform module shows how to create forms using Drupal.') . '</p>';
    return $output;
  }
}

При помощи вышеуказанного кода вы сможете увидеть свой модуль в списке доступных модулей и получите возможность включить его, как это показано на рисунке ниже.

модуль в списке доступных

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

/**
* Implementation of hook_menu().
*/
function drupalform_menu() {
  $items['drupalform/form1'] = array(
        'type' => MENU_CALLBACK,
        'access arguments' => array('доступ к контенту'),
        'page callback' => 'drupal_get_form',
        'page arguments'=>array('drupalform_form1'));

  return $items;
}

function drupalform_form1() {
    $form = array();


    $form['name']=array(
        '#type'=>'textfield',
        '#title'=>t('Введите ваше имя'),
        '#description'=>t('Ваше имя идет сюда')
      );
    $form['last_name']=array(
        '#type'=>'textfield',
        '#title'=>t('Введите вашу фамилию'),
        '#description'=>t('Ваша фамилия идет сюда')
      );

     $form['email']=array(
        '#type'=>'textfield',
        '#title'=>t('Введите ваш e-mail'),
        '#description'=>t('Ваш e-mail идет сюда')
      );

    $form['country']=array(
        '#type'=>'select',
        '#title'=>t('Выберете вашу страну'),
        '#options'=>array('США','Великобритания','Франция','Япония')
      );

    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Отправить')
      );

      return $form;
}

В приведенном выше коде, реализуя hook_menu, мы создали пункт меню, для которого значением page_callback является drupal_get_form, а аргументом для него будет form_id «drupalform_form1«. Функция drupalform_form1 возвращает массив форм, который мы намерены создать.

В функции drupalform_form1 мы создаем три текстовых поля: имя (name), фамилия (last name), адрес электронной почты (email) и один блок для выбора страны. В выпадающем окне блока мы указываем варианты стран. Кроме этого, мы добавили кнопку «Отправить», чтобы пользователь сумел, в конце концов, отправить форму.

Теперь, у вас должно получиться зайти в свое меню по адресу: /drupalform/form1 и увидеть форму, которая будет выглядеть следующим образом:

drupalform_form1

Проверка формы Drupal

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

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

Таким образом, для нашей формы функция имени будет выглядеть как:

drupalform_form1_validate($form, $form_state)

Значения, которые пользователь ввел, будут представлены в массив $form_state[‘значение’], и будут совпадать с идентификатором, который был вами указан в форме.

Таким образом, если мы должны провести проверку нашей формы, функция будет следующей:

function drupalform_form1_validate($form, $form_state) {

  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');
  else if(filter_var($form_state['values']['email'], FILTER_VALIDATE_EMAIL) == false)
    form_set_error('email','Email is not valid');

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

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

сообщение об ошибке

Отправка форм Drupal

Аналогично функции проверки, функция отправки (submit) также основана на правилах именования и имя функции должно быть: _submit. Опять же, переменная $form_state будет ей передана. Таким образом, наша функция отправки будет задана как:

f

unction drupalform_form1_submit($form, $form_state) {
   //В зависимости от типа формы вы можете добавить алгоритм
   //для хранения сведений о форме 
   //путем его добавления в таблицу Drupal.
   //или отправки письма администратору
   //Запись в файл
   //или передать в кукую-либо другую службу
   drupal_set_message("Форма была отправлена");
}

Теперь, если мы заполнили все поля должным образом, то получаем на экране следующее сообщение:

сообщение

Используя поля, вы можете установить в формах Drupal отдельные элементы.

Иногда, когда форма большого размера, и в ней имеется много полей, может быть полезно разбить её на небольшие секции, чтобы она представлялась пользователю более логичной. Для реализации подобного решения, вы можете сформировать объединения полей (fieldsets) в Drupal, чтобы создать группы полей.

Чтобы создать объединение полей с названием basicdetails, которое будет содержать поля, которые мы уже определили выше, нам нужно будет обновить drupalform_form1 следующим образом:

function drupalform_form1() {
    $form = array();


     $form['basicdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Введите основные данные ниже'),
        '#description'=>t('Это является обязательным')
      );

        $form['basicdetails']['name']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите ваше имя'),
            '#description'=>t('Ваше имя напишите здесь')
          );
        $form['basicdetails']['last_name']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите вашу фамилию'),
            '#description'=>t('Вашу фамилию напишите здесь')
          );

         $form['basicdetails']['email']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите ваш email'),
            '#description'=>t('Ваш email напишите здесь')
          );


    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Отправить')
      );

      return $form;
}

Это позволит создать объединение нескольких полей, как показано ниже:

объединение нескольких полей

Различные элементы форм, которые могут быть использованы в формах Drupal

Drupal поддерживает очень много различных типов полей, которые мы можем использовать в наших формах. Я обновлю формы из нашего примера, чтобы использовать некоторые из них, создав еще два объединения полей для более подробного адреса и дополнительных деталей.

Обновленный код приведен ниже:

function drupalform_form1() {
    $form = array();


     $form['basicdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Введите основные детали ниже'),
        '#description'=>t('Эти поля являются обязательными')
      );

        $form['basicdetails']['name']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите ваше имя'),
            '#description'=>t('Ваше имя впишите здесь')
          );
        $form['basicdetails']['last_name']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите вашу фамилию'),
            '#description'=>t('Вашу фамилию напишите здесь')
          );

         $form['basicdetails']['email']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите ваш email'),
            '#description'=>t('Ваш email напишите здесь')
          );

  $form['addressdetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Введите ваш подробный адрес ниже'),
        '#description'=>t('Это поле является обязательным')
      );

        $form['addressdetails']['country']=array(
            '#type'=>'select',
            '#title'=>t('Выберете вашу страну'),
            '#options'=>array('США','Великобритания','Франция','Япония')
          );
        $form['addressdetails']['city']=array(
            '#type'=>'textfield',
            '#title'=>t('Введите ваш город'),
            '#description'=>t('Название вашего города введите здесь')
          );
        $form['addressdetails']['localaddress']=array(
            '#type'=>'textarea',
            '#title'=>t('Введите ваш адрес'),
            '#description'=>t('Ваш адрес впишите здесь')
          );

     $form['additionaldetails']=array(
        '#type'=>'fieldset',
        '#title'=>t('Введите другую информацию о себе ниже'),
        '#description'=>t('Это необязательное поле')
      );

        $form['additionaldetails']['gender']=array(
            '#type'=>'radios',
            '#title'=>t('Пол'),
            '#options'=>array('Мужской','Женский')
          );

        $form['additionaldetails']['suscribtion']=array(
            '#type'=>'checkboxes',
            '#title'=>t('Я хочу подписаться на'),
            '#options'=>array('Email-рассылку','Другие предложения')
          );

        $form['additionaldetails']['birthdate']=array(
            '#type'=>'date',
            '#title'=>t('Дата рождения'),
          );

        $form['#attributes']['enctype'] = 'multipart/form-data';

         $form['additionaldetails']['picture']=array(
            '#type'=>'file',
            '#title'=>t('Загрузите свое фото'),
          );



    $form['submit']=array(
        '#type'=>'submit',
        '#value'=>t('Отправить')
      );

      return $form;
}

Вот как будет выглядеть новый набор полей для ввода:

новый набор полей

Заключение

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

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

Всего вам наилучшего, когда будете создавать следующий список заполняемых форм в вашем Drupal модуле!

Если вы хотите, чтобы мы рассмотрели какой-либо конкретный случай или разъяснили какие-либо нюансы, или же вы просто хотите высказаться — отпишитесь в комментариях.

Перевод статьи «Understanding Forms in Drupal» был подготовлен дружной командой проекта Сайтостроение от А до Я.