Form API. Создание пользовательских форм в Drupal

Опубликовано 2012.04.14 в разделе Drupal

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

Сразу даю ссылку на документацию, к которой мы будем обращаться http://api.drupal.org/api/drupal/developer!topics!forms_api_reference.html/7

Это очень удобная таблица, а также пример использования каждого элемента.

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

Ключ #type – это тип элемента (поле ввода, область ввода, выпадающий список, скрытое поле и т.д.).

#title –отвечает за заголовок поля

#description – описание поля

#default_value – значение по умолчанию

И так далее. Для разных типов элементов доступны свои аргументы. Смотрите документацию.

  1. //первая простая форма
  2. function my_first_form($form, &$form_state){
  3. $form=array();
  4. $form['name'] = array(
  5. '#type' => 'textfield',
  6. '#title' => t('Название поля'),
  7. '#default_value' => t('Текст по умолчанию'),
  8. );
  9. $form['settings'] = array(
  10. '#type' => 'radios',
  11. '#title' => t('Состояние статуса'),
  12. '#options' => array(0 => t('Статус 1'), 1 => t('Статус 2')),
  13. '#description' => t('Описание данного элемента.'),
  14. );
  15. $form['submit'] = array(
  16. '#type' => 'submit',
  17. '#value' => t('Submit'),
  18. );
  19. return $form;
  20. }

Чтобы отобразить эту форму – к ней нужно обратиться и отрендерить её. Для получения формы используем функцию drupal_get_form(), которой в качестве аргумента передадим id формы. Id формы совпадает с названием функции, которая возвращает массив её элементов. В нашем случае это my_first_form.

Вернемся к функции отрисовки страницы test_url - main_function.

Создадим переменную $form , которая будет содержать в себе нашу форму.

  1. function main_function(){
  2. $form = drupal_get_form('my_first_form'); //получаем поля формы
  3. $form = drupal_render($form); //рендерим форму
  4. return $form.'Содержимое тестовой страницы.';
  5. }

В 17-й строке в переменную form был помещен массив элементов формы и в 18-й этот массив отрендерен в html код. И в 19-й мы выводим эту форму.

Если всё сделано верно-то в браузере мы увидим нашу форму.

Все три поля успешно отрисованы.

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

По умолчанию имя этой функции будет <id формы>_submit . Но при желании в функции формы можно задать любое другое имя.

Создадим функцию my_first_form_submit. Она будет запускаться при сабмите нашей формы. Чтобы принять данные, отправленные формой - следует обратиться к её второму аргументу - $form_state , передаваемому ей по ссылке. Но также можно использовать и стандартный массив $_POST.

Проверим работу функции, выведя на экран значение всех элементов формы.

  1. function my_first_form_submit($form, &$form_state){
  2. debug($form_state['values']);
  3. }

Обратите внимание - выводим только значение элемента с ключом values. Так как в массиве form_state  очень много ненужной нам служебной информации. Проверяем работу формы.

Заполняем форму.

И отправляем её.

Нужные нам переменные - это name и settings. Теперь мы можем записать их в файл, в БД или использовать по своему усмотрению.

Ещё у форм есть замечательный аргумент - #states. Он позволяет создавать динамические формы, без написания JavaScript кода. Например, есть следующее задание на создание формы: в форме должен быть переключатель для выбора пола (М и Ж). Если выбран Ж – то показать поле для ввода девичьей фамилии. Если выбран М – то дать возможность отметить чекбокс «Служил в армии», и если отмечен-то показать поле для ввода воинского звания.

Сейчас мы сделаем это всё тем же Form API.

