Author image
Senior Developer

Dynamic forms in Drupal 7

When building forms, you will often want to only provide certain options if other options are chosen by a user. For example, there's no need to show the 'open link in new window' checkbox, if the 'make this into a link' checkbox hasn't been ticked. These kinds of dynamic forms haven't been easily available for Drupal... until now, with the #states for form elements in Drupal 7.

Take a peek at this example of dynamic forms in Drupal 7.

To make one form element be dependent on another element, you may have delved into AJAX, or tried using CTools for form item dependency. Doing it with AJAX isn't simple, and using CTools isn't always an option and includes various caveats. Now, you can make dynamic froms in Drupal 7, straight 'out of the box'! Here's an example element that depends on the make_link checkbox being ticked:

$element['new_window'] = array(
  '#type' => 'checkbox',
  '#title' => t('Open link in new window'),
  '#default_value' => $settings['new_window'],
  '#states' => array(
    'visible' => array(   // action to take.
      ':input[name="fields[field_my_field][settings_edit_form][settings][make_link]"]' // element to evaluate condition on
        => array('checked' => TRUE),  // condition
    ),
  ),
);

That new #states is the bit to look at. It contains the action (make 'visible') to take when another form item (an <input> element, with a certain value in the name attribute) has it's checked attribute as TRUE. The action can be various things - e.g. visible, checked, expanded, collapsed. The element could be any HTML element - just write it as a jQuery selector. Then the condition is just evaluated on that element, to decide whether to do the action (make our new_window element visible in this case).

If using the name attribute, ensure you surround the value with quotes -- this is what I had trouble with, because of all the square brackets that get added if your element is within fieldsets.

Your users will immediately appreciate dynamic forms, since they allow forms to be much tidier rather than displaying all sorts of additional options. Easier to use websites mean happier customers!

For much more on dynamic forms in Drupal 7 using #states, see the full documentation for drupal_process_states() to get you going. You'll find a list of all the actions you can use, and how to depend on multiple conditions. The Drupal 7 Form API for #states may be useful - this page should be bookmarked by all Drupal developers!

I learnt the majority of this having seen Randy Fay's article on #states and then exploring the example at d7.drupalexamples.info, plus browsing around the Drupal issue queues.

Edit: I added a follow-up post on using multiple conditions in #states. Take a look.