Komplexe Formulare, rekursives Ajax und promise() Interface

21. Oktober 2011 - HTML, JavaScript

Nehmen wir mal an, dass ihr auf auf eurer Webseite ein komplexes Formular habt (Beispiel: order.php), in dem viel geprüft (Spam, Adressen…) werden muss, was die Wahrscheinlichkeit erhöht, dass das Formular mehrfach zwischen Client und Server hin- und hergeschickt wird. Nun möchtet ihr dieses Formular  ohne Änderungen an mehreren Stellen eurer Webseite aufrufen können, ohne dass der Benutzer die aktuelle Seite verlassen muss.

Hier ist eine Lösung dafür.

English Summary: If you want to call a complex form page (order sheet, inquiry form,…) from several locations inside your website without the need to follow a link to that form page, here is a solution using recursive Ajax, UI-Dialog und the jQuery promise interface.

Dieses kurze Javascript sorgt dafür, dass euer Formular richtig ausgefüllt wird. Bei Fragen: bitte Kommentar schicken.

jQuery(document).ready(
function()
{

jQuery(".****class der Elemente, die das Formular aufrufen können****").click(
function()
{
var sendpost=jQuery.Deferred();
function send_post_req ()
sendpost=jQuery.post(order.php);
}
function show_post (response) {
clean_up();
jQuery("***id des Elements auf der Seite, nach dem eingefügt werden soll***").append('<div id="**ID des Formulars****" style="display: none;">'+response+'</div>');
}
function clean_up () {
jQuery("**ID des Formulars****").remove();
}

function add_submit () {
jQuery("form #**** ID eures Submit-Buttons****").click ( function (e) {
e.preventDefault;
var ser2=jQuery('form').serialize();
sendpost=jQuery.post(order.php, ser2);
proc_post();
});
}
function add_dialog ()
jQuery("**ID des Formulars****").dialog({
width: 600,
resizable: true,
title: 'Einfache Bestellung',
position: 'center',
close: function(event, ui) { clean_up();
}
});

}
send_post_req();
proc_post();
function proc_post() {
jQuery.when (sendpost)
.done (function (response) {
show_post (response);
add_dialog();
add_submit();
});
}
});
});

Zunächst werden einige Funktionen definiert:
send_post_req:  Post-Request; damit holen wir den Inhalt eurer Formular-Seite zum ersten Mal
show_post:  damit wird der Inhalt  im DOM der aktuellen Seite unsichtbar angelegt
clean_up:  damit wird dieser Inhalt bei Bedarf wieder entfernt
add_submit:  übernimmt den Submit-Button und schickt das Formular an den Server zurück
add_dialog:  stellt den Inhalt des Formulars in einem UI-Dialog auf der Seite dar.
proc_post:  bindet alle Funktionen zusammen und nutzt das promise Interface von jQuery.

Gestartet wird in das Ganze in der Zeile 39.

Die Zeile 25 sorgt für das rekursive Abarbeiten, wenn das Formular mehrmals zwischen Server und Client hin- und hergeschickt werden muss.

Damit proc_post nicht schon verfrüht losfeuert, wird in Zeile 8 ein Deferred Objekt (sendpost) erzeugt, auf das proc_post warten muss.  Dieses Objekt wird in send_post_req überschrieben, so dass proc_post jetzt auf den Ausgang der Ajax-Anfrage wartet.

Die zweite Ajax-Anfrage in add_submit schickt beim Anklicken den mit einem zweiten Parameter serialisierten Inhalt eures (hoffentlich vom Benutzer ausgefüllten) Formulars  an den Server.  Dabei wird das „resolved“ Deferred sendpost überschrieben und wieder aktiviert.

Für die wenigen, die es noch nicht wissen:  jQuery und Javascript kann man prima und ohne Formalitäten bei jsFiddle austesten.

Wenn ihr mit einem Content-Management System arbeitet, werdet Ihr in der Regel keine Seite „order.php“ haben, weil dort die Seite erst auf Anforderung vom CMS zusammen gebaut wird .

Im Falle CMS=wordpress kann man so vorgehen:

Der Post-Request muss etwas modifiziert werden (Doku hier)


var nf_data = {
action: 'order',
_ajax_nonce: MyAjax.akt_nonce
};
sendpost=jQuery.post(MyAjax.ajaxurl, jQuery.param(nf_data));

MyAjax.ajaxurl ist die Seite, die den Request erhalten soll: admin-ajax.php. Wo sie im Verzeichnisbaum liegt, muss dem Script über


wp_localize_script('simple', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php'),
'akt_nonce' => $this->nonce) );

mitgeteilt werden. Zusätzlich  wird noch ein Nonce  zum Überprüfen des Requests  mitgegeben.

action: ‚order‘ ist eure callback-Funktion (hier:“order“), die von admin-ajax.php aufgerufen wird und das Formular erzeugt.

Der zweite Post-Request sieht so aus:


var ser2=jQuery('form').serialize();
var ser=jQuery.param(nf_data);

sendpost=jQuery.post(MyAjax.ajaxurl, ser+'&'+ser2 );

Zum besseren Verständnis könnt Ihr den Original Code hier downloaden:  Template einfacher_bestellen

Denkt bitte daran: das Plugin muss für eure Zwecke noch modifiziert werden. Der Code für das Formular ist z.B. in einer Klasse enthalten, die in der Webseite an anderer Stelle definiert und hier nicht beigefügt wird.
Einige Teile des jQuery Codes sind formularspezifisch (z.B. wird das Formular über „form.yform“ gefunden).