Создадим новую форму с именем my_next_form. Вначале просто создадим все элементы, а потом настроим их отображение.

  1. function my_next_form($form, &$form_state){
  2. $form=array();
  3.  
  4. $form['name']=array( //Имя пользователя
  5. '#type' => 'textfield',
  6. '#title' => t('Ваше имя'),
  7. '#required' => true
  8. );
  9.  
  10. $form['sex'] = array( //пол
  11. '#type' => 'radios',
  12. '#title' => t('Ваш пол'),
  13. '#options' => array(0 => t('М'), 1 => t('Ж')),
  14. '#required' => true
  15. );
  16.  
  17. $form['maiden_name']=array( //девичья фамилия
  18. '#type' => 'textfield',
  19. '#title' => t('Ваша девичья фамилия')
  20. );
  21.  
  22. $form['served']=array( //отметка о службе
  23. '#type' => 'checkbox',
  24. '#title' => 'Служил в армии'
  25. );
  26.  
  27. $form['rank']=array( //воинское звание
  28. '#type' => 'textfield',
  29. '#title' => t('Ваше воинское звание'),
  30. '#default_value' =>t('Рядовой')
  31. );
  32.  
  33. $form['submit'] = array( //кнопка сабмит
  34. '#type' => 'submit',
  35. '#value' => t('Submit'),
  36. );
  37.  
  38. return $form;
  39. }

Также создадим новую страницу для работы с этой формой. Дадим ей адрес next_form.

  1. function test_module_menu(){
  2. $items = array();
  3.  
  4. $items['test_url'] = array(
  5. 'title' => 'Заголовок страницы',//заголовок страницы
  6. 'page callback' => 'main_function',//имя функции
  7. 'type' => MENU_NORMAL_ITEM, //тип страницы
  8. 'access callback' => TRUE, //доступ к странице
  9. );
  10.  
  11. $items['next_form'] = array(
  12. 'title' => 'Сложная форма',//заголовок страницы
  13. 'page callback' => 'form_function',//имя функции
  14. 'type' => MENU_NORMAL_ITEM, //тип страницы
  15. 'access callback' => TRUE, //доступ к странице
  16. );
  17.  
  18. return $items;
  19. }

Задаем ей новый title и главной функцией назначим функцию form_function, которую создадим далее.

  1. function form_function(){
  2. $form = drupal_get_form('my_next_form'); //получаем поля формы
  3. $form = drupal_render($form); //рендерим форму
  4. return $form;
  5. }

Очистим кэш Друпала и перейдем на URL next_form. Если не было допущено ошибок – то увидим всю форму.

Я намеренно сделал поля для имени и пола обязательными к заполнению. Как вы заметили – Drupal автоматически присвоил им нужные стили, поставил звёздочки.

Если попробовать отправить форму прямо сейчас – система выдаст сообщение о том, что поле для имени не заполнено и форма не будет отправлена. Все остальные поля сохранят свои значения (если вы их изменили).

Теперь сделаем поля зависимыми. Вначале настроим отображение поля для ввода девичьей фамилии. Дополним поле maiden_name.

  1. $form['sex'] = array( //пол
  2. '#type' => 'radios',
  3. '#title' => t('Ваш пол'),
  4. '#options' => array(0 => t('М'), 1 => t('Ж')),
  5. '#required' => true
  6. );
  7.  
  8. $form['maiden_name']=array( //девичья фамилия
  9. '#type' => 'textfield',
  10. '#title' => t('Ваша девичья фамилия'),
  11. '#states' => array(
  12. 'visible' => array(
  13. 'input[name="sex"]' => array('value' =>1),
  14. ),
  15. ),
  16. );

Аргумент states у поля maiden_name представляет собой массив. В нем может быть элемент с ключом visible или invisible, отвечающем за показ или скрытие элемента. Значением этого элемента также будет массив. Его ключ – это проверяемое значение формы, а значение этого ключа – это значение этого проверяемого значения.

Наше условие сделает элемент maiden_name видимым при условии, что значение элемента с именем sex будет равно 1.

Данного условия будет достаточно. Проверьте работу формы. Поле для ввода девичьей фамилии будет видно, только если выбран пол Ж.

