Change record status: 
Project: 
Introduced in branch: 
7.x, 8.x
Introduced in version: 
7.14
Description: 

Change

  • #states now support OR and XOR conditions

Example

  $form['dependent_1']['#states'] = array(
    'disabled' => array(
    // dependee_1 has value ON
      '[name="dependee_1"]' => array('value' => 'ON'),
      array(
      // At least one of dependee_2 or dependee_3 has value ON
        array('[name="dependee_2"]' => array('value' => 'ON')),
        array('[name="dependee_3"]' => array('value' => 'ON')),
      ),
      array(
      // Only one of dependee_4 or dependee_5 can have value ON
        array('[name="dependee_4"]' => array('value' => 'ON')),
        'xor',
        // The field should be disabled when Select #1 has value ON; at least one
        // of Select #2 and Select #3 has value ON; one but only one of Select #4
        // and Select #5 has value ON.
        array('[name="dependee_5"]' => array('value' => 'ON')),
      ),
    )
  );
Impacts: 
Site builders, administrators, editors
Module developers
Themers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

Calcifer’s picture

I've followed your instructions but my code doesn't work. I have this situation:

two select boxes, if you select option '' and 3 on the first, the second disappers.

For this, i've written this code:

'octo_insurance_situation' => array (
  '#type' => 'select',
  '#title' => 'Situazione assicurativa',
  '#required' => false,
  '#default_value' => '',
  '#options' => array (
    '' => t('- Select -'),
    1 => 'Prima assicurazione per un\'auto nuova',
    2 => 'Prima assicurazione per un\'auto usata',
    3 => 'Già assicurato con contratto Bonus/Malus',
  ),
),
'octo_bersani_available' => array (
  '#type' => 'select',
  '#title' => 'Puoi usufruire della Bersani?',
  '#required' => false,
  '#default_value' => '',
  '#states' => array(
    'invisible' => array(
      array(
        array(':input[name="octo_insurance_situation"]' => array('value' => '')),
        array(':input[name="octo_insurance_situation"]' => array('value' => '3')),
      ),
    ),
  ),
  '#options' => array (
      1 => 'No',
      2 => 'Sì, il veicolo già assicurato è mio',
      3 => 'Sì, il veicolo già assicurato è di un mio familiare convivente',
  ),
),

But when i change the first select, the second doesn't disappear.

Have you got any solutions? Maybe my code is wrong?
Thans,

C.

klonos’s picture

I have always used https://www.lullabot.com/articles/form-api-states as my go-to article for remembering/revisiting conditionals in #states. The code snippet in this change record is confusing, and demonstrates 3 different examples (simple condition, then an OR, and then an XOR, all wrapped in additional arrays, which basically puts an OR between the examples).

Here's a simplified version of the various conditionals allowed within states after this change:

Simple condition:

  $form['whatever']['#states'] = array(
    'disabled' => array(
      '[name="dependee_1"]' => array('value' => 'ON'),
    ),
  );

AND condition:

  $form['whatever']['#states'] = array(
    'disabled' => array(
      '[name="dependee_1"]' => array('value' => 'ON'),
      '[name="dependee_2"]' => array('value' => 'ON'),
    ),
  );

OR condition (same as the previous example, but conditions are wrapped within additional arrays):

  $form['whatever']['#states'] = array(
    'disabled' => array(
        array(
          '[name="dependee_1"]' => array('value' => 'ON')
        ),
        array(
          '[name="dependee_2"]' => array('value' => 'ON')
        ),
    ),
  );

XOR condition (same as the previous example, but there's a textual 'xor' between the OR arrays):

  $form['whatever']['#states'] = array(
    'disabled' => array(
        array(
          '[name="dependee_1"]' => array('value' => 'ON')
        ),
        'xor',
        array(
          '[name="dependee_2"]' => array('value' => 'ON')
        ),
    ),
  );