Drupal → Зависимые элементы форм (#states)

11.03.2011

Часто бывает необходимо, чтобы определённые элементы формы появлялись только при определённых значениях других элементов. Например нет необходимости показывать checkbox "Открывать в новом окне", если не отмечен стоящий выше checkbox "Сделать ссылкой". Для этого у элементов доступно новое свойство #states.

Реализуется это так:

'#states' => array(
  'state_for_current_element' => array(
    'selector_for_another_element' => array(
      'condition_type' => 'value',
    ),
  ),
),

Пример формы с двумя чекбоксами "Сделать ссылкой" и "Открывать в новом окне", где видимость второго зависит от значения первого:

$form['make_link'] = array(
  '#type' => 'checkbox',
  '#title' => 'Сделать ссылкой',
);

$form['in_new_window'] = array(
  '#type' => 'checkbox',
  '#title' => 'Открывать в новом окне',
  '#states' => array(
    'visible' => array(
      ':input[name="make_link"]' => array(
        'checked' => TRUE,
      ),
    ),
  ),
);

Ещё один пример, в котором при выборе в селекте значения "- Upload -" появляется поле для выбора файла:

$form['file'] = array(
  '#type' => 'select',
  '#title' => t('File'),
  '#options' => array(
    'upload' => '- Upload -',
    'left.jpg' => 'left.jpg',
    'center.jpg' => 'center.jpg',
    'right.jpg' => 'right.jpg',
  ),
);
  
$form['fileup'] = array(
  '#type' => 'file',
  '#states' => array(
    'visible' => array(
      ':input[name="file"]' => array(
        'value' => 'upload',
      ),
    ),
  ),
);

Множество примеров можно найти в демо модуле form_example из состава Examples for Developers (прямая ссылка). Так же эта тема освещена в видео от Lullabot — jQuery and JavaScript in Drupal (Глава 12, начало в 2:43).

Виды состояний и условий.

По материалам статьи Dynamic forms in Drupal 7.

Написанное актуально для
Drupal 7, Drupal 8
Похожие записи

Комментарии

круто, в шестерке есть модуль conditional fields, но он сильно ограничен, а здесь так просто.

А как сделать зависимость от нескольких значений поля?
Скажем показывать поле, если какой-нибудь селект имеет значение "Яблоко" или "Груша" или "Помидор"?

Dimmduh, ответ на свой вопрос нашли? Отпишите, пожалууйста,

А как сделать зависимость от нескольких значений поля?
Скажем показывать поле, если какой-нибудь селект имеет значение "Яблоко" или "Груша" или "Помидор"?

Насколько помню, условие ИЛИ использовать нельзя, только И. На d.org была соответствующая issue, в которой хотели добавить этот функционал в D8 (хотя может будет backport)

Andrey, нет, к сожалению стандартное решение не было найдено.
Поэтому был написан дополнительный код на jQuery.

Спасибо
А можно задать условие "Не равно"?
Например, опиции "Яблоко", "Груша", "Помидор", "Розы", "Тюльпаны". Задать

array(
'visible' => array(
JQUERY_SELECTOR => REMOTE_CONDITIONS1,
JQUERY_SELECTOR => REMOTE_CONDITIONS2,
...
),

где REMOTE_CONDITIONS1 - не равно Розы
REMOTE_CONDITIONS2 - не равно Тюльпаны
)

Насчет "не равно" не в курсе.

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

array(
'visible' => array(
'input[name="city"]' => 'Иркутск',
'input.input_city' => 'Слюдянка',
...
),

Гость
01.08.2012, 14:41

Не равно указывается так:

  $form['field_NAME']['#states'] = array(  
    'visible' => array(
      ':input[name="field_type[und]"]' => array('!value' => 'VALUE'),
    ),
  );
Гость
10.03.2013, 21:41

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

читай про хуки, альтер хуки, form api

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

Гость
27.08.2013, 12:55

Спасибо, мне помогли комменты. Использовал 'invisible' и '!value' .

'invisible' => array(
':input[name="field1[und]"]' => array('!value' => 'VALUE1'),
':input[name="field2[und]"]' => array('value' => 'VALUE2')
),

Если field1 не равно значению VALUE1 (для всех кроме одного из списка), и field2 равно значению 'VALUE2' (только для одного из списка) - скрывать поле.

Мне нужно делать зависимые поля при добавлении материала (тип заведения). Куча полей. И вывод некоторых полей зависит от значения таксаномии. Как нужно мне все это сделать? Через form_alter в теме? Или модуль. В общем как. Объясните пожалуйста. Есть модуль conditional_fields для drupal 7 он чем плох? И если я использую hierarhical_select для выбора категории, будут ли работать зависимости

hook_form_alter
чем плох conditional_fields не знаю

А каким будет текст функции хотя бы пример. Допустим в материале есть поле field_category - это термин таксаномии. В этом термине словарь содержит поля
-Досуг
-- Ресторан
-- Кафе
-Красота
--Салон красоты
--SPA

Допустим при выборе Досуг--Ресторан, появляется поле Количество залов(field_zal), при выборе -Красота--Салон красоты, появляется поле Тип услуг (field_usluga)

Но при этом чтобы положение полей задавалось в типе материала (Такое же возможно). Еще один нюанс, я использую Multistep Nodeform для добавления материала, не будет ли он мешать зависимостям.

Или все же использовать Conditional Fields?
ПРосто где то читал, что в drupal 7 лучше использовать #states, а conditional fields типо не допиленный.

Единственное что заметил с Conditional fields не работает корректно hierarhical select.
А вот что не нравиться в Multistep, это то что редактировать созданный материал, тоже нужно по шагам. Возможно ли сделать редактирование по вкладкам.

P.S. Извиняюсь за огромное количество вопросов, просто как новичек запутался в этом.

В общем какое оптимальное было бы решение для создания, зависимых полей, выбора категории в 2 поля, пошаговое добавление материала, и редактирование материала по вкладкам (Контакты, Дополнительно, Фото, и т.д.).

Дерек
08.12.2013, 16:47

а как в данном случае - если поле отмечено как обязательное, скрыв его как убрать обязательность? параметр нашел, но вот как сформировать условие при котором параметр будет меняться?

Гость
20.04.2014, 14:39

Не ужели ни кто не знает как заставить Conditional Fields или #states работать с "or" для значений одного поля ????

Я так понял зависимый элемент прячется с помощью js без перестройки формы? А если зависимый имеет атрибут #required?

Dirst, форма будет сообщать об ошибке, мол не заполнено поле, то поле которое спрятано. #states - это всего лишь визуальное скрывание.

Vlad Savitsky
04.05.2016, 14:11

У зависимого атрибут 'required' может тоже выставляться в зависимости от других элементов формы:

'#states' => array(
  'required' => array(
      ':input[name="field_payment[und]"]' => array('value' => 'authnet_aim|commerce_payment_authnet_aim'),
),
),

https://api.drupal.org/comment/49823#comment-49823

логика ИЛИ для радиобоксов с одним и тем же именем:
$form['...']['field_...']['#states'] = array(
'visible' => array(
':input[name="имя"]' => array(
array('value' => '...'),
array('value' => '...'),
),
),
);

Гость
15.12.2016, 17:43

Как из js сбросить к исходным states?
Если вызвать form.reset() - сбрасываются только значения полей, при этом условия satets перестают соответствовать этим значениям.

Leagnus, пт 30/09/2016 - 00:00
логика ИЛИ для радиобоксов с одним и тем же именем:

Супер, спасибо за подсказку!

Добавить комментарий