wake-up-neo.com

AJAX Formular validieren und abschicken

Ich habe ein Formular in Drupal 7 erstellt und möchte AJAX verwenden. Ich habe dies zum Submit Button Array hinzugefügt:

"#ajax" => array(
  "callback" => "my_callback",
  "wrapper" => "details-container",
  "effect" => "fade"
)

Dies funktioniert, aber die gesamte Validierungsfunktion wird ignoriert. Wie kann ich das Formular validieren, bevor my_callback() aufgerufen wird? Und wie kann ich die Status- oder Fehlermeldungen in einem AJAX Formular anzeigen?

13
Marius Ilie

Ok, ich finde es heraus. Anscheinend sollten Sie ein Array für Ihre Ajax-Rückruffunktion zurückgeben, nicht nur eine Textnachricht ...

Etwas wie das:

return array("#markup" => "<div id='wrapper'></div>");
7
Marius Ilie

Diese Frage und Antwort hat mir geholfen, die richtige Lösung zu finden, aber es ist nicht ganz klar. Lass es uns so machen.

Dinge, die sehr beachtet werden müssen:

  1. Überprüfungsfehlermeldungen werden in den Code #ajax['wrapper'] eingefügt.
  2. Achten Sie genau darauf, wo in der Drupal Forms API-Dokumentation des Ajax-Wrappers angegeben ist, dass "das gesamte Element mit dieser ID ersetzt wird, nicht nur der Inhalt des Elements".
  3. Da dieses Element ersetzt wird, sollten Sie es erneut bereitstellen. Das ist der Grund, warum Marius Ilies Antwort funktioniert - nicht wegen des Arrays und #markup, sondern weil er das div mit der Wrapper-ID einschließt.

Hier ist der Code, der für mich funktioniert hat, basierend auf dem, was Marius oben in den Kommentar geschrieben hat:

function dr_search_test_form($form, &$fstate) {
  $form["wrapper"] = array("#markup" => "<div id='test-ajax'></div>");

  $form["name"] = array(
    "#type" => "textfield",
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit",
    "#value" => t("Send"),
    "#ajax" => array(
      "callback" => "dr_search_test_form_callback",
      "wrapper" => "test-ajax",
      "effect" => "fade",
    ),
  );
  return $form;
}

function dr_search_test_form_callback($form, &$fstate) {
  return "<div id='test-ajax'>Wrapper Div</div>";
}

function dr_search_test_form_validate($form, &$fstate) {
  form_set_error("name", "Some error to display.");
}
17

Ich habe eine hervorragende Lösung für dieses Problem gefunden.

Gutschrift geht zum Blog dieses Kerls:

http://saw.tl/validate-form-ajax-submit-callback

Die Lösung, die er vorschlägt, ist die folgende:

// when creating or altering the form..
{
  $form['#prefix'] = '<div id="formwrapper">';
  $form['#suffix'] = '</div>';
  // the submit button
  $form['save']['#ajax'] = array(
    'callback' => 'mymodule_form_ajax_submit',
    'wrapper' => 'formwrapper',
    'method' => 'replace',
    'effect' => 'fade',
  );
 // ...
}

function mymodule_from_ajax_submit($form, &$form_state) {
  // validate the form
  drupal_validate_form('mymodule_form_id', $form, $form_state);
  // if there are errors, return the form to display the error messages
  if (form_get_errors()) {
    $form_state['rebuild'] = TRUE;
    return $form;
  }
  // process the form
  mymodule_form_id_submit($form, $form_state);
  $output = array(
    '#markup' => 'Form submitted.'
  );
  // return the confirmation message
  return $output;
}
10
bmunslow

Nichts davon funktioniert für mich. Die Ajax-Funktion des Formulars "submit" ruft die Rückruffunktion weiterhin direkt auf und umgeht dabei die Validierung und das Senden. Außerdem kann die Schaltfläche nicht mehrmals angeklickt werden. Die Überprüfungsmeldungen werden NICHT angezeigt. Ich habe buchstäblich Joshua Stewardson-Code kopiert und eingefügt und es hat nicht funktioniert.

