Thursday 26 January 2012

Conditional fields in Drupal 7

Have you ever had to create a conditional input field? For example, one field is a checkbox that reads "Do you have children?" and if the user selects "Yes", we want to show an additional input field that asks "How many?" (and if the user selects "No" the field disappears).
I ran into this in a recent project and, as usual, added some custom javascript using #after_build that did exactly that. I'm pretty sure this is a widespread practice.

The secret is to use the new "container" type to wrap our conditional elements and control their visibility through the #states attribute:
$form['haskids'] = array(
  '#type' => 'checkbox',
  '#title' => t('Do you have children?'),
);
 $form['kids_container'] = array(
  '#type' => 'container',
  '#states' => array(
    'invisible' => array(
      'input[name="haskids"]' => array('checked' => FALSE),    ),
  ),
);
 
$form['kids_container']['numkids'] = array(  '#type' => 'textfield',
  '#title' => t('How many?'),
);
 
Using #states, we defined an invisible state for the container,
 which is triggered when the value of the "checked" attribute of the 
input specified by the selector is FALSE. It might at first seem a 
little confusing to mix in jQuery selector in PHP, but this is just how 
Drupal rolls and manages to bind the javascript event automatically. If 
in dobut, simply replace name="haskids" with your field's "name" attribute!