== Formulare ==
Formulare sind eine Möglichkeiten um Eingaben des Benutzers zu erhalten. Ein Formular muss mindestens die Attribute "action" und "method" haben.
Das "method"-Attribut gibt die HTTP Request Methode an, über die die Daten transferiert werden. Das kann entweder POST oder GET sein.
GET Daten werden über die URL übertragen - sie sind also für jeden Betrachter und auch in den Logfiles sichtbar. Für Formulareingaben sollte dies niemals verwendet werden.
Die Eingabe wird nicht direkt an das Formular - sondern mit einem HTTP Request an eine zweite URL - geschickt. Diese gibt man über das "action"-Attribut an.
Man kann die Eingabe auch an das Formular selbst schicken - das ist eine gute Praxis, wenn man nicht seinen Code nicht über zu viele Dateien verstreuen will.
== Formularfelder ==
Formulare haben verschiedene Feldtypen wie einzeilige und mehrzeilige Texteingaben, Auswahlboxen und -Listen mit einfach und mehrfach Auswahl und Feldtypen für Dateiuploads.
Die einfachste Platzierung ist schlicht, sehr gängig und enthält eigentlich alle notwendigen Informationen:
easy-coding.de/Attachment/500/…2eed3b0ae3686173825076c78
== Bessere Formularfelder ==
Schönere Formularfelder mit besserer Semantik erhält man, indem die Beschreibung mittels eines Labels dem Eingabefeld zugeordnet wird. Dazu muss dem Eingabefeld eine eindeutige ID vergeben werden:
Dies hat den praktischen Nebeneffekt, dass man nur den Text klicken braucht um die Auswahlbox zu de-/selektieren.
Eingabefelder lassen sich meist gruppieren. Um so mehr Eingabefelder es gibt, desto eher sollte sich der Entwickler darüber Gedanken machen.
Der Benutzer kann so eine bessere Übersicht gewinnen. Vor allem da HTML hier praktische Elemente liefert, die der Benutzer durch die Verbreitung auf vielen Websites schnell unterbewusst wahrnimmt. Es handelt sich dabei um s.g. "Fieldsets". Um diese "Fieldsets" zu beschriften fügt man eine Legende hinzu.
easy-coding.de/Attachment/501/…2eed3b0ae3686173825076c78
== Verarbeitung in PHP ==
Selbstverständlich gehören alle Elemente die gleichzeitig übertragen werden müssen innerhalb eines einzige Formulars. Sie stehen im Zieldokument unter der Superglobalen $_POST zur Verfügung. Als Index wird der Formularname verwendet. Ein Besonderfall bilden mehrdeutige Elemente. So kann zum Beispiel der Typ Checkbox mehrere Werte annehmen.
Dazu muss man die Array-Schreibweise mit öffnender und schließender eckigen Klammer verwenden und erhält in PHP ein Array, über das man am besten mit einer foreach-Schleife iterierten kann.
Dass $_POST ein normales Array ist erkennt man auch daran, dass sich die print_r Funktion darauf anwenden lässt.
== POST Daten per AJAX übertragen ==
Um Formulardaten über POST mittels AJAX zu übertragen muss ein GET String zusammengebaut werden, so wie man ihn hätte auch direkt im Browser aufrufen können.
Ein vollständiger POST Request sieht Ende wie folgt aus:
== Formulardaten mit JavaScript sammeln ==
Die selbstgeschriebene Funktion getFormData ist sehr trickreich. Man sagt dass sie das "Formular serialisiert". Der GET String wird zusammengebaut (Alternativ kann sie auch ein Array liefern). Sie iteriert über "form.elements" - also alle Elemente des Formulars. Auswahllisten haben den Sonderfall, dass alle Kindelemente (also die options) abgefragt werden müssen.
An dieser Stelle setze ich die Funktion einfach als gegeben voraus:
Alles anzeigen
Die bewährteste Möglichkeit um an Formulardaten zu gelangen, ist es sich in den onsubmit Event des Formular-Objektes einzuhängen.
Der onsubmit Event wird noch ausgeführt bevor das "action"-Attribut ausgelesen wird. Wird das Event mit false terminiert, dann fährt der Browser nicht fort und ignoriert es gar. Das ist die perfekte Voraussetzung für einen AJAX Request.
Als Nebeneffekt wird das onsubmit bei deaktiviertem JavaScript nicht gelesen und man landet direkt bei der Zielseite.
Bei unserem Beispielformular mit nur einem Element sieht der Alert wie folgt aus:
easy-coding.de/Attachment/502/…2eed3b0ae3686173825076c78
== Formular per AJAX übertragen ==
Das Übertragen des gesamten Formulars per AJAX ist ein Zusammensetzen der bekannten Funktionen.
Der AJAX POST Request wurde in die Funktion ajaxPost übernommen. Diese sieht wie folgt aus:
Alles anzeigen
== Best Practice Parallelbetrieb ==
Zum Abschluss möchte ich eine Variante erläutern, wie man einfache Formulare parallel "mit" und "ohne" AJAX betreiben kann.
Ich habe mich dafür entschieden, dass das Formular die Daten an sich selbst schickt. Außerdem will ich unterscheiden ob die Daten per AJAX oder nicht per AJAX gesendet wurden. Daher füge ich allein im onsubmit Event die POST Variable "ajax" hinzu.
Der Formularkopf sieht nach der Bearbeitung wie folgt aus:
Zusätzlich kümmert man sich im Kopf der Datei um die Bearbeitung des Requests. Falls es sich um einen AJAX Request handelt wird die Meldung direkt ausgegeben und ein exit ausgeführt. Das verhindert, dass der Rest der Seite neu geladen werden muss.
Ansonsten
Alles anzeigen
== Demo ==
Eine Live Demo mit allen möglichen Formularelementen findet ihr unter demo.easy-coding.de/ajax/forms-with-and-without-ajax. Des weiteren wird der kompletten Code hier als ZIP Archiv zur Verfügung gestellt: download.zip.
easy-coding.de/Attachment/503/…2eed3b0ae3686173825076c78
Formulare sind eine Möglichkeiten um Eingaben des Benutzers zu erhalten. Ein Formular muss mindestens die Attribute "action" und "method" haben.
Das "method"-Attribut gibt die HTTP Request Methode an, über die die Daten transferiert werden. Das kann entweder POST oder GET sein.
GET Daten werden über die URL übertragen - sie sind also für jeden Betrachter und auch in den Logfiles sichtbar. Für Formulareingaben sollte dies niemals verwendet werden.
Die Eingabe wird nicht direkt an das Formular - sondern mit einem HTTP Request an eine zweite URL - geschickt. Diese gibt man über das "action"-Attribut an.
Man kann die Eingabe auch an das Formular selbst schicken - das ist eine gute Praxis, wenn man nicht seinen Code nicht über zu viele Dateien verstreuen will.
== Formularfelder ==
Formulare haben verschiedene Feldtypen wie einzeilige und mehrzeilige Texteingaben, Auswahlboxen und -Listen mit einfach und mehrfach Auswahl und Feldtypen für Dateiuploads.
Die einfachste Platzierung ist schlicht, sehr gängig und enthält eigentlich alle notwendigen Informationen:
easy-coding.de/Attachment/500/…2eed3b0ae3686173825076c78
== Bessere Formularfelder ==
Schönere Formularfelder mit besserer Semantik erhält man, indem die Beschreibung mittels eines Labels dem Eingabefeld zugeordnet wird. Dazu muss dem Eingabefeld eine eindeutige ID vergeben werden:
Dies hat den praktischen Nebeneffekt, dass man nur den Text klicken braucht um die Auswahlbox zu de-/selektieren.
Eingabefelder lassen sich meist gruppieren. Um so mehr Eingabefelder es gibt, desto eher sollte sich der Entwickler darüber Gedanken machen.
Der Benutzer kann so eine bessere Übersicht gewinnen. Vor allem da HTML hier praktische Elemente liefert, die der Benutzer durch die Verbreitung auf vielen Websites schnell unterbewusst wahrnimmt. Es handelt sich dabei um s.g. "Fieldsets". Um diese "Fieldsets" zu beschriften fügt man eine Legende hinzu.
easy-coding.de/Attachment/501/…2eed3b0ae3686173825076c78
== Verarbeitung in PHP ==
Selbstverständlich gehören alle Elemente die gleichzeitig übertragen werden müssen innerhalb eines einzige Formulars. Sie stehen im Zieldokument unter der Superglobalen $_POST zur Verfügung. Als Index wird der Formularname verwendet. Ein Besonderfall bilden mehrdeutige Elemente. So kann zum Beispiel der Typ Checkbox mehrere Werte annehmen.
Dazu muss man die Array-Schreibweise mit öffnender und schließender eckigen Klammer verwenden und erhält in PHP ein Array, über das man am besten mit einer foreach-Schleife iterierten kann.
Dass $_POST ein normales Array ist erkennt man auch daran, dass sich die print_r Funktion darauf anwenden lässt.
== POST Daten per AJAX übertragen ==
Um Formulardaten über POST mittels AJAX zu übertragen muss ein GET String zusammengebaut werden, so wie man ihn hätte auch direkt im Browser aufrufen können.
Ein vollständiger POST Request sieht Ende wie folgt aus:
== Formulardaten mit JavaScript sammeln ==
Die selbstgeschriebene Funktion getFormData ist sehr trickreich. Man sagt dass sie das "Formular serialisiert". Der GET String wird zusammengebaut (Alternativ kann sie auch ein Array liefern). Sie iteriert über "form.elements" - also alle Elemente des Formulars. Auswahllisten haben den Sonderfall, dass alle Kindelemente (also die options) abgefragt werden müssen.
An dieser Stelle setze ich die Funktion einfach als gegeben voraus:
Quellcode
- function getFormData(form, asArray) {
- var ret;
- var add = function(n, v) {
- if(asArray) {
- if(ret == null) ret = new Array();
- ret[n] = escape(v);
- } else {
- ret = (ret == null ? '' : ret+'&') + n +'='+ escape(v);
- }
- };
- for(var i=0; i<form.elements.length; i++) {
- var el = form.elements[i];
- var type = (el.type || '');
- if(type.match(/^(text|hidden|textarea)$/i) || (type.match(/^(radio|checkbox)$/i) && el.checked)) {
- add(el.name, el.value);
- } else if(el.nodeName.match(/^select$/i)) {
- for(var j=0; j<el.options.length; j++) {
- if(el.options[j].selected) {
- add(el.name, el.options[j].value);
- }
- }
- } else if(el.nodeName.match(/^textarea$/i)) {
- add(el.name, el.value);
- }
- }
- return ret != null ? ret : (asArray ? new Array() : '');
- }
Die bewährteste Möglichkeit um an Formulardaten zu gelangen, ist es sich in den onsubmit Event des Formular-Objektes einzuhängen.
Der onsubmit Event wird noch ausgeführt bevor das "action"-Attribut ausgelesen wird. Wird das Event mit false terminiert, dann fährt der Browser nicht fort und ignoriert es gar. Das ist die perfekte Voraussetzung für einen AJAX Request.
Als Nebeneffekt wird das onsubmit bei deaktiviertem JavaScript nicht gelesen und man landet direkt bei der Zielseite.
Bei unserem Beispielformular mit nur einem Element sieht der Alert wie folgt aus:
easy-coding.de/Attachment/502/…2eed3b0ae3686173825076c78
== Formular per AJAX übertragen ==
Das Übertragen des gesamten Formulars per AJAX ist ein Zusammensetzen der bekannten Funktionen.
Der AJAX POST Request wurde in die Funktion ajaxPost übernommen. Diese sieht wie folgt aus:
Quellcode
- function ajaxPost(url, postData, callback) {
- var req;
- try {
- req = window.XMLHttpRequest ? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");
- } catch (e) {
- // browser does not have ajax support
- }
- req.onreadystatechange = typeof callback == 'function' ? callback : function() {
- if (req.readyState == 4 && req.status == 200) {
- if(typeof callback == 'string') callback = document.getElementById(callback);
- if(callback) callback.innerHTML = req.responseText;
- }
- };
- req.open('POST', url, true);
- req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- req.send(postData);
- return false;
- }
== Best Practice Parallelbetrieb ==
Zum Abschluss möchte ich eine Variante erläutern, wie man einfache Formulare parallel "mit" und "ohne" AJAX betreiben kann.
Ich habe mich dafür entschieden, dass das Formular die Daten an sich selbst schickt. Außerdem will ich unterscheiden ob die Daten per AJAX oder nicht per AJAX gesendet wurden. Daher füge ich allein im onsubmit Event die POST Variable "ajax" hinzu.
Der Formularkopf sieht nach der Bearbeitung wie folgt aus:
Zusätzlich kümmert man sich im Kopf der Datei um die Bearbeitung des Requests. Falls es sich um einen AJAX Request handelt wird die Meldung direkt ausgegeben und ein exit ausgeführt. Das verhindert, dass der Rest der Seite neu geladen werden muss.
Ansonsten
Quellcode
- <?php
- $response = '';
- if(count($_POST)) {
- $response = sprintf('<b style="color:green">%s</b>', 'form data ok');
- try {
- // validation
- if(!isset($_POST['radio1'])) throw new Exception('you have to add at least one option');
- } catch(Exception $e) {
- $response = sprintf('<b style="color:red">%s</b>', $e->getMessage());
- }
- if(isset($_POST['ajax'])) {
- echo $response;
- exit;
- }
- }
- ?>
== Demo ==
Eine Live Demo mit allen möglichen Formularelementen findet ihr unter demo.easy-coding.de/ajax/forms-with-and-without-ajax. Des weiteren wird der kompletten Code hier als ZIP Archiv zur Verfügung gestellt: download.zip.
easy-coding.de/Attachment/503/…2eed3b0ae3686173825076c78
19.914 mal gelesen
Lemmi -
Neben den vielen Tipps, die man über Googel findet, hab ich da noch einen, der vielleicht vor allem bei der Formular-Auswertung in PHP sehr wichtig sein kann.
[font='Courier New, Courier, mono']strtolower[/font] - eine Zeichenkette in Kleinbuchstaben umwandeln - funktioniert nicht mit dem häufig verwendete Zeichensatz UTF-8. Dafür dieses nette Workaround aus den Kommentaren der offiziellen PHP-Webseite:
[syntax="php"]function strtolower_utf8($inputString) {
$outputString = utf8_decode($inputString);
$outputString = strtolower($outputString);
$outputString = utf8_encode($outputString);
return $outputString;
}[/syntax]
Auch bei anderen Funktionen, die Zeichensätze in verschiedene Zustände bringen können, solltet ihr dieses Problem überprüfen. Ich hatte eigentlich alles korrekt vorbereitet und war entsprechend erleichtert, als ich das Problem herausfiltern konnte.
Vielleicht gibt es ja noch andere hilfreiche Erfahrungstipps aus der Arbeit mit AJAX und das Problem des Zeichensatzes, die ihr hier gerne anführen dürft.