18

How can I have multiple values trigger the Form API's #states?

Say for example, I wanted this field to be visible not only if the value is 5 (currently works below), but wanted to make the field visible if the the values are 3, 4 or 5.

'#states' => array(
    'visible' => array(
       ':input[name="field_star_rating"]' => array('value' => t('5')),
    ),
),

As a note, I tried the following and it does not work. It only works if the value is '4'

'#states' => array(
    'visible' => array(
        ':input[name="field_star_rating"]' => array('value' => t('5')),
        ':input[name="field_star_rating"]' => array('value' => t('4')),
    ),
),

This also does not work, it too only works if the value is '4':

'#states' => array(
    'visible' => array(
        ':input[name="field_star_rating"]' => array('value' => t('5'), 'value' => t('4')),
    ),
),
37
+50

Here's what you need:

'#states' => array(
    'visible' => array(
        ':input[name="field_star_rating"]' => array(
            array('value' => t('5')),
            array('value' => t('4'))
        ),
    ),
),
  • This is indeed the correct way, the current one marked as correct is wrong. See this issue for more info: drupal.org/node/735528 – Robin Jan 3 '13 at 4:52
  • The #states API sure has come a long way sense 2011. Marking as correct. – Citricguy Feb 6 '14 at 1:51
  • this is a great answer, and I came here from Google, like a dozen times... a bounty is on its way. – AyeshK Mar 27 '15 at 3:41
  • It is working fine for normal view. After running any 'ajax', it added again and again – Guru Nov 23 '15 at 11:10
3

Only way I could figure is to use #ajax in D7.

Here are a few helpful tip's I wish I would have known before starting.

  1. #ajax in the form API is awesome and worth learning
  2. #states does not support OR or XOR (Without a patch? http://drupal.org/node/735528 )
  3. dpm($form); and var_dump($form_state) on a custom submit function are priceless

Here is a modified version of one of the AJAX examples from the examples module.

function plugin_autotextfields($form, &$form_state) {

    $form['star_rating'] = array(
        '#type' => 'select',
        '#title' => t('Star Rating'),
        '#options' => array('_none' => '- select -', 5 => '5 Star', 4 => '4 Star', 3 => '3 Star', 2 => '2 Star', 1 => '1 Star'),
        '#ajax' => array(
            'callback' => 'plugin_autotextfields_callback',
            'wrapper' => 'textfields',
            'effect' => 'fade',
        ),
    );

    $form['textfields'] = array(
        '#title' => t("Fieldset Name"),
        '#prefix' => '<div id="textfields">',
        '#suffix' => '</div>',
        '#type' => 'fieldset',
        '#description' => t('Where the field will be placed'),
    );

    if (!empty($form_state['values']['star_rating']) && $form_state['values']['star_rating'] == 5) {
        $form['textfields']['review'] = array(
            '#type' => 'textfield',
            '#title' => t('Message if 5 stars'),
        );
    } else if (!empty($form_state['values']['star_rating'])) {
        $form['textfields']['review'] = array(
            '#type' => 'textfield',
            '#title' => t('Message if not 5 stars'),
        );
    }

    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Click Me'),
    );

    return $form;
}

function omfg_autotextfields_callback($form, $form_state) {
    return $form['textfields'];
}

I hope this helps someone that runs into the same problem :)

  • Wow! Very helpful answer my friend. I have been wrapping my head around an issue with #states and now have it working but #ajax would of obviously been easier now that you slapped me with a clue-stick. And that debugging tip as a bonus? Sorry I have to pay you with measly karma. ;) – stefgosselin Apr 24 '12 at 8:28
3
 $form['student_type'] = array(
    '#type' => 'checkboxes',
    '#options' => array(
      'high_school'   => t('High School'),
      'undergraduate' => t('Undergraduate'),
      'graduate'      => t('Graduate'),
    ),
    '#title' => t('What type of student are you?')
  );

// High school information.
  $form['high_school']['tests_taken'] = array(
    '#type' => 'textfield',
    '#title' => t('What standardized tests did you take?'),
    '#states' => array(
      'visible' => array(   // action to take.
        ':input[name="student_type[high_school]"]' => array('checked' => TRUE),
        ':input[name="student_type[undergraduate]"]' => array('checked' => TRUE),
        ':input[name="student_type[graduate]"]' => array('checked' => FALSE),
      ),
    ),
  );

P.S. See the examples module for more features "form_example/form_example_states.inc"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.