About Conditional Form Fields in Drupal you can read here. In this article I would like share some ready to use examples.
In general the structure of #states looks like it:
<?php
$form['some_field']['#states'] => [
'state_type' => [
'selector' => 'conditions',
'selector' => 'conditions',
],
];
So, let's go to examples:
<?php
$form['show_name'] = [
'#type' => 'checkbox',
'#title' => t('Show name?'),
];
// Hide "name" field when the "show_name" checkbox is checked.
$form['name'] = [
'#type' => 'textfield',
'#title' => t('Name'),
'#states' => [
'visible' => [
':input[name="show_name"]' => ['checked' => TRUE],
],
],
];
<?php
// Show the email field when the "email" is selected and the "name" field is filled.
$form['email'] = [
'#type' => 'textfield',
'#title' => t('Email'),
'#states' => [
'visible' => [
':select[name="method"]' => ['value' => 'email'],
':input[name="name"]' => ['filled' => TRUE],
],
],
];
<?php
// Show the "email" field when either:
// * Anonymous is checked and method is email
// OR
// * The "name" is filled and the method is email
$form['email'] = [
'#type' => 'textfield',
'#title' => t('Email'),
'#states' => [
'visible' => [
[
':input[name="anonymous"]' => ['checked' => TRUE],
':select[name="method"]' => ['value' => 'email'],
],
[
':input[name="name"]' => ['filled' => TRUE],
':select[name="method"]' => ['value' => 'email'],
],
],
],
];
<?php
// Show the email field when either condition is TRUE, but not both
// * Anonymous is checked and method is email
// * The "name" is filled and the method is email
$form['email'] = [
'#type' => 'textfield',
'#title' => t('Email'),
'#states' => [
'visible' => [
':input[name="anonymous"]' => ['checked' => TRUE],
':select[name="method"]' => ['value' => 'email'],
],
'xor',
[
':input[name="name"]' => ['filled' => TRUE],
':select[name="method"]' => ['value' => 'email'],
],
],
],
];
<?php
$form['first_name'] = [
'#type' => 'textfield',
'#title' => t('First Name'),
];
// Make "last_name" required if "first_name" is filled.
$form['last_name'] = [
'#type' => 'textfield',
'#title' => t('Last Name'),
'#states' => [
'required' => [
':input[name="first_name"]' => ['filled' => TRUE],
],
],
];
Also, you can use for select wildcard selectors (*, ^ and $) like CSS for classes like this:
<?php
$form['first_name'] = [
'#type' => 'textfield',
'#title' => t('First Name'),
];
// Make "last_name" required if any field ends with "_name" is filled.
$form['last_name'] = [
'#type' => 'textfield',
'#title' => t('Last Name'),
'#states' => [
'required' => [
':input[name$="_name"]' => ['filled' => TRUE],
],
],
];
The following states may be applied to an element:
- enabled
- disabled
- required
- optional
- visible
- invisible
- checked
- unchecked
- expanded
- collapsed
The following states may be used in remote conditions:
- empty
- filled
- checked
- unchecked
- expanded
- collapsed
- value
The following states exist for both elements and remote conditions, but are not fully implemented and may not change anything on the element:
- relevant
- irrelevant
- valid
- invalid
- touched
- untouched
- readwrite
- readonly