Problembeschreibung
Die Formularkomponente BreezingForms für Joomla meldet an den Seitenbenutzer diverse Informationen, so z.B. wenn Pflichtfelder nicht ausgefüllt wurden, oder das Formular erfolgreich gesendet wurde. Da Webseiten heutzutage wg. der mobilen Geräte häufig sehr lang sind, oder Formulare sehr viele Felder haben können, kann es passieren, dass diese Meldungen, die bei BreezingForms oberhalb des Formulars eingeblendet werden, oder auf einer Feedbackseite ausgegeben werden, nicht im sichtbaren Bereich liegen. Der Seitenbesucher sieht diese Meldungen nicht, und ist verwundert, oder gar genervt darüber, nicht zu erfahren, was jetzt nach dem Klick auf dem Absendebutton genau passiert ist.
Beide oben genannten Grundprobleme - also die Feedbackmeldung nach dem erfolgreichen Senden und die Fehlermeldungen bei Fehleingaben oder nicht gefüllten Feldern, sind jedoch vom Verhalten etwas unterschiedlich.
Bei den Erfolgs-Feedbackmeldungen wird nach dem Senden die gleiche Seite auf dem sich das Formular befindet erneut aufgerufen. Statt des Formulars wird dann aber z.B. der Inhalt der Formularseite 2 oder eine andere angezeigt. Allerdings an der gleichen Position wie das Formular vorher. Wie gesagt bei langen Seiten, wenn das Formular recht weit unten steht, wird nicht zu dieser Meldung gesprungen, sondern die Seite bleibt oben stehen. Die Meldung wird nicht gesehen.
Der 2. Fall, bei Fehleingaben oder fehlenden Angaben, werden per JavaScript Meldungen oberhalb des Formulars erzeugt. Ist das Formular sehr lang und logischerweise befindet sich der Nutzer beim Klick auf den Senden-Button am unteren Ende des Formulars, dann sieht er diese Meldungen nicht. Evtl. nimmt er an, dass das Formular erfolgreich gesendet wurde oder er vermutet, dass das Formular nicht funktioniert. Der Seitenbetreiber erhält dann beidenfalls keine Anfrage.
Diese Probleme müssen also gelöst werden.
Die Problemlösungen
Beide Fälle müssen unterschiedlich gelöst werden, einzig das Scrollen an die Zielposition mit den Fehler- oder Feedbackmeldungen werden adäquat behandelt. Im Detail folgt hier mein einfach umzusetzender Lösungsvorschlag:
A) Feedbackmeldung bei erfolgreichem Absenden
Wie gehen hierbei davon aus, dass Formulare in einer Modulposition veröffentlich wurden. In das Modul können wir eine Modulklasse für dieses Formular eintragen, um später darüber unser Formular zu erkennen. Natürlich kann man auch in der Formularkonfiguration oberhalb jedes Formulars einen Anchor setzen und später diesen ansprechen. Ich habe mich im Beispiel aber für diese Variante entschieden.
Unserem Formular-Modul-Bsp. gebe ich hier mal die CSS-Klasse _mbf-TA (steht für modul-breezing-forms-Termin-Anfrage) mit.
Dann wechselt man in die Formularverwaltung, ruft das betroffene Formular auf. Über den Reiter Erweitert und den Button mehr Optionen gelangen wir auf die Formulareinstellungen. Dort gibt es den Reiter Scripte und dort die Section übermittelt Skript. Wenn man die Checkbox spezial anklickt kann man eigene JavaScripte editieren. Dort editieren wir z.B. unser Submit-Script, welches beim Klick auf den Absenden-Button ausgeführt wird. Für das Scrollen nach oberhalb des Formulars habe ich hier eine jQuery-Sequenz eingefügt, die die Position des Formulars auf der Seite bestimmt und dann per animate() mit etwas Verzögerung dorthin scrollt. Das Formular finden wir über o.g. CSS-Selector.
function ff_terminanfrage_submitted(status, message) {
if(status==0){
ff_switchpage(2);
jQuery(document).ready(function() {
jQuery('html, body').animate({ scrollTop: jQuery('._mbf-TA').first().offset().top}, 2000);
});
} else {
alert(message);
}
}
Die Formulareinstellungen müssen dann noch gespeichert werden und können dann in ihrer Funktion getestet werden.
Wer nicht mit dem Selector im Modul arbeiten will, was denkbar ist, wenn man definitiv immer nur ein BF-Formular pro Seite hat, kann z.B. auch den Selector für die den BF-Intro-Text verwenden.
Die jQuery-Zeile sähe dann für diesen Fall so aus:
jQuery('html, body').animate({ scrollTop: jQuery('.bfPageIntro').first().offset().top }, 1000);
Eine dritte Möglichkeit sei gezeigt, die ich bevorzuge - nämlich die Verwendung von Ankern. Der Grund für die Präferenz ist, dass es viele Seiten gibt, bei denen es z.B. im Kopfbereich ein fix verankertes Menü gibt. Springe ich an den Formularbeginn, rutschen die Meldungen evtl. noch unter das Menü und sind damit verdeckt. Kreiere ich eine Anchor-Tag, kann ich diesem per Styleanweisung einen negativen margin mitgeben. Damit liegt der Anchor immer ein Stück weit oberhalb seines Formulars und es wird dorthin gescrollt. Den Anchor selbst kann ich in das Formlar einbauen. Dazu rufe ich das jeweilige Formular auf und klicke auf Seite 1. Dort gibt es den editieren-Link über den man in ein Editorfenster gelangt. Dieses in den HTML-Modus umschalten und z.B. folgende Zeile eingeben:
<a id="bf-anchor-page1" name="bf-anchor-page1" class="bf-anchor"></a>
In die CSS/LESS-Datei dann folgende Anweisung einbauen:
.bfPageIntro {
position: relative;
a.bf-anchor {
position: absolute; top:-5rem;
}
}
Die dazu passende jQuery-Zeile sähe dann so aus:
jQuery('html, body').animate({ scrollTop: jQuery('.bf-anchor').first().offset().top }, 1000);
Noch eine einfache Möglichkeit sei erwähnt. Diese kommt gänzlich ohne zusätzlichem Anchor oder zusätzlichem Modul-Selector aus. Aber! Diese Möglichkeit wird nicht in jedem Fall anwendbar sein, denn ich z.B. beitreibe meine BF-Formulare i.d.R. so, dass die Feedback-Meldung nach dem erfolgreichen Empfang und Verarbeiten der Formulardaten auf eine 2. Formularseite springt - so wie das BF auch regulär anbietet. Hierbei passieren aber ein paar nicht offensichtliche Dinge, die Stolperfallen sind: Nämlich, mit jedem Laden einer Seite mit BF-Formular, wird in der Seite immer das gesamte Formular mit allen seinen Formular-Seiten eingebettet. Nur die jeweils für den Schritt aktuelle Formularseite ist sichtbar. Alle anderen Seiten sind immer per Style display:none ausgeblendet. Über den Dom-Baum lassen diese sich natürlich trotzdem referenzieren. D.h. einen Anchor mit dem Selector .bf-anchor oder .bfPageIntro gibt es bei Mehr-Seiten-Formularen mehrfach. Evtl. findet eine jQuery('.bfPageIntro:first') oder ein jQuery('.bfPageIntro').first() einen Tag, der nicht sichtbar ist. Das liefert ggf. einen Offset von 0/0 und damit ein Fehlverhalten.
Also: 1.) Wir verwenden keinen speziell einzufügenden Anchor, sondern eine schon existierenden Tag mit ID. Ganz zuverlässig unter Berücksichtigung eben formulierte Problematik erweist sich hier z.B. die Formuar-Seiten-ID. Für unsere 2. Feedbackseite wäre das die ID #bfPage2. Und nun machen wir gleich noch eins: Nach dem wir per offset().top die vertikale Position ermittelt haben, subtraieren wir einen Wert von z.B. 200px und scollen an diese Position. Damit verhindern wir also, dass der Formularanfang mit unseren Meldungen unter ein vorhandenes fixes Site-Menü rutscht. Die jQuery-Zeile sähe dann so aus:
jQuery('html, body').animate({ scrollTop: jQuery('#bfPage2').offset().top - 200 }, 1000);
Für welche der drei Möglichkeiten Sie sich entscheiden, überlasse ich Ihnen. Das hängt sicher immer auch von der Projektkonstellation ab. Die zuletzt aufgeführte, ist die einfachste aber evtl. nicht immer praktikabel. Von mir wird diese bevorzugt und empfohlen. Wer mit weiteren als nur mit 2 Formularseiten arbeitet, muss sich hier ein bissel was ausdenken.
B) Fehlermeldung bei Fehleingaben oder fehlenden Pflichfeldeingaben
Für die Umsetzung dieser Aufgabe gehen wir anders vor, denn diese Fehlermeldungen werden ja nicht erst nach dem Formularsenden als Feedback ausgegeben, sondern die Validierungsscripte prüfen vor dem Absenden und verhindern dieses im Fehlerfall.
Für die Auslösung und Auswertung dieser Validierung ist das Script ff_validate_submit verantwortlich. Das ist ein fertiges von BF geliefertes Scriptschnippselchen, welches wir in der Liste, welche über den Button Scripte verwalten aufgerufen wird, finden.
Mit dem von mir eingefügten Zweizeiler sieht das Script modifiziert dann so aus:
function ff_validate_submit(element, action)
{
if(typeof bfUseErrorAlerts != 'undefined'){
JQuery(".bfErrorMessage").html('');
JQuery(".bfErrorMessage").css("display","none");
}
error = ff_validation(0);
if (error != '') {
if(typeof bfUseErrorAlerts == 'undefined'){
alert(error);
} else {
bfShowErrors(error);
}
ff_validationFocus();
// damit die Fehlermeldungen in den sichtbaren Bereich scrollen:
jQuery('html, body').animate({ scrollTop: jQuery('.bfPageIntro').first().offset().top - 200 }, 1000);
} else
ff_submitForm();
} // ff_validate_submit
In gleicher Manier wie oben für A) beschrieben, wird auch hier per jQuery das Tag mit dem Selector bfPageIntro geholt und dann scrollend dorthin animiert.
Alternativ kann man auch hier mit einem Eingefügten Anchor arbeiten, wobei dann aber zu beachten ist, dass diese ggf. nicht auf Seite 1 des Formulars, sondern auf Seite 2 o.a. eingefügt werden muss! Oder Sie nutzen wieder einen Modul-Selector, falls Sie z.B. mehrere BF-Formulare pro Seite nutzen.
Verwendung einer externen Scroll-To-Funktion
Die hier beschriebene Methode ist eine nachträglich von mir noch eingefügte Vereinfachung der Scroll-To-Anweisung. Der Grund ist, dass ich eh schon in meinen Projekten eine softe scroll-to-Funktion lade und diese folglich auch hier anwenden möchte, um Code-Redundanzen zu vermeiden.
Die JavaScript-Funktion zum soften Scrollen (smoothScrollTo()) sieht bei mir so aus und befindet sich neben anderen im Script smoothscroll.js:
function smoothScrollTo (anchor) {
console.log('Vers. 20:07, ist eine Anchor-Ref.');
// Wenn der Anchor als ID mit # fertig übergeben wird
if (anchor.substring(0,1) == '#') {
anchor = anchor;
// Wenn das Target über einen Class-Selektor angeben wird, nach dem ersten Treffer suchen
} else if (anchor.substring(0,1) == '.') {
console.log('Anchor als Cls-Selector');
anchor = anchor+':first';
} else {
anchor = '#anchor_'+anchor;
}
var duration= 2000;
console.log(anchor);
var target = jQuery(anchor);
var targetY = target.offset().top - 100;
console.log('anchor-y-target '+anchor+': '+ targetY );
jQuery("html, body").animate({
"scrollTop" : targetY
},
duration,
'swing'
);
}
Der Aufruf z.B. im BF-Script ff_validate_submit (zur Erinnerung, dieses Script ist verantwortlich für die Prüfung von Formulareingaben oder fehlenden Eingaben VOR dem Absenden) sieht dann z.B. einfach so aus (hier mit der Voraussetzung, dass wir lediglich eine 2-Seiten-Formular nutzen):
...
ff_validationFocus();
// damit die Fehlermeldungen in den sichtbaren Bereich scrollen:
smoothScrollTo('#bfPage1');
...
Ganz oben hatte ich beschrieben, wie ein eigenes Script z.B. ff_terminanfrage_submitted() modifiziert habe, um NACH dem Absenden eines Formulars die Feedbackmeldung in den sichtbaren Bereich zu scollen. Neben dieser formulareigenen Lösung gibt es auch eine für alle Formular gemeinsam nutzbare Lösung (Immer vorausgetzt, dass z.B. alle Formulare nur 2 Seiten haben!). Dazu habe ich mir das Script ff_showsubmitted dubliziert per Kopieren-Button und diesen Klone umbenannt in ff_showsubmittedscrolltop. Dieses Script wird dann unter der Formulareinstellung Erweitert > mehr Optionen unter dem Register Scripte in der Section Übermittelt Skript aus der Bibliothek-Pulldownliste (Radiobutton Bibliothek) zugewiesen:
function ff_showsubmittedscrolltop(status, message) {
if(status==0){
ff_switchpage(2);
jQuery(document).ready(function() {
// wer die SmoothScroll-JS-Bibliothek verwendet:
// hier mit Nutzung des Anchor "bfPage2"
smoothScrollTo('#bfPage2');
// wer diesen Aufruf lieber über jQuery direkt nutzen will:
// hier mit Nutzung des immer verfügbaren PF-Anchors "formsubmitsuccess"
jQuery('html, body').animate({ scrollTop: jQuery('#formsubmitsuccess').offset().top }, 2000);
});
} else {
alert(message);
}
} // ff_showsubmittedscrolltop
Wer mal ein lebendes Beispie dazu sehen möchte, kann mal das Projekt DJ WAM besuchen. Ganz unten befindet sich ein so bearbeitetes Formular.
iFrame-Formulare als Lösung
Eine weiter Möglichkeit um das Problem mit dem sichtbaren Bereich für Meldungen nach dem Absenden der BF-Formular zu lösen, besteht darin die Formular in ein iFrame einzubetten. Nach dem Absenden wird so nicht eine komplett neue Seite geladen, sondern nur der iFrame-Inhalt aktualisiert. Ein Scrollen findet so nicht statt. Das ist allerdings auch keine immer nutzbare Lösung - z.B. ist diese dann nicht geeignet, wenn das Formular im iFrame relativ lang ist, denn dann liegt wiederum der Formlaranfang weit oberhalb des Absenden-Buttons und ein Scrollen findet dann nicht automatisch an die Anfangsposition statt.
Hier kurz die Beschreibung, wie man mit BF-Boardmitteln ein Forumular in ein iFrame einbettet. Dazu gibt es zwei Möglichkeiten, entweder das Formular ist ein Menü-Typ eingebunden, oder das Formular wird als Modul an einer Modulposition veröffentlicht. Jedoch gibt es in beiden Wegen die gleiche Konfigurationsmöglichkeit. Im Register Modul in der Modulkonfiguration oder im Add Form in der Menü-Eintrag-Konfiguration gibt es jeweils die Option Run in iframe. Diese auf Yes stellen.
Weiterhin gibt es in der Formular-Verwaltung für das jeweilige Formular unter dem Register Erweitert und dem Button Mehr Optionen und dort dem Register Einstellungen die Optionen für die Dimensionierung der iFrames. Hier kann die Breite z.B. auf 100% gesetzt werden und die Höhe auf Autoheight iFrame on. Somit passt sich das Formular auf die volle iFrame-Größe an.
Der BF-Formular-Einstellungen Speichern-Fehler
Achtung! An dieser Stelle sei auf eine Fehler aufmerksam gemacht, der sich beim Speichern der Formulare oft unbemerkt und unerkannt auswirkt.
In BF ist es möglich globale Einstellungen für ein Formular an zwei verschiedenen Stellen zu speichern. Zum eine kann man diverse Parameter unter der Formularverwaltung für das Formular unter dem Register Eigenschaften und Erweitert einstellen. Zum anderen kann man unter dem Register Einstellungen dem Button Weitere Optionen folgen und dann auf dieser Konfigurationsseite unter den diversen Registern Einstellungen setzen. Wenn man hier aber z.B. im Register Skripte unter Übermittelt Skript den Radiobutton Bibliothke wählt und ein Script aus der Pulldownliste auswählt wird das beim Speichern korrekt übernommen. Geht man nun aber in die o.g. Formulareinstellungen und speichert dort das Formular, dann wird man feststellen, dass die eben getroffene Konfiguration für das Übermittelt Skript wieder verloren gegangen ist. Das ist sehr tückisch, denn wenn man hier wichtige Funktionen aufgerufen hat, dann gehen diese bei jedem Formlarspeichern wieder verloren. Ich hoffe, dass dieser Bug mal behoben wird in BF.
Wenn man plötzlich eine weisse Seite erhält
Achtung! Es gibt einen kleine Bugs in BF. Vielen werden diese nie im Projektleben begegnen, aber wen es erwischt, steht ziemlich ratlos da.
- Wenn bei den Auswahloptionen für Scripte, Übermittlungsteile und Formularteile in der Radiogruppe aus Kein / Bibliothek / Spezial die Option Bibliothek ausgewählt wurde aber nichts in der dann erscheinenden Dropdownliste ausgewählt wurde, z.B. weil gar kein zutreffendes Teil zur Verfügung steht, dann führt das in BreezingForms zu einem Datenbankfehler.
- Wenn im Formular-Eigenschaften-Register die Checkbox "Blättern verwenden" auf nein Steht, kann das zu einem Fehler in Form einer Weißen Seite nach dem Absenden führen!