The little-known #states feature has gone into Drupal 7, and it rocks.
Essentially, you can provide dynamic behavior in a form based on changes to other elements in the form. An easy example: Often you only need to collect information if a particular element is selected. If they select type=student, you don't have to require them to fill in a further "Employer" field.
The idea of #states is that you add a #states property to a form element that is supposed to change when some other form element changes. So if a form element is supposed to be shown or hidden, the #states property will be added on that element, not on the element that caused the change.
The #states property is a structured array of action => condition arrays. The action is 'visible' or 'checked' or 'required' or several other options. The condition is an associative array of 'jquery_selector' => array(value_statement). But mostly you can do it by copying and pasting examples. Much of the time the jquery selector can be ":input[name=field_name]" and the rest of the array can be cookbook from example code.
In the example, the 'tests_taken' field is only to be visible if the form-filler is a high school student:
$form['tests_taken'] = array(
'#type' => 'checkboxes',
'#options' => drupal_map_assoc(array(t('SAT'), t('ACT'))),
'#title' => t('What standardized tests did you take?'),
'#states' => array(
'visible' => array( // action to take.
':input[name=student_type]' => array('value' => t('High School')),
So we set the action to 'visible' when the condition (our select called student_type is set to 'High School') is true.
That's basically all there is to it.
So when would you use #states as opposed to AJAX forms or a sprinkling of jquery?
- If your form actually changes under the hood based on user input, then you need to use AJAX forms. #states doesn't fundamentally change any of the elements, it just changes their presentation.
- If you don't change the form, but need a transformation that simple conditional logic can't do, you'll have to roll some jQuery.
For more detailed comments and possibilities, read the #states example.