Die Tatsache, dass dieser Anwendungsfall so schwierig und undokumentiert ist, ist sehr beunruhigend. Für mich scheint dies die grundlegendste Anforderung für eine AJAX Formular-API zu sein. Okay, fertig, meine Frustration auf die Lösung loszulassen.

Hier ist, was ich getan habe, um dies zum Laufen zu bringen. Es fühlt sich abgehackt und zurückgeblieben an. Es wird auch kaputt gehen, wenn es mehrere Instanzen des Formulars auf einer Seite gibt, aber es war das Beste, was ich tun konnte. Wenn jemand Licht ins Dunkel bringen kann, bitte!

Grundsätzlich müssen Sie das gesamte Formular innerhalb Ihres Rückrufs durch sich selbst ersetzen und alle festgelegten Nachrichten dem Formularobjekt manuell voranstellen. Deklarieren Sie dazu den Wrapper als die ID Ihres Formulars (dies funktioniert nicht, wenn auf einer Seite mehrere Instanzen Ihres Formulars vorhanden sind, da die ID aktualisiert wird).

function productsearchbar_savesearch_form($form, &$form_state) {

  $form["wrapper"] = array("#markup" => "<div class='inline-messages'></div>");

  $form["name"] = array(
    "#type" => "textfield", 
    "#required" => true,
    "#title" => "Name"
  );

  $form["submit"] = array(
    "#type" => "submit", 
    "#value" => "Send", 
    "#ajax" => array(
      "callback" => "productsearchbar_savesearch_form_callback", 
      "wrapper" => "productsearchbar-savesearch-form", 
      "effect" => "fade"
    )
  );

  return $form;
}

function productsearchbar_savesearch_form_callback($form, &$form_state) {
  $messages = theme('status_messages');

  if($messages){
    $form["wrapper"] = array("#markup" => "<div class='inline-messages'>$messages</div>");
  }
  return $form;
}

function productsearchbar_savesearch_form_validate($form, &$form_state) {
  if ($form_state['values']['name'] == '') {
   form_set_error('', t('Name field is empty!'));
  }
}

function productsearchbar_savesearch_form_submit($form, &$form_state) {
  drupal_set_message(t('Your form has been saved.'));
}
9
Brent Hartmann

Ich suchte viele Stunden nach einer Möglichkeit, dies richtig zu tun. Leider verlassen sich die meisten dieser Lösungen immer noch auf die serverseitige Überprüfung von Drupal, um zu bestimmen, ob die Ajax-Ergebnisse oder die clientseitigen Fehlermeldungen im Wrapper abgelegt werden sollen. Das Verlassen auf das Serverergebnis ist langsamer als die clientseitige Validierung, die praktisch sofort erfolgen sollte. Auch das Ersetzen des Formulars ... durch ein Formular ... mit den Fehlermeldungen ist für meine Präferenz etwas zu chaotisch.

Verwenden Sie die Methoden von jquery validation, um ein Ajax-Ereignis mit einem Javascript-Trigger auszulösen:

// Prevent form submission when there are client-side errors, trigger ajax event when it is valid
(function ($) {
    Drupal.behaviors.submitForm = { 
        attach: function (context) {
            var $form = $("form#validated_form", context);
            var $submitButton = $('input[type="submit"]', $form);

            $form
                .once('submitForm')
                .off('submit')
                .on('submit', function(e){

                    // Prevent normal form submission
                    e.preventDefault();
                    var $form = $(this);

                    // The trigger value should match what you have in your $form['submit'] array's ajax array
                    //if the form is valid, trigger the ajax event
                    if($form.valid()) {
                        $submitButton.trigger('submit_form');
                    }
            });

        }
    };
})(jQuery);

Verweisen Sie auf den Javascript-Auslöser als Ihr Ajax-Ereignis, das abgehört wird:

$form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
    '#ajax' => array(
      'event' => 'submit_form',
      'callback' => 'callback_function_for_when_form_is_valid',
      'wrapper' => 'validated_form'
    )
);

Jetzt wird die Validierung ausgelöst, sobald auf die Schaltfläche "Senden" geklickt wird, und die serverseitige Validierung findet erst statt, wenn sie gültig ist!

0
CLL