Formular neu erstellen, nachdem der Ajax-Rückruf ausgeführt wurde

7

Ich habe ein Formular mit einer Schaltfläche, die beim Drücken einen anderen Teil des Formulars über eine Ajax-Anfrage neu erstellt.

Wenn Sie auf die Schaltfläche klicken, wird das Formular neu erstellt. Anschließend wird mein Ajax-Rückruf aufgerufen, der die Werte aus dem Formular speichert und dann einen Teil des Formulars zurückgibt.

Das Problem ist, dass das Formular VOR meinem Rückruf neu erstellt wird, wodurch die Werte gespeichert werden und daher die Erstellung des Formulars geändert wird.

Wenn ich ein zweites Mal auf die Schaltfläche Ajax klicke, funktioniert dies ordnungsgemäß, ebenso wie die Werte aus der vorherigen Ajax-Anforderung beim Erstellen des Formulars.

Wie kann ich meine Rückruffunktion ausführen, bevor das Formular neu erstellt wird?

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'];

}

BEARBEITEN:

Als Problemumgehung habe ich festgestellt, dass es möglich ist, das Formular ein zweites Mal im Ajax-Rückruf mit manuell neu zu erstellen $form = drupal_rebuild_form('emtr_shift_plan_form', $form_state);, aber es scheint ineffizient zu sein, das Formular zweimal zu erstellen. Kann ich die Reihenfolge dieser Ereignisse einfach vertauschen, anstatt das Formular zweimal pro Ajax-Anforderung erstellen zu lassen?

Felix Eve
quelle
2
Sie sollten das 'Speichern' in einer Übermittlungsfunktion durchführen. Ajax-Rückrufe sollten im Allgemeinen nur das Formularelement zurückgeben. Möglicherweise wird dadurch auch Ihr Problem behoben.
2pha

Antworten:

2

Ich weiß, dass diese Frage 3 Jahre alt ist, aber ich bin auf sie gestoßen, als ich nach einem ähnlichen Problem gesucht habe.

Sie müssen Ihren Ansatz ändern, damit dies funktioniert. Die Reihenfolge der Vorgänge beim Senden der AJAX-Anforderung lautet wie folgt:

  1. AJAX Submit Callback wird ausgelöst. In Ihrem AJAX-Rückruf möchten Sie die Daten speichern. Markieren Sie es in Ihrer $form_stateVariablen.
  2. Form wird wieder aufgebaut.
  3. AJAX-Rückruf wird ausgelöst.

Ich habe Ihren Code ein wenig überarbeitet, um dies zu demonstrieren.

// 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'];
}

Hoffe, das bringt etwas Licht für jemanden.

Scott Joudry
quelle
2

Sie könnten versuchen, so etwas anders zu machen und Rückruf anders zu machen und zu sehen, ob es hilft.

$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
}
Ali Nouman
quelle
Vielen Dank für Ihren Vorschlag, aber es scheint keinen Unterschied zu machen. Diese Schaltfläche sollte eigentlich keinen Submit-Handler benötigen, wenn ein Ajax-Rückruf definiert ist.
Felix Eve
Dies ist in der Tat die richtige Antwort zusammen mit dem 2pha-Kommentar: Ajax-Rückruffunktionen geben nur die Ausgabe zurück. Alle anderen Aktionen sollten in einer Übermittlungsfunktion (wenn das Element eine Schaltfläche oder eine Entsprechung ist) oder in den Funktionen ausgeführt werden, die das Formular zurückgeben (oder in Änderungsfunktionen). Die Frage ist also nicht, wie nach einem Rückruf neu erstellt werden soll, sondern wie Berechnungen vor der Ajax-Rückruffunktion durchgeführt werden sollen. Die falsche Annahme ist, dass die Ajax-Rückruffunktion eine Übermittlungsfunktion ist: Sie ist nur eine Funktion, die die Ausgabe zurückgibt: ein Formularfragment oder AJAX-Befehle.
Sanzante