Change the states of an element based on another element (field) | Drupal 8

Change the states of an element based on another element (field)

Submitted by editor on Tue, 01/31/2017 - 17:18
Question

How to change the visibility of an afield element based on another field element ?

Note : The tutorial is usins States VISIBLE, but can also use for other html parameters such as : REQUIRED, EXPENDED, CHECKED ...

The selector is an "JQUERY_SELECTOR"

The field API adds JavaScript (AJAX) to change the state of an element (form)  based on another element.

Example 1. Show/Hide a field depend on a select box value

$form['testfield'] = array(
  '#type' => 'select',
  '#title' => $this->t('Select'),
  '#options' => array('a' => 'a', 'b' => 'b', 'c' => 'c'),
);
$form['display'] = array(
  '#title' => t('Display B'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[id="edit-testfield"]' => array('value' => 'b'),
    ),
  ),
);
$form['display2'] = array(
  '#title' => t('Display C value'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      'select[name="testfield"]' => array('value' => 'c'),
    ),
  ),
);
$form['display3'] = array(
  '#title' => t('Display C value : Short syntax'),
  '#type' => 'textfield',
  '#states' => ['visible' => [':input[name="testfield"]' => ['checked' => TRUE],],],
);

Example 2 : Show/Hide field according to the value of a checkbox

$form['testfield'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('A check box'),
);
$form['display1'] = array(
  '#title' => t('1 - Just display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[name="testfield"]' => array('checked' => TRUE),
    ),
  ),
);
$form['display2'] = array(
  '#title' => t('2 - Just display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[id="edit-testfield"]' => array('checked' => FALSE),
    ),
  ),
);

Example 3 : Show/Hide Fields using a value of an array (field)

$form['settings'] = [
  '#type' => 'details',
  '#title' => 'Settings',
  '#tree' => TRUE,
  '#open' => TRUE,
];
$form['settings']['testfield'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('A check box'),
);
$form['settings']['display1'] = array(
  '#title' => t('1 - Just display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[name="settings[testfield]"]' => array('checked' => TRUE),
    ),
  ),
);
$form['display2'] = array(
  '#title' => t('2 - Just display : visible if NOT checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[id="edit-settings-testfield"]' => array('checked' => FALSE),
    ),
  ),
);
$form['display3'] = array(
  '#title' => t('3 - display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[name$="[testfield]"]' => array('checked' => TRUE),
    ),
  ),
);

Example 4 : Usage of container : Show/Hide a Test (#Markup : type = markup)

$form['testfield'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('A check box'),
);
$form['display'] = array(
  '#type' => 'container',
  '#states' => array(
    'visible' => array(
      ':input[id="edit-testfield"]' => array('checked' => TRUE),
    ),
  ),
);
$form['display']['a_markup'] = array(
  '#type' => 'markup',
  '#markup' => "Just a text, visible if checked",
);

 

Example 5 : Usage in a FieldFormatter (Drupal\Core\Field\FormatterBase ...)

  $elements['selectable'] = [
    '#title' => t('Selectable'),
    '#type' => 'checkbox',
    '#default_value' => $this->getSetting('selectable'),
  ];
  $elements['style'] = array(
    '#title' => t('Apply CSS'),
    '#type' => 'checkbox',
    '#default_value' => $this->getSetting('style'),
    '#states' => array(
      'visible' => array(
        ':input[name="selectable"]' => array('checked' => TRUE),
      ),
    ),
  );

 

Example 6 : Multiple posibilities (OR)

'visible' => array(
  array(
    ':input[name="name"]' => array('filled' => TRUE),
  ),
  array(
    'select[name="method"]' => array('value' => 'email'),
  ),
),
),

 
Example 7 : Multiple conditions (AND)

'visible' => array(
  array(
    ':input[name="name"]' => array('filled' => TRUE),
    'select[name="method"]' => array('value' => 'email'),
  ),
),
),

 

 

Other Examples (Not tested).

$form['testfield'] = array(
  '#type' => 'checkbox',
  '#title' => $this->t('Checkbox'),
);
//Example 2 - 1
$form['display1'] = array(
  '#title' => t('1 - Just display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[name$="[testfield]"]' => array('checked' => TRUE),
    ),
  ),
);
//Example 2 - 2
$form['display2'] = array(
  '#title' => t('2 - Just display : visible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'visible' => array(
      ':input[name$="settings[testfield]"]' => array('checked' => TRUE),
    ),
  ),
);
//Example 2 - 3
$form['display3'] = array(
  '#type' => 'container',
  '#states' => array(
    'visible' => array(
      ':input[id="edit-settings-testfield"]' => array('checked' => TRUE),
    ),
  ),
);
$form['display3']['a_markup'] = array(
  '#type' => 'markup',
  '#markup' => "3 - Just a text, visible if checked",
);
//Example 2 - 4
$form['display4'] = array(
  '#title' => t('4 - invisible if checked'),
  '#type' => 'textfield',
  '#states' => array(
    'invisible' => array(
      ':input[id="edit-settings-testfield"]' => array('checked' => TRUE),
    ),
  ),
);

 

Example of state usage in a settings edit form (Like field display settings ...  here settings_edit_form )

$elements['display'] = [
  '#title' => t('Show'),
  '#type' => 'checkbox',
  '#default_value' => $this->getSetting('display'),
];
// Hide field conditional.
$elements['display_2'] = [
  '#title' => t('Show 2'),
  '#type' => 'checkbox',
  '#default_value' => $this->getSetting('display_2'),
  '#states' => [
    'visible' => [
      ':input[name$="[settings_edit_form][settings][display]"]' => ['checked' => TRUE],
    ],
  ],
];

Example with text area:

=> [
    'textarea[name="field_body[und][0][value]"]' =>
      ['value' => 'THE_VALUE']
  ];

 

The States scope

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

 

 

Help : https://api.drupal.org/api/drupal/core%21includes%21common.inc/function/drupal_process_states/8.2.x
More examples : https://www.lullabot.com/articles/form-api-states

Comments

Add new comment