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