1 common.inc backdrop_process_states(&$elements)

Adds JavaScript to change the state of an element based on another element.

A "state" means a certain property on a DOM element, such as "visible" or "checked". A state can be applied to an element, depending on the state of one or more other elements on the page. In general, states depend on HTML attributes and DOM element properties, which change due to user interaction.

Since states are driven by JavaScript only, it is important to understand that all states are applied on presentation only, none of the states force any server-side logic, and that they will not be applied for site visitors without JavaScript support. All modules implementing states have to make sure that the intended logic also works without JavaScript being enabled.

#states is an associative array in the form of:

'#states' => array(
  STATE1 => CONDITIONS_ARRAY1,
  STATE2 => CONDITIONS_ARRAY2,
  ...
)

Each key is the name of a state to apply to the element, such as "visible" or "checked". Each value is a list of conditions that denote when the state should be applied.

Multiple conditions may be specified for a given state. In this case (an 'AND' conditional), all conditions must be true for the state to be applied:

'#states' => array(
  STATE1 => array(
    // All of these conditions must be true; this one...
    JQUERY_SELECTOR1 => CONDITION1,
    // ...AND this one.
    JQUERY_SELECTOR2 => CONDITION2,
  ),
  STATE2 => CONDITIONS_ARRAY2,
  ...
)

For 'OR' conditionals, each condition must be wrapped in its own array:

'#states' => array(
  STATE1 => array(
    // Any of these conditions must be true; this one...
    array(JQUERY_SELECTOR1 => CONDITION1),
    // OR this one (or both).
    array(JQUERY_SELECTOR2 => CONDITION2),
  ),
  STATE2 => CONDITIONS_ARRAY2,
  ...
)

For 'XOR' (exclusive 'OR') conditionals, a similar syntax as 'OR' is used, but the 'XOR' operator needs to be explicitly defined as an array item with the string 'xor':

'#states' => array(
  STATE1 => array(
    // Either one of these conditions must be true; this one...
    array(JQUERY_SELECTOR1 => CONDITION1),
    'xor',
    // or this one, but NOT both.
    array(JQUERY_SELECTOR2 => CONDITION2),
  ),
  STATE2 => CONDITIONS_ARRAY2,
  ...
)

Each remote condition is a key/value pair specifying conditions on the other element that need to be met to apply the state to the element:

array(
  'visible' => array(
    ':input[name="remote_checkbox"]' => array('checked' => TRUE),
  ),
)

For example, to show a textfield only when a checkbox is checked:

$form['toggle_me'] = array(
  '#type' => 'checkbox',
  '#title' => t('Tick this box to type'),
);
$form['settings'] = array(
  '#type' => 'textfield',
  '#states' => array(
    // Only show this field when the 'toggle_me' checkbox is enabled.
    'visible' => array(
      ':input[name="toggle_me"]' => array('checked' => 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

Note that the 'required' and 'optional' states only affect the display of the required indicator (i.e. the red asterisk). They *do not* affect validation in any way. If you need a form element to be required based on the state of another element, you must implement your own form validation to account for that.

When referencing select lists and radio buttons in remote conditions, a 'value' condition must be used:

  '#states' => array(
    // Show the settings if 'bar' has been selected for 'foo'.
    'visible' => array(
      ':input[name="foo"]' => array('value' => 'bar'),
    ),
  ),

To specify what a value should NOT be, use '!value':

  '#states' => array(
    // Show the settings if 'bar' has NOT been selected for 'foo'.
    'visible' => array(
      ':input[name="foo"]' => array('!value' => 'bar'),
    ),
  ),

Parameters

$elements: A renderable array element having a #states property as described above.

See also

form_example_states_form()

File

core/includes/common.inc, line 5354
Common functions that many Backdrop modules will need to reference.

Code

function backdrop_process_states(&$elements) {
  $elements['#attached']['library'][] = array('system', 'backdrop.states');
  $elements['#attached']['js'][] = array(
    'type' => 'setting',
    'data' => array('states' => array('#' . $elements['#id'] => $elements['#states'])),
  );
}