web-dev-qa-db-fra.com

Reconstruire le formulaire après l'exécution du rappel ajax

J'ai un formulaire avec un bouton qui, une fois pressé, reconstruit une partie différente du formulaire via une demande ajax.

En cliquant sur le bouton, le formulaire est reconstruit, puis mon rappel ajax est appelé, ce qui enregistre les valeurs du formulaire, puis renvoie une partie du formulaire.

Le problème est que le formulaire est reconstruit AVANT mon rappel qui enregistre les valeurs et modifie donc la façon dont le formulaire est créé.

Si je clique sur le bouton ajax une deuxième fois, cela fonctionne correctement, tout comme les valeurs de la demande ajax précédente lors de la création du formulaire.

Comment puis-je exécuter ma fonction de rappel avant que le formulaire ne soit reconstruit?

function emtr_shift_plan_form($form, &$form_state) {

    ddl('build'); // log that this function is being called

    $form['save'] = array(
        '#type' => 'button',
        '#submit' => array('emtr_shift_plan_form_ajax_submit'),
        '#value' => 'Save',
        '#ajax' => array(
            'callback' => 'emtr_shift_plan_form_ajax_submit',
            'wrapper' => 'postions',
        ),
        '#id' => 'ajax-save-form-values',
    );

    $form['postions'] = array(
        '#type' => ' container',
        '#prefix' => '<div id="postions">',
        '#suffix' => '</div>',
    );

    // code here to populate the positions container

}

function emtr_shift_plan_form_ajax_submit($form, &$form_state) {

    ddl('ajax submit'); // log the ajax callback is being called

    $form_state['rebuild'] = TRUE; // As the form has already been rebuilt at this point what effect can this have?!?

    emtr_shift_plan_form_save($form, $form_state); // save the values

    // This is the point at which I want the form to be rebuilt

    return $form['positions'];

}

ÉDITER:

Comme solution de contournement, j'ai trouvé qu'il était possible de reconstruire manuellement le formulaire une deuxième fois dans le rappel ajax avec $form = drupal_rebuild_form('emtr_shift_plan_form', $form_state);, mais il semble inefficace de construire le formulaire deux fois. Puis-je simplement échanger l'ordre de ces événements plutôt que de créer le formulaire deux fois par demande ajax?

7
Felix Eve

Je sais que cette question a 3 ans, mais je suis tombée dessus en cherchant un problème similaire.

Vous devrez modifier votre approche pour que cela fonctionne. L'ordre des opérations lorsque vous soumettez la demande AJAX est la suivante:

  1. AJAX soumettre un rappel est renvoyé. Dans votre AJAX soumettre un rappel, vous voudrez enregistrer les données. Signalez-le dans votre $form_state variable.
  2. Le formulaire est reconstruit.
  3. Le rappel AJAX est déclenché.

J'ai retravaillé un peu votre code pour le démontrer.

// AJAX FLOW: 2. Form rebuild is fired.
function emtr_shift_plan_form($form, &$form_state) {

    ddl('build'); // log that this function is being called

    $form['save'] = array(
        '#type' => 'button',
        '#submit' => array('emtr_shift_plan_form_button_submit'),
        '#value' => 'Save',
        '#ajax' => array(
            'callback' => 'emtr_shift_plan_form_ajax',
            'wrapper' => 'postions',
        ),
        '#id' => 'ajax-save-form-values',
    );

    $form['postions'] = array(
        '#type' => ' container',
        '#prefix' => '<div id="postions">',
        '#suffix' => '</div>',
    );

    // code here to populate the positions container
    if (isset($form_state['saved_values'])) {
      // do stuff.
    }
}

// AJAX FLOW: 1. Button submit is fired.
function emtr_shift_plan_form_button_submit($form, &$form_state) {

  // log the ajax callback is being called
  ddl('ajax submit');

  // save the values. Make sure the data is stored somehow so your form can get at it.
  $form_state['saved_values'] = emtr_shift_plan_form_save($form, $form_state);

  // rebuild flag here will trigger emtr_shift_plan_form() to be run
  $form_state['rebuild'] = TRUE;
}

// AJAX FLOW: 3. Button callback is fired.
function emtr_shift_plan_form_ajax($form, &$form_state) {
    return $form['positions'];
}

J'espère que cela éclaire quelqu'un.

2
Scott Joudry

Vous pouvez essayer comme ceci en soumettant différent et rappel différent et voir si cela aide.

$form['save'] = array(
    '#type' => 'button',
    '#submit' => array('emtr_shift_plan_form_ajax_submit'),
    '#value' => 'Save',
    '#ajax' => array(
        'callback' => 'emtr_shift_plan_form_ajax',
        'wrapper' => 'postions',
    ),
    '#id' => 'ajax-save-form-values',
);

function emtr_shift_plan_form_ajax($form, &$form_state){
  return $form['positions'];
}
function emtr_shift_plan_form_ajax_submit($form, &$form_state) {

    ddl('ajax submit'); // log the ajax callback is being called

    $form_state['rebuild'] = TRUE; // As the form has already been rebuilt at this point what effect can this have?!?

    emtr_shift_plan_form_save($form, $form_state); // save the values

    // This is the point at which I want the form to be rebuilt
}
2
Ali Nouman