Commit f8b63338 authored by Dries's avatar Dries

- Patch #756762 by effulgentsia, fago, sun, rfay, pwolanin: AJAX should follow...

- Patch #756762 by effulgentsia, fago, sun, rfay, pwolanin: AJAX should follow same rules for whether to call drupal_rebuild_form() as non-AJAX submissions.
parent 1b3c481a
......@@ -239,6 +239,12 @@ function ajax_get_form() {
// Since some of the submit handlers are run, redirects need to be disabled.
$form_state['no_redirect'] = TRUE;
// When a form is rebuilt after AJAX processing, its #build_id and #action
// should not change.
// @see drupal_rebuild_form()
$form_state['rebuild_info']['copy']['#build_id'] = TRUE;
$form_state['rebuild_info']['copy']['#action'] = TRUE;
// The form needs to be processed; prepare for that by setting a few internal
// variables.
$form_state['input'] = $_POST;
......@@ -263,18 +269,15 @@ function ajax_get_form() {
* enhanced function.
*/
function ajax_form_callback() {
list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
// Build, validate and if possible, submit the form.
drupal_process_form($form_id, $form, $form_state);
// This call recreates the form relying solely on the $form_state that
// drupal_process_form() set up.
$form = drupal_rebuild_form($form_id, $form_state, $form);
// As part of drupal_process_form(), the element that triggered the form
// submission is determined, and in the case of AJAX, it might not be a
// button. This lets us route to the appropriate callback.
list($form, $form_state) = ajax_get_form();
drupal_process_form($form['#form_id'], $form, $form_state);
// We need to return the part of the form (or some other content) that needs
// to be re-rendered so the browser can update the page with changed content.
// Since this is the generic menu callback used by many AJAX elements, it is
// up to the #ajax['callback'] function of the element (may or may not be a
// button) that triggered the AJAX request to determine what needs to be
// rendered.
if (!empty($form_state['triggering_element'])) {
$callback = $form_state['triggering_element']['#ajax']['callback'];
}
......
......@@ -495,9 +495,12 @@ function _batch_finished() {
// Use drupal_redirect_form() to handle the redirection logic.
drupal_redirect_form($_batch['form_state']);
// If no redirection happened, save the final $form_state value to be
// retrieved by drupal_get_form() and redirect to the originating page.
$_SESSION['batch_form_state'] = $_batch['form_state'];
// If no redirection happened, redirect to the originating page. In case the
// form needs to be rebuilt, save the final $form_state for
// drupal_build_form().
if (!empty($_batch['form_state']['rebuild'])) {
$_SESSION['batch_form_state'] = $_batch['form_state'];
}
$function = $_batch['redirect_callback'];
if (function_exists($function)) {
$function($_batch['source_url'], array('query' => array('op' => 'finish', 'id' => $_batch['id'])));
......
This diff is collapsed.
......@@ -254,7 +254,7 @@ function file_ajax_upload() {
return array('#type' => 'ajax', '#commands' => $commands, '#header' => FALSE);
}
list($form, $form_state, $form_id, $form_build_id) = ajax_get_form();
list($form, $form_state) = ajax_get_form();
if (!$form) {
// Invalid form_build_id.
......@@ -271,12 +271,8 @@ function file_ajax_upload() {
}
$current_file_count = isset($current_element['#file_upload_delta']) ? $current_element['#file_upload_delta'] : 0;
// Build, validate and if possible, submit the form.
drupal_process_form($form_id, $form, $form_state);
// This call recreates the form relying solely on the form_state that the
// drupal_process_form() set up.
$form = drupal_rebuild_form($form_id, $form_state, $form);
// Process user input. $form and $form_state are modified in the process.
drupal_process_form($form['#form_id'], $form, $form_state);
// Retrieve the element to be rendered.
foreach ($form_parents as $parent) {
......
......@@ -1011,6 +1011,10 @@ class FormsRebuildTestCase extends DrupalWebTestCase {
$this->drupalPost(NULL, array(), t('Save'));
$this->assertText('Title field is required.', t('Non-AJAX submission correctly triggered a validation error.'));
// Ensure that the form contains two items in the multi-valued field, so we
// know we're testing a form that was correctly retrieved from cache.
$this->assert(count($this->xpath('//form[contains(@id, "page-node-form")]//div[contains(@class, "form-item-field-ajax-test")]//input[@type="text"]')) == 2, t('Form retained its state from cache.'));
// Ensure that the form's action is correct.
$forms = $this->xpath('//form[contains(@class, "node-page-form")]');
$this->assert(count($forms) == 1 && $forms[0]['action'] == url('node/add/page'), t('Re-rendered form contains the correct action value.'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment