I was recently working on a site where I wanted to use the '#states' key in a form using the Drupal 7 Form API. If you haven't come across this yet its a great way to only show a field depending on a certain set of circumstances. This example was fairly simple, show a set of radio buttons if a checkbox was ticked. It looked something like this:

$form['check_box'] = array(
  '#type' => 'checkbox',
  '#title' => 'Tick this checkbox if you would like to see the radio buttons',
);

$form['set_of_radiobuttons'] = array(
  '#type' => 'fieldset',
);
    
$form['set_of_radiobuttons']['radio_buttons'] = array(
  '#type' => 'radios',
  '#options' => array('Radio Button 1', 'Radio Button 2', 'Radio Button 3'),
  '#states' => array(
    // Only show this field when the checkbox is enabled.
    'visible' => array(
      ':input[name="check_box"]' => array('checked' => TRUE),
    ),
  ),
);

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

The expected out come of this would be to get a form with only a checkbox visible and when you click on the checkbox a series of radio buttons became visible beneath them. Similarly when you un-check the checkbox the radio buttons would become invisible again. However the actual results were:

Unchecked:

Checked:

As you can see, not only was the state action not working but it was actually doing the complete opposite of what it was supposed to do.

The form I was trying to get the state function to work on was in the midst of a large multi-step form with various layers of fieldsets, with various form elements being sent through their own individual theming and I was sure that something I had done would be the cause for the issue. I commented out the theming, took out all the nested fieldsets and removed any custom js files I could find to try and debug the problem, but the solution was simple: jQuery Update. You can read a bit more information about some of the other issues created by jquery_update here.

Once I disabled jQuery Update everything worked like a charm again. I had to write some code to prevent jQuery update from appearing specific pages (this form) and then hurray, everything was working as expected!

Alternatively if you're comfortable with altering core then you can apply this patch which also fixes the problem.

Comments

Wouldn't applying the '#states' property to the radio fieldset, not the radio field itself also fix this issue?