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;
}

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;
}

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.'));
}
}