Аналогично поступаем с элементом served. Только значение элемента sex должно быть равно 0.

  1. $form['served']=array( //отметка о службе
  2. '#type' => 'checkbox',
  3. '#title' => 'Служил в армии',
  4. '#states' => array(
  5. 'visible' => array(
  6. 'input[name="sex"]' => array('value' => 0),
  7. ),
  8. ),
  9. );

Теперь зададим условия для поля rank. Оно должно быть видно при условии что выбран пол М и поставлена отметка о службе в армии. Для этого в массив visible помещаем 2 элемента – 2 условия.

  1. $form['rank']=array( //воинское звание
  2. '#type' => 'textfield',
  3. '#title' => t('Ваше воинское звание'),
  4. '#default_value' =>t('Рядовой'),
  5. '#states' => array(
  6. 'visible' => array(
  7. 'input[name="served"]' => array('checked' => true),
  8. 'input[name="sex"]' => array('value' =>0)
  9. ),
  10. ),
  11. );

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

Таким образом можно создавать сложные интерактивные формы.

Также помимо обработчика форм в Drupal есть система валидации форм. Например, можно проверить – была ли введена девичья фамилия. И если не была введена – то подставить какое-то дефолтное значение. Данный функционал можно описать и в обработчике, но мы рассмотрим его в валидаторе в качестве примера.

Валидатор формы – это функция с именем <id формы> _ validate.

Создадим функцию my_next_form_validate и проверим в ней поле maiden_name. Если оно будет пустым – присвоим ему значение «Отсутствует».

  1. function my_next_form_validate($form, &$form_state){
  2. if($form_state['values']['maiden_name']==''){
  3. $form_state['values']['maiden_name']='Отсутствует';
  4. }
  5. }

Обратите внимание, что переменная form_state передаётся по ссылке.

Для проверки нашей функции валидации выведем значения полей формы в обработчике формы.

  1. function my_next_form_submit($form, &$form_state){
  2. debug($form_state['values']);
  3. }

Введем в форму только имя и нажмём Submit.

Как видите – переменная maiden_name приняла значение «Отсутствует».

Давайте ещё сделаем проверку на длину имени. Выведем ошибку, если длинна имени менее трёх символов.

  1. function my_next_form_validate($form, &$form_state){
  2. if($form_state['values']['maiden_name']==''){
  3. $form_state['values']['maiden_name']='Отсутствует';
  4. }
  5. if(mb_strlen($form_state['values']['name'])<3){
  6. form_set_error('name', t('Слишком короткое имя.'));
  7. }
  8. }

Функцией mb_strlen определим длину строки. Если она меньше трёх – то функцией form_set_error создадим ошибку. Первый аргумент этой функции – это имя поля, которое должно быть подсвечено. И второй – текст ошибки. Проверяем, пробуем ввести поле имени 1 символ.

Функция валидации успешно сработала. Форма не была отправлена.

А теперь давайте напишем простой обработчик – поместим имя, пол, девичью фамилию и воинское звание в файл.

Напишем обработчик.

  1. function my_next_form_submit($form, &$form_state){
  2. $name = $form_state['values']['name'];
  3. $sex = $form_state['values']['sex'];
  4. $maiden_name = $form_state['values']['maiden_name'];
  5. $rank = $form_state['values']['rank'];
  6.  
  7. $str = $name."\r\n".$sex."\r\n".$maiden_name."\r\n".$rank;
  8.  
  9. $file_name='public://'.md5(time()).'.txt';
  10. $file = fopen ($file_name,"w+");
  11. fputs ( $file, $str);
  12. fclose ($file);
  13.  
  14. drupal_set_message('Данные успешно отправлены');
  15. }

Вначале создадим 4 переменные из полученных данных. Далее объединяем их в одну переменную. Потом определим - по какому адресу будет располагаться создаваемый файл.

Строка public:// будет означать путь sites/default/files . В дальнейшем используйте её. Далее стандартными функциями PHP осуществляем запись в файл.

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

Проверяем.

И открываем sites/default/files.

Файл успешно создан.

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


57 Комментариев

Оставить комментарий

  1. Гость 2016/05/29

    здравствуйте
    есть array('name') из БД

    1. $form['settings'] = array(
    2. '#type' => 'radios',
    3. '#title' => t('Состояние статуса'),
    4. '#options' => array(0 => t('Статус 1'), 1 => t('Статус 2')),
    5. '#description' => t('Описание данного элемента.'),
    6. );

    как вместо t('Статус 1') поставить значения 'name' чтобы кол-во кнопок радио отображалось в зависимости от количества 'name' в array('name')7

    Ответить

    1. Админ 2016/05/30

      Добрый день.
      Вот так:

      1. //если это ваш массив
      2. $name = array('Name 1', 'Name 2', 'Name 3');
      3.  
      4. //то
      5. $form['settings'] = array(
      6. '#type' => 'radios',
      7. '#title' => t('Состояние статуса'),
      8. '#options' => array(),
      9. '#description' => t('Описание данного элемента.')
      10. );
      11.  
      12. foreach($name as $one_name) {
      13. $form['settings']['#options'][] = t($one_name);
      14. }

      Ответить

  2. Гость 2015/06/09

    Здравствуйте Большое спасибо за статью,
    Вы не могли бы подсказать как быть?
    Есть раскрытые фильтры во вьюхе,
    добавлены states к форме и id-форм в template.php
    Какое свойство нужно добавить чтобы сбрасывались значения в фильтре в url-e.
    К примеру выбрал страну "Беларусь",выпал фильтр с городом "Гомель" нажал submit - нашел Гомель,
    Но потом если выбрал другую страну и город то ищет через "Гомель" то-есть в url-e остается значения предыдущего выбранного значение "Гомель"
    Вопрос - какое свойство добавить чтобы сбрасывались выбранные предыдущие значения фильтра,
    #states запоминает пред значения и это не удобно, и поиск становиться не корректный.
    Заранее Большое Вам спасибо за ответ!

    Ответить

    1. Админ 2015/06/10

      Ну #states это чисто визуальный помощник, так сказать, он просто прячет и показывает инпуты.
      Можно попробовать с своём js скрипте. Например на событие onchange селекта со страной очищать поле с городом.
      Может подойдёт ещё модуль https://www.drupal.org/project/views_dependent_filters ?
      https://www.drupal.org/project/hierarchical_select - вроде бы тоже, но говорят что он не работает с фильтрами вьюса.

      Ответить

      1. Гость 2015/06/10

        Спасибо за ответ.
        Попробывал оба модуля, которые написали выше.
        hierarchical_select не подошел т.к дает зависимость только на один выпадающий селект.
        А вот views_dependent_filter подошел, только появился вопрос-
        У меня 5 фильтров, страна, город, вид услуг, стоимость и время выполнения.
        Зависимость идет так - выбрал [-Беларусь-] -> выпал выбор с городами [-Выбирите Город-] выбрал город => выпали [-Вид услуг-] [-Стоимость-] [-Время выполнения-] выбрал значения в этих трех фильтрах.
        Затем изменил страну - селект с "Городом" убрался т.к он зависит от "Выбранной страны",
        А вот селекты с выбранными значениями этих фильтров [-Вид услуг-] [-Стоимость-] [-Время выполнения-] остались и не скрылись, и если выбрать страну Беларусь то автоматом стоит уже Выбранный ранее город "Гомель" а не дефолтное значение [-Выбирите Город-] и за того что не сбрасываются значения города три зависимых селекта не пропадают.
        Как сделать чтобы возвращались селекта в дефолтные значения?
        Заранее большое Вам спасибо за ответ.

        Ответить

        1. Админ 2015/06/11

          Скорей всего только самому на jQuery очищать все "дочерние" инпуты.

          Ответить

          1. Гость 2015/06/11

            А не будет ли jquery нагружать пользователей?

            Если исходить из логики как лучше поступить?
            Кастом модуль на подобие dependent?

            Ответить

            1. Админ 2015/06/15

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

              Ответить

  3. Гость 2015/05/05

    div после form удалось победить?

    Ответить

  4. Гость 2015/05/02

    Доброго всем дня, спасибо за изложенный материал.
    Хотя конечно во всем разобраться новичку не просто.
    Давно мечтаю создать форму регистрации в определенной теме, но не хватает мозгов. Суть такова: Создаем тему это к примеру соревнования. Для участия в котором зарегистрированные пользователи нажимая на кнопку формы, тем самым подтверждают свое участие в турнире. При этом в этой же теме создается видимый список всех участников этого турнира. При чем у тех кто зарегистрировался видна кнопка отменить регистрацию, кто не зарегистрировался соответственно видна кнопка подать заявку.
    Гости не могут видеть эти кнопки,только список участников.
    При всем этом каждый подавший заявку и отменивший, получает письмо на свою почту ваша заявка принята(или отменена).
    Прошу помощи в создании данного не знаю как назвать проекта,
    модуля, скрипта. Не бесплатно конечно. Предложения на почту пожалуйста.

    Ответить

  5. Гость 2015/04/29

    Посоветуйте как лучше сделать.
    Обычное текстовое поле проверяется вот так:
    $form['field_order_phone']['und'][0]['value']['#description'] = t('Enter your phone.');

    После сабмита пользователь видит указанный дексрипшн. Как мне заставить также обрабатываться поле с радиопереключателями? Там #description не подтягивается. А поле нужно проверить за заполняемость (то есть оно обязательно). Сейчас друпал звездочки подтянул, но нечего не показывает после сабмита - не понятно почему нас вернуло назад...

    Ответить

    1. Админ 2015/05/03

      Попробуйте для радиобаттонов использовать свойство "#suffix", вместо "#description"

      Ответить

      1. Гость 2015/05/06

        Спасибо, подходит! Может еще подскажите как темизировать обязательные радио-поля. Просто класс .form-radios не работает к классом .error Есть еще варианты? может можно как-то после сабмита сменить стиль дескрипшина?

        Ответить

        1. Админ 2015/05/11

          Можно попробовать в валидации изменить элемент формы. Добавить ему тот же дескрипшн с описанием ошибки.

          Ответить

  6. Гость 2015/01/13

    спасибо

    Ответить

  7. Гость 2014/11/17

    Спасибо!
    Делаю по вашему уроку форму.
    Такой вопрос. У меня выпадающий список, значений 15.
    И нужно, что бы отображалось 1 поле при выборе первых двух значений, а второе при выборе остальных.
    Подскажите как правильнее записать, не могу ни где найти пример.
    Сейчас у меня вот так:

    1. $form['flight']=array(
    2. '#type' => 'textfield',
    3. '#title' => t('Поле'),
    4. '#states' => array(
    5. 'visible' => array(
    6. ':input[name="fromwhere"]' => array(
    7. 'value' =>11,
    8. 'value' =>12),
    9. ),
    10. ),
    11. );

    Но поле отображается при выборе только одного значения. Как сделать, что бы и так и так?
    Сегодня первый день практики у меня :) Вы уж извините.

    Ответить

    1. Админ 2014/11/18

      Код написан с логической ошибкой, а именно:

      1. array('value' =>11,'value' =>12);

      У массива не должно быть двух элементов с одинаковыми ключами. Если так написать - то второй элемент перезапишет первый.
      И второе - states не позволяют решить вашу задачу. Такой функционал планировался в восьмёрке, незнаю, есть он там или нет, надо проверить.
      Для семёрки придётся писать полностью свой JS код.

      Ответить

  8. Гость 2014/02/16

    Здравствуйте! А не подскажите как отправить данные формы на другой сервер не нажатием кнопки submit, а при условии успешной оплаты товара (drupal 6 ubercart 2)?

    Ответить

  9. Гость 2014/02/12

    при создании первой формы - вы результат не увидите, т.к. вы не определили страницу с url - test_url, а лишь создали форму и кнопку.

    Ответить

    1. Админ 2014/02/13

      Да, это так.
      hook_menu подробнее описан в этой статье.

      Ответить

  10. Гость 2014/01/13

    Здравствуйте,

    а как реализовать return из функции main_function, чтобы вернуть и форму и текстовую переменную (в ней html)?

    Если делать так: return $form . ;TextVar - ругается на несовместимость этих типов.

    Как правильно?

    Ответить

    1. Гость 2014/01/13

      return $form . ;TextVar - опечатался, правильно:
      return $form . $TextVar

      Ответить

      1. Админ 2014/01/14

        Так вот же код:

        1. function main_function(){
        2. $form = drupal_get_form('my_first_form'); //получаем поля формы
        3. $form = drupal_render($form); //рендерим форму
        4. return $form.'Содержимое тестовой страницы.';
        5. }


        В $TextVar у вас что? Может там не строка или число? А объект или массив. В таком случае как раз и будет возникающая у вас ошибка.
        Или же форма написана с ошибками.
        Попробуйте просто return $form или return $TextVar. Если по отдельности они выведутся-то вместе тоже должны.

        Ответить

        1. Гость 2014/01/14

          Спасибо, в $TextVar действительно всякая фигня была.
          PHP только начал изучать, и отсутствие строгой типизации пока выносит мозг.

          Ответить

          1. Админ 2014/01/15

            После строгих языков ещё выносит мозг и то, что не обязательно объявлять переменные в начале скрипта)

            Ответить

            1. Гость 2015/05/18

              точно

              Ответить

  11. Гость 2013/11/12

    Мне как начинающему изучать друпал ваша статья оказалось полезной. Хорошо оформлена и структурированна. Спасибо!

    Ответить

  12. Гость 2013/11/11

    Помогите пожалуйста..
    в зависимости от выбора опции радиоса, нужно чтобы форма отправлялась в разные обработчики..
    например при выборе первой опции, срабатывает стандартная функция ____form_submit()
    а при выборе второй опции нужно чтобы форма отравила данные на другой сервер. т.е. нужно воспользоваться $form['#action'] = '__';
    а '#states' => на него не поставить....

    еще пробывал тупо хтмлем запихать новую форму с инпутами..

    1. $form['zp_form'] = array(
    2. '#type' => 'item',
    3. '#title' => '<form .. ><input .... </form>',
    4. '#states' => array(
    5. 'visible' => array(
    6. 'input[name="tab_radio"]' => array('value' =>'2'),
    7. )
    8. ),
    9. );

    но она игнорируется и не выводится(

    Ответить

    1. Админ 2013/11/12

      Можно добавить 2 кнопки сабмит:

      1. $items['submit_1'] = array(
      2. '#type' => 'submit',
      3. '#value' => t('В первый обработчик'),
      4. );
      5. $items['submit_2'] = array(
      6. '#type' => 'submit',
      7. '#value' => t('Во второй обработчик'),
      8. );


      В функции обработчике смотреть на $form_state['clicked_button']['#id']:
      1. function formfunction_submit($form, &$form_state) {
      2. //Смотри какой айдишник у сабмита и подставляй его в условия.
      3. drupal_set_message($form_state['clicked_button']['#id']);
      4. if ($form_state['clicked_button']['#id'] == 'edit-submit-1') {
      5. drupal_set_message('Первый');
      6. }
      7. elseif ($form_state['clicked_button']['#id'] == 'edit-submit-2') {
      8. drupal_set_message('Второй');
      9. }
      10. }

      Ответить

      1. Гость 2013/11/12

        спасибо)
        но мне надо было во втором случае послать запрос на другой сервер.. т.е. на специальный урл..
        благо оказалось что другой сервер может так же принимать гет запросы, поэтому во втором обработчике выставил drupal_goto($link);

        Ответить

        1. Админ 2013/11/13

          Ну это роли не играет. Кстати, если бы сторонний сервер не мог принимать GET - можно было бы через CURL слать на него POST запрос.
          На него можно также переделать ваш drupal_goto. Смысл в том, что если этот сторонний сайт ляжет - ваш сайт на drupal_goto тоже ляжет, по таймауту. А в CURL можно выставить таймаут, например в 5 секунд. И если за это время ответ не будет получен - можно выдавать ошибку, что форма не ушла. И ниче не зависнет.

          Ответить

          1. Гость 2013/11/13

            мм.. спасиб)
            буду изучать курл)

            Ответить

  13. Гость 2013/10/17

    Проблема с использованием #states в IE.. он не выводит поля с этим свойством..

    1. <?php
    2. $form['test_radio'] = array(
    3. '#type' => 'radios',
    4. '#title' => '!!!',
    5. '#options' => array(0 => 'Первый пункт', 1 => 'Второй Пункт'),
    6. );
    7.  
    8. $form['teststest5'] = array(
    9. '#type' => 'item',
    10. '#title' => '--',
    11. '#states' => array(
    12. 'visible' => array(
    13. 'input[name="test_radio"]' => array('value' =>0),
    14. )
    15. ),
    16. );
    17. ?>

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

    Ответить

    1. Гость 2013/10/17

      Разобрался)
      оказывается нужно брать в ковычки значение:
      'input[name="test_radio"]' => array('value' =>'0'),

      Правда непонятно как это вообще может влиять на браузер? это же пхпешный код который компилируется на сервере..

      Ответить

      1. Админ 2013/10/18

        Но ведь в браузере будет отрабатываться только js код. Стало быть этот пхп код преобразуется в js, который и шаманит полями.
        Для эксперимента можно посмотреть исходный код страницы с работающим кодом и с неработающим. Он обязательно должен отличаться.

        Ответить

  14. Гость 2013/09/10

    Спасибо, очень помогло.

    Ответить

  15. Гость 2013/09/01

    Спасибо за статью!) все понятно объясняете)
    но возник вопрос такой: как после нажатия кнопки сабмит сделать чтобы отображалась не форма а другая страница.. или другая информация на странице - не форма.

    Ответить

    1. Админ 2013/09/02

      Пожалуйста.
      Можете посмотреть в сторону элемента #redirect https://api.drupal.org/comment/18139#comment-18139
      Или же использовать в обработчике формы функцию drupal_goto.
      Другую инфу на странице... можно попробовать посмотреть, есть ли переменная $_POST, и ориентируясь на неё что-то другое выводить.

      Ответить

      1. Гость 2013/09/02

        Спасибо за ответ!)
        с редиректом получилось.
        а вот проверить переменной $_POST не получается.. она представляет собой пустой массив..
        пытаюсь поймать ее в главной функции, которая возвращает тело страницы.. в ней $_POST всегда существует и всегда пустой массив(отправил я форму или нет)..

        Ответить

        1. Админ 2013/09/03

          Он может быть пустым из-за редиректа. Он точно должен быть в функции обработчике формы, и в валидаторе. В других функциях уже нужн опроверять.
          А знаете как можно поступить. В обработчике добавить какую-нибудь переменную в сессию, типа $_SESSION['form_submit'] = 1;
          А на главной странице(да вообще на любой) проверять:

          1. if (isset($_SESSION['form_submit'])){
          2. //другой код
          3.  
          4. //сносим переменную, иначе больше никогда не увидим форму
          5. unset($_SESSION['form_submit']);
          6. }
          7. else{
          8. //вывод формы
          9. }

          Ответить

          1. Гость 2013/09/03

            Редирект тут не причем, я его тут не использую..
            с сессией работает!))крутотенечка)) спс!)
            а вот как передать переменные отосланные формой в главную функцию? тоже через сессии?

            Ответить

            1. Админ 2013/09/03

              Нет, юзай переменную $form_state, вроде как в ней засабмиченные данные. И их можешь подставлять в свойство поля #default_value.

              Ответить

              1. Гость 2013/09/03

                мм.. это мне нужно сделать в главной функции страницы..
                та которая вот так задается:

                1. 'page callback' => 'main_function',

                как передать в нее $form_state ума не приложу..

                Ответить

                1. Админ 2013/09/03

                  В эту никак. Обычно и не передают в неё. Можешь сессиями попробовать, или ещё как-нибудь из бд вытаскивать.

                  Ответить

                  1. Гость 2013/09/07

                    Через глобальные переменные можно еще)

                    Ответить

  16. Гость 2013/08/04

    Добрый день! Все хорошо и понятно описано. Большое вам спасибо.
    Подскажите, можно ли реализовать такое:
    к ноде (то есть к типу материала) добавить форму c помощью form api. То есть не добавлением полей реализовать форму а form api и это должно быть типом материала.
    Конкретно нужна реализация именно, вот этой динамичной смени формы, при выборе одного из параметров (в примере мужчина/женщина).

    Ответить

    1. Админ 2013/08/05

      Здравствуйте.
      Реализовать новый тип материала за счёт Form API конечно-же не удастся, это ведь только формы.
      Решение такое.

      Создайте новый тип материала, стандартно из админки.
      Так же средствами cck создайте все нужные поля.
      Затем в своём модуле реализуйте hook_form_FORM_ID_alter, в котором и будут перехвачены созданные поля, и установлена между ними требуемая зависимость.

      Ответить

  17. Гость 2013/07/04

    Вот сколько не видел инструкций, по друпалу, все такие красавцы, всё так понятно объясняют, но не один не скажет - В КАКИХ ФАЙЛАХ ПИСАТЬ ВЕСЬ ЭТОТ КОД?

    Ответить

    1. Админ 2013/07/04

      Теоретически - в файле любого модуля.
      Правильно будет создать свой модуль и в нём(в файле с расширением .module) размещать функции. В этом же файле размещаются и всевозможные хуки, которые вызовутся автоматически когда нужно.

      Ответить

  18. Гость 2013/03/28

    Очень грамотное изложение материала. Всё доступно и легко написано. Перечитал до этого кучу материала, от всего оставалось весьма смутное представление. Теперь же всё структурировалось и стало гораздо понятнее. Как новичку, очень полезно. Спасибо!

    Ответить

    1. Админ 2013/03/28

      Пожалуйста, я старался)) Спрашивайте что ещё интересно узнать - напишу об этом.

      Ответить

  19. Гость 2013/03/14

    Спасибо за статьи! Нигде так доступно не объясняется как здесь!

    Ответить

  20. Гость 2012/11/08

    !огромное спасибо..

    Ответить

    1. Админ 2012/11/09

      Пожалуйста!))))

      Ответить

  21. Гость 2012/11/07

    Спасибо огромное за статью!
    Очень просто и подробно описано, как создать форму!

    Ответить

  22. Гость 2012/04/22

    скажите, а как будет выглядеть hook_submit для некоторых полей и upload поля?

    Ответить

    1. Админ 2012/04/23

      А что за форма? Можно добавить к ней hook_form_alter и указать в нём функцию(свою) обработчик.тогда у формы при сабмите отработаются сразу 2 обработчика.
      Укажите ещё версию друпала и что именно надо сделать с полем типа upload.

      Ответить

Ваш комментарий успешно создан

Ваш комментарий

  • Для выделения кода оберните его в тэги <code> и </code>
  • Отметьте коробку