In this example, we just use checkboxes to determine whether textboxes are displayed.
One of the fundamental ideas of having a form change based on selections within the form is that the form is reconfiguring itself based on $form_state. So here, the generation of the form is driven by $form_state['values']. If the checkbox for last name is checked, then we generate a textfield for last name.
(Experiment with this one at http://d7.drupalexamples.info/examples/ajax_example/autotextfields or see the current code at http://api.drupal.org/api/function/ajax_example_autotextfields/7.)
<?php
/<strong>
* Show/hide textfields based on AJAX-enabled checkbox clicks.
*/
function ajax_example_autotextfields($form, &$form_state) {
$form['ask_first_name'] = array(
'#type' => 'checkbox',
'#title' => t('Ask me my first name'),
'#ajax' => array(
'callback' => 'ajax_example_autotextfields_callback',
'wrapper' => 'textfields',
'effect' => 'fade',
)
);
$form['ask_last_name'] = array(
'#type' => 'checkbox',
'#title' => t('Ask me my last name'),
'#ajax' => array(
'callback' => 'ajax_example_autotextfields_callback',
'wrapper' => 'textfields',
'effect' => 'fade',
),
);
$form['textfields'] = array(
'#title' => t("Generated text fields for first and last name"),
'#prefix' => '<div id="textfields">',
'#suffix' => '</div>',
'#type' => 'fieldset',
'#description' => t('This is where we put automatically generated textfields'),
);
if (!empty($form_state['values']['ask_first_name']) && $form_state['values']['ask_first_name']) {
$form['textfields']['first_name'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
);
}
if (!empty($form_state['values']['ask_last_name']) && $form_state['values']['ask_last_name']) {
$form['textfields']['last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last Name'),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Click Me'),
);
return $form;
}
/</strong>
* Selects the piece of the form we want to use as replacement text and returns
* it as a form (renderable array).
*
* @return renderable array (the textfields element)
*/
function ajax_example_autotextfields_callback($form, $form_state) {
return $form['textfields'];
}
?>
5 Comments
behaving strangely in hook_form_alter
Submitted by Phil on
Hi,
I'm trying to ajaxify an existing form (drupal commerce checkout form) using a custom module with hook_form_alter. The code above pretty much does what I want to do - have a checkbox that alters other elements in the form when it is checked/unchecked.
I thought I'd start off by just C&Ping the code above into my hook_form_alter function. It works fine if I'm logged in - changing the select box causes the fieldset to be reloaded with the correct number of checkboxes.
However if visit the site as an anonymous user the ajax call is only made the first time I change the select box. Subsequent changes do nothing.
Any idea what I'm doing wrong?
Is hook_form_alter the right place to put this code if I'm modifying an existing form?
Thanks!
Page caching?
Submitted by rfay on
Does turning off page caching affect the behavior?
no
Submitted by Phil on
turning off all caching makes no difference.
Make a simple module that demonstrates it; make a sandbox
Submitted by rfay on
If you'll make a simple module (bare bones) that demonstrates this and push it to a sandbox or github or something, I'll take a look at it.
Probably best to make an issue in Commerce queue and point me to it.
thanks
Submitted by Phil on
Thanks Randy, will do.