Drupal Form API - Conditional Fields

In a previous Drupal developer blog post, I discussed leveraging Ajax with Drupal's Form API. In this post we'll cover an alternative method in displaying dynamic content to your user - using Drupal's form states (conditional fields).

Using form states is really quite simple. It's just a Drupal Form API attribute and is used to display any kind of form content conditionally (conditional form fields). Commonly, a user may have some option, like a select list and different form fields may hide or show (using jQuery) based on the user's selection (often times referred to as dependent dropdowns). In this Drupal 7 example we'll create a basic form with a radio button and show an addition textfield based on their selection.

First, lets create a basic Drupal form. We'll start out with a simple select with two options and a submit button to close out the form.

/**
 * Custom Example Form.
 */
function deckfifty_conditional_form($form, &$form_state) {
  $form['drupal_love'] = array(
    '#title' => t('Do you love Drupal?'),
    '#type' => 'radios',
    '#options' => array('yes' => t('Yes'), 'no' => t('No')),
  );

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

  return $form;
}

Next, we'll add a simple textfield below the radio buttons.

function deckfifty_conditional_form($form, &$form_state) {
  $form['drupal_love'] = array(
    '#title' => t('Do you love Drupal?'),
    '#type' => 'radios',
    '#options' => array('yes' => t('Yes'), 'no' => t('No')),
  );
  $form['how_much_love'] = array(
    '#title' => t('Great! Tell us more:'),
    '#type' => 'textfield',
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );

  return $form;
}

Drupal Form API Conditional Fields
Lastly, we'll add the "states" attribute so the textfield will only display (with jQuery) when the the user selects "Yes".

function deckfifty_conditional_form($form, &$form_state) {
  $form['drupal_love'] = array(
    '#title' => t('Do you love Drupal?'),
    '#type' => 'radios',
    '#options' => array('yes' => t('Yes'), 'no' => t('No')),
  );
  $form['how_much_love'] = array(
    '#title' => t('Great! Tell us more:'),
    '#type' => 'textfield',
    '#states' => array(
      'visible' => array(
        ':input[name="drupal_love"]' => array('value' => 'yes'),
      ),
    ),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );

  return $form;
}

Drupal Form API Conditional Fields
Pretty simple, right? Try implementing conditional fields in your next project to enhance your Drupal forms!


Updated: Jun 3 2014
As requested in the comments, let's update the form so the textfield is required if "yes" is selected.

First we'll add to the states array by adding a "required" key.

function deckfifty_conditional_form($form, &$form_state) {
  $form['drupal_love'] = array(
    '#title' => t('Do you love Drupal?'),
    '#type' => 'radios',
    '#options' => array('yes' => t('Yes'), 'no' => t('No')),
  );
  $form['how_much_love'] = array(
    '#title' => t('Great! Tell us more:'),
    '#type' => 'textfield',
    '#states' => array(
      'visible' => array(
        ':input[name="drupal_love"]' => array('value' => 'yes'),
      ),
      'required' => array(
        ':input[name="drupal_love"]' => array('value' => 'yes'),
      ),
    ),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );

  return $form;
}

Done right!? Since this is client side, it's only adding the required class so we see the red asterisk. To validate, we'll need to provide a bit of field checking in our validation handler.

function deckfifty_conditional_form_validate($form, &$form_state) {
  
  if ($form_state['values']['drupal_love'] == 'yes' && empty($form_state['values']['how_much_love'])) {
    form_set_error('how_much_love', t('Please enter a value.'));
  }
  
}

Drupal Form API Conditional Fields

Shane Graham

Shane Graham

Shane Graham is a senior Drupal developer and co-founder of Deck Fifty Design.

Get in touch

Let's go!

We look forward to hearing from you!