I've started using the forms API and am getting into AJAX. There are two places where I've inserted it. The first is a select box which, when changed, updates another part of the form. This part works correctly. The second is a button that adds additional fields to the form when pressed. This doesn't work. I think the problem is that for whatever reason, the form isn't being rebuilt. I've confirmed that my custom submit handler is understanding the button press and is incrementing $form_state['app']['counts'][$fieldname]
properly, and my AJAX callback is returning the correct part of the form.
This is the code that generates the form element:
// If the options include MULTIPLE, add extra fields based on
// $form_state['app']['counts'][$fieldname] and add a field to
// increase that number.
if ($multiple) {
$form[$fieldname] += array(
'#type' => 'fieldset',
'#prefix' => "<div id=\"appform-$fieldname-div\">",
'#suffix' => '</div>',
'#tree' => TRUE,
);
// If the field count hasn't been set, set it to 1.
if (!isset($form_state['app']['counts'][$fieldname])) {
// If there are $values specified, pull the number from there instead.
$form_state['app']['counts'][$fieldname] =
(empty($values[$fieldname]) ? 1 : count($values[$fieldname]));
}
// This message appears during the other AJAX callback based on a <select> element, but not when pressing the button.
drupal_set_message("$fieldname has {$form_state['app']['counts'][$fieldname]} fields.");
for ($i = 1; $i < $form_state['app']['counts'][$fieldname]; ++$i) {
$form[$fieldname][$i] = $form[$fieldname][0];
}
// Insert the button to add more fields to this part of the form.
$form[$fieldname]['more'] = array(
'#type' => 'submit', // Should this be 'submit' or 'button'? It doesn't seem to work right with 'button'.
'#value' => t('Add another acceptable response'),
'#submit' => array('_appform_more'), // I've confirmed that this handler properly increments $form_state['app']['counts'][$fieldname] when the button is pressed.
'#limit_validation_errors' => array(),
'#ajax' => array(
'callback' => '_appform_ajax', // I've confirmed that this callback is properly returning the correct form element and that $form_state['app']['counts'][$fieldname] has been incremented. Do I need to manually rebuild the form here?
'wrapper' => "appform-$fieldname-div",
'method' => 'replace',
'effect' => 'fade',
),
}
}
(it's not actually called 'app'; I've changed the name for this request)
Comments
Comment #1
meustrus CreditAttribution: meustrus commentedSo I've made this functional now. I threw in a call to drupal_rebuild_form, and several problems later ended up changing the
'more'
button to'#type' => 'button', '#submit' => array()
and moved the submit handler code to the AJAX handler (because it won't fire when it is'#type' => 'submit'
). Is it OK that the AJAX handler alters form state and rebuilds the form? This is the new AJAX handler:Comment #2
nod_To make ajax form loaded via ajax work
Drupal.settings
needs to be updated with the ajax settings of the new form elements. I haven't looked at which level that should be done but overall that's the way to go.Comment #3
meustrus CreditAttribution: meustrus commentedI will restate that it does work now; maybe
Drupal.settings
is getting updated, or maybe there's some kind of black magic going on in my situation to make it work. Unless it needs to be updated for the form to be rebuilt properly? I would like a clarification that it's OK to calldrupal_rebuild_form($form['#form_id'], $form_state, $form)
inside the AJAX callback.Comment #4
sokrplare CreditAttribution: sokrplare commentedConfirming what meustrus ran into. Maybe intended behavior, but seems odd that a callback on a textfield rebuilds the form, but the callback on the submit button doesn't. Dropped in the call to
drupal_rebuild_form()
and it started working which makes sense.Comment #13
nod_I'm guessing a solution has been found by now.