web-dev-qa-db-fra.com

Pourquoi mes AJAX sont-ils soumis deux fois?

Je cherchais des heures de haut en haut pendant des heures pour essayer de comprendre ce que je fais mal.

Chaque fois que je soumets un formulaire via Ajax, la fonction Soumettre est invoquée deux fois. En d'autres termes, la forme est soumise deux fois. Voici un exemple que j'ai travaillé dans ma tentative pour faire bouillir tout sur les bases dans l'espoir de trouver la racine de cette question très gênante (l'exemple suppose AJAX Demandes, et n'est pas vraiment axé sur la dégradation gracieuse).

Ce n'est pas un problème avec plusieurs AJAX demandes envoyées à partir du navigateur. Le navigateur n'envoie qu'une seule demande lorsque je clique sur le bouton "Soumettre" du formulaire.

/**
 * Page callback for 'welcome'. This path has been registered
 * as a plain MENU_CALLBACK.
 */
function us_welcome() {

  // This is where the user arrives at first when navigating to
  // 'welcome'. The user is simply presented with a link which 
  // will load the registration for via AJAX and show that form
  // on the very same page.

  $html[] = l(t('Register'), 'welcome/register/nojs', array(
    'attributes' => array(
      'class' => array(
        'use-ajax'
      ),
    ),
  ));

  $html[] = '<div id="form-register-wrapper"></div>';

  return implode($html);

}

/**
 * Page callback for 'welcome/register'. This path has been registered
 * as a plain MENU_CALLBACK.
 */
function us_register($mode = 'nojs') {

  // This callback is responsible for the path 'welcome/register'
  // and is the one which the link invokes. If invokation happens
  // from the link, then $mode is 'ajax'. Otherwise, it is 'nojs'.

  // Get form.
  $form = drupal_get_form('us_register_form');

  if ($mode != 'ajax') {
    return $form;
  }

  // Generate commands array.
  $commands = array(
    ajax_command_replace('#form-register-wrapper', drupal_render($form)),
  );

  $page = array('#type' => 'ajax', '#commands' => $commands);
  ajax_deliver($page);

}

function us_register_form($form, &$form_state) {

  // A plain old form builder function. Nothing magical
  // going on here.

  $form['#prefix'] = '<div id="form-register-wrapper">';
  $form['#suffix'] = '</div>';
  $form['#action'] = '/welcome/register/nojs';

  $form['messages'] = array(
    '#markup' => '<div id="form-messages"></div>',
  );

  $form['basic'] = array(
    '#type' => 'fieldset',
    '#title' => t('Basic Details'),
  );

  $form['basic']['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Your Name'),
  );

  $form['basic']['email'] = array(
    '#type' => 'textfield',
    '#title' => t('Your E-mail'),
    '#required' => TRUE,
  );

  $form['basic']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    '#ajax' => array(
      'callback' => 'us_register_form_submit',
      'wrapper' => 'form-register-wrapper',
      'effect' => 'fade',
    )
  );

  return $form;

}

function us_register_form_submit($form, &$form_state) {

  // This is the form submit function. The weird thing is that it gets
  // called twice every time the form is submitted via AJAX. 

  // This block of code will only apply to AJAX requests. Normal requests will
  // return from the validation function(s) if validation error(s) should occur,
  // and by the time normal requests get to this point everything have been
  // validated. AJAX requests, on the other hand, goes through the validation
  // function(s) but will still reach this point even though validation error(s)
  // occur. Thus, we need to check for errors and return error messages in case
  // of validation errors. In case of errors, return the form again.
  $errors = form_get_errors();
  if (!empty($errors)) {
    return $form;
  }

  // @todo : carry out registration here.

  $content = array();
  $content[] = t('Thank you for registering!');

  // Process form submission.
  $commands = array(
    ajax_command_replace('#form-register-wrapper', implode($content)),
  );
  $page = array('#type' => 'ajax', '#commands' => $commands);
  return $page;
}
3
sbrattla

Basé sur -- Ceci Post, je crois avoir trouvé pourquoi mes formulaires sont soumis deux fois. Il semble que la fonction #ajax ['rappel'] est à la fois une fonction de validation et une fonction de réponse. La fonction de soumission standard du formulaire sera toujours invoquée, mais pendant AJAX Demandes, quelles que soient les rendements de la fonction de soumission seront ignorés car les valeurs de retour de la fonction de rappel seront utilisées à la place.

La fonction Soumettre ne sera pas appelée dans la validation de formulaire échoue et la fonction de rappel sera invoquée directement après des fonctions de validation afin que l'utilisateur puisse être averti sur la validation défaillante.

1
sbrattla