Nachträglich hinzugefügtes Element im DOM ansprechen

Ich muss zugeben, ich hatte öfter das Problem, Elemente auf einer Webseite mit jQuery anzusprechen, die nachträglich via Ajax oder .append() dem DOM hinzugefügt wurden. Höchstwahrscheinlich bin ich auch der Letzte, der die ideale Lösung wohl nicht kannte, obwohl es bereits seit 2011 möglich und bekannt ist.

Normale DOM Elemente mit Click-Handler behandeln:

Das geht solange gut, wie alle Elemente schon im DOM vorhanden sind, kommt aber etwas nachträglich hinzu, zum Beispiel nachgeladen durch Ajax, dann kennt der Click-Handler den Selektor noch nicht und dann kann man auf das Element klicken wie man möchte, es wird nichts passieren. Es wird nicht mal eine Fehlermeldung ausgegeben, weil es keinen Fehler gibt.

Jetzt endlich, bin ich über eine gute Lösung für das Problem gestolpert.

Nachträgliche, dem DOM hinzugefügte Elemente, mit Click-Handler behandeln:

In diesem Fall wird das neue Element in jedem Fall gefunden. Das ganze bedeutet natürlich auch, dass in diesem Beispiel der gesamte DOM einer Seite durchlaufen wird, bis der gewünschte Selektor gefunden wird, wegen $(document).on().

Aus Performancegründen wäre vielleicht die Wahl eines vorhanden, näher an dem neuen Element liegender Container, die bessere Wahl, solange dieser bereits vorhanden ist. Das sollte aber nicht wirklich ein Problem sein 😉

Divx, jQuery und der IE9

Da muss man auch erstmal drauf kommen. Beim Testen von Änderungen eines Kundenauftritts funktionierten plötzlich die Ajax Requests für ein paar, via jQuery eingebundenen Skripte nicht mehr, natürlich nur im Internet Explorer 9. Zuerst dachte ich, ok, wird wohl irgendwo ein Scriptfehler im jQuery Code sein, ich habe dort aber keinen gefunden, nur eine lustige Fehlermeldung:

Beim googeln stieß ich dann auf den Hinweis, dass DivX Plugins für den IE9 hier zu Fehlern führen. Sobald man diese deaktiviert und dann den Internet Explorer neu startet, läuft auch alles wieder wie erwartet. Da könnte man Stunden beim debuggen verlieren.

IE8, HTML5 und Fancybox

Tja, der liebe IE8 kann halt auch nicht mit HTML5, wenn man Fancybox verwenden möchte. Das kann jetzt natürlich auch am modernizr liegen, dass eben Inhalte, die per Ajax nachgeladen werden, nicht mehr für die alten IE Versionen modifiziert werden.

Ich werde wohl mal mit innerShiv beschäftigen, vielleicht läuft es dann ja wie gewünscht. So lange aber werde ich nachladbare Inhalte lieber noch ohne HTML5 Elemente erstellen.

Wenn ich dann noch einen Wunsch frei hätte, würde ich mir wünschen, dass Microsoft dem Internet Explorer die gleiche Silent Update Routine Ihrem Produkt hinzufügt, wie Sie Google schon seit langem für Chrome verwendet. Bedenken ob des Zugriffs auf den Anwenderrechner hin oder her, aber so könnte man gewährleisten, dass alte IE Versionen endlich mal nahezu aussterben würden.

*Update*
innerShiv funktioniert auch mit via Fancybox und Ajax nachgeladenen Inhalten scheinbar einwandfrei. Das hat mir jetzt eine menge Arbeit beim umschreiben von HTML5 zurück zu HTML4.01 oder XHTML1.0 erspart.

Zend Forms mit Ajax versenden

Im Netz gibt es ja zahlreiche Artikel zu Zend Forms und wie man diese mit Ajax validiert. Eigentlich alle Treffe via Google, die ich gefunden habe, basieren auf die selbe Lösung und exemplarisch dafür möchte ich hier nur auf eine mögliche Seite, die sich diesem Thema annimmt, verweisen: Ajaxify your Zend Form, validation with jquery.

Da eigentlich alle Seiten die gleichen Codefragmente verwendet haben und man hier noch einen ausführlichen Webcast dazu bekommt, hat mir das Tutorial bei Zendcast zu diesem Thema am besten gefallen. Der Vorteil bei dieser Art der Validierung liegt auf der Hand, das Zend Framework nimmt einem jegliche Programmierung bei der eigentlichen Validierung ab und noch wichtiger, die Validierung an sich bleibt Server-Seitig. Leider fand ich nirgends einen Hinweis darauf, wie man die Form, nach erfolgreicher Validierung dann doch abschicken kann. Viele fragten auf einschlägigen Seiten nach, oft gab es aber nur die Antwort darauf, wie man ein automatisches Submit der Form bei erfolgreicher Validierung verhindert.

Als erstes muss man ganz klassisch eine Form mit Hilfe von Zend_Form definieren.

Natürlich sollte hier mindestes ein Pflichtfeld vergeben sein, sonst gibt es nichts zu validieren und das Formular kann immer versendet werden. In diesem Beispiel ist es das E-Mail Feld $email->setRequired(true);. Jetzt benötigt man noch den Controller und die View, schließlich möchte man das Formular ja sehen und falls es valide ist, soll ja irgendwas mit der Eingabe geschehen.

Der Controller sieht vorerst so aus und macht erst einmal nichts weiter als das Formular anzuzeigen:

Die zugehörige View könnte dann zum Beispiel so aussehen:

Oder einfacher (je nachdem, wie flexibel man beim Layout seien muss oder möchte):

Als nächstes kommt dann noch, wie bei ZendCast vorgeführt die eigentliche Validierung via Ajax und dem Serverseitigen Mechanismus, der durch Zend Form zur Verfügung gestellt wird. Hierzu werden einige kurze Javascript Funktionen benötigt, die sich in der entsprechenden View befinden und schnell erstellt sind. Ferner werden die Pflichtfelder bereits bei der Eingabe überprüft (.blur()). Das ganze könnte dann ungefähr so aussehen:

Es gibt, wie man sehen kann, zwei Funktionen für die Validierung. Zum einen, wie bei den ganzen anderen Tutorials die Funktion doValidation(). Hier wird jedes Feld direkt bei der Eingabe überprüft und sofort das entsprechende Feld mit einer Fehlermeldung markiert, bzw. diese Markierung wieder entfernt, sobald das Feld valide ist. Da man aber sicher nicht schon bei der Eingabe eines an sich validen Formulars dieses automatisch absenden möchte, da vielleicht die Felder, die nicht validiert werden, fertig ausgefüllt sind oder man seine Eingabe noch ändern möchte, habe ich eine zweite, angepasste Funktion (doValidationAll()) implementiert, die zum einen das valide Formular absendet und zum anderen alle Felder gleichzeitig beim drücken des Submit Buttons validiert und entsprechende Fehlermeldungen positioniert. Gleichzeitig ist dieser Teil auch dafür zuständig, alle Daten des validen Formulars an den Controller weiter zu reichen, um dann hier die Daten zu verarbeiten.

Man könnte das ganze sicher noch vereinfachen und vor allem bei Erfolg einen leeren JSON-String zurück geben und anschließend auf einen leeren String testen und so ein paar Zeilen sparen. Sicher könnte man auch aus zwei Controllern nur einen machen, aber das sind dann Feinheiten für das Refactoring.

Jedenfalls hat mit genau dieser Teil bei meiner Suche im Netz gefehlt. Vielleicht hilft es ja Jemandem.