Peter: Formular in Echtzeit speichern

hallo,

in meiner bude habe ich eine kleine plattform mit php programmiert auf welcher es diverse siten gibt, welche die user daten in formularfelder eingeben müssen. die user haben sich nun beschwert, dass wenn sie aus unachtsam nicht den speicher-button dedrückt hatten und auf eine andere site gewechselt haben, dass alle daten dann natürlich verloren sind/sprich ja nicht gespeichert.

meine frage nun, gibt es eine möglichkeit (wahrscheinlich mit JavaScript), dass alle daten irgend in einen Cache/session geschriben werden bis sie gespeichert werden?

vielleicht kennt jemand eine referenz oder hat eine idee dazu?

vielen dank

  1. Hallihallo!

    Möglich wäre da ein eventhandling "onunload".
    Diesem könntest Du eine Funktion zuordnen, die das Formular übermittelt.
    Man könnte das sogar noch auf die Spitze treiben, daß sich onunload ein confirm- Fenster öffnet, in dem man die Übermittlung der Formulardaten bestätigen muss (man könnte ja auch absichtlich nicht gespeichert haben).

    Das funktioniert aber Alles nur, wenn die schusseligen Besucher auch Javascript aktiviert haben.

    Die passenden Kapitel dazu in Selfhtml:
    eventhandler onUnload
    confirm()

    Viele liebe Grüße,
    Der Dicki

  2. Hallo

    in meiner bude habe ich eine kleine plattform mit php programmiert auf welcher es diverse siten gibt, welche die user daten in formularfelder eingeben müssen. die user haben sich nun beschwert, dass wenn sie aus unachtsam nicht den speicher-button dedrückt hatten und auf eine andere site gewechselt haben, dass alle daten dann natürlich verloren sind/sprich ja nicht gespeichert.

    Vielleicht hilft Dir die Diskussion im Thread https://forum.selfhtml.org/?t=114012&m=725421 weiter.
    Beachte Cybaers Tipps.

    Freundliche Grüße

    Vinzenz

  3. Hi,

    in meiner bude habe ich eine kleine plattform mit php programmiert auf welcher es diverse siten gibt, welche die user daten in formularfelder eingeben müssen. die user haben sich nun beschwert, dass wenn sie aus unachtsam nicht den speicher-button dedrückt hatten und auf eine andere site gewechselt haben, dass alle daten dann natürlich verloren sind/sprich ja nicht gespeichert.

    meine frage nun, gibt es eine möglichkeit (wahrscheinlich mit JavaScript), dass alle daten irgend in einen Cache/session geschriben werden bis sie gespeichert werden?

    vielleicht kennt jemand eine referenz oder hat eine idee dazu?

    ja, Du kannst einen Warenkorb bauen, indem Du alle Felder speicherst (Änderungen generell übernehmen, mit onchange...).

    Aber ehrlich gesagt, würde ich diesen Aufwand nicht betreiben wollen, ich glaube auch, daß es ein anderes Problem gibt, was mit der Benutzerführung zusammenhängt!
    Wenn man ein 3km langes Formular präsentiert und ganz unten irgendwo ein "speichern"-Button hängt, dürften 3 von 10 Leuten erhebliche Probleme haben. Die Leute lesen nicht alles, wissen nicht, daß der Button etwas macht, usw.

    Tip: Ich kenne Deine Seite ja nicht, aber nutze sehr kleine Formulare, die Du vielleicht per Divs umschaltest. Guck Dir mal ein Beispiel an, daß ich vor kurzem geschrieben habe:
    http://free.w3statistics.de (Du müßtest Dich da einmal anmelden, email reicht).
    Geh dann mal in die "Konfiguration" und sieh Dir das an.
    Es gibt ein paar unabhängige Formulare (User, Gruppen, Webseiten, Rechte), die auch immer ein "speichern" verlangen.
    Selbst wenn man 100 User hätte, wäre es wohl noch händelbar bzgl. des Formulars, da jeder User per DIV umgeschaltet wird, die DIVS aber alle in ein und demselben Formular hängen. D.h. wenn ich User_A geändert habe und (ohne zu Speichern) auf User_B umschalte, geht die Information _nicht_ verloren.

    Gruß
    Reiner

  4. moin,

    vielleicht kennt jemand eine referenz oder hat eine idee dazu?

    mit xajax geht das. ich glaube aber, dass der aufwand unverhältnismäßig groß ist weil du eine ganze menge zusatzlogik brauchst, um die daten auch wirklich richtig zuzuordnen.

    ich habe bei gleicher fragestellung eher immer daran gedacht, die links mit javascript zu belegen, die alle formfelder auf änderungen prüfen. wenn vorhanden kommt ein alert. ich hab aber keine ahnung, ob man das in jeden link einbauen muss, um das zu realisieren (was natürlich vom aufwand auch nicht ohne ist).

    abgesehen von den möglichkeiten kann man ja auch mal von einer bestimmten grundmenge an hirn eines benutzers ausgehen ;)

    viele grüsse, andreas

  5. Hallo,

    die user haben sich nun beschwert, dass wenn sie aus unachtsam nicht den speicher-button dedrückt hatten und auf eine andere site gewechselt haben, dass alle daten dann natürlich verloren sind/sprich ja nicht gespeichert.

    Recht doofe User, wenn Du mich fragst.

    Derzeit wird eine Javascript-Technik namens AJAX recht gehypt. Im wesentlichen ist das nichts neues, neu ist nur, dass man in den großen Browsern das Objekt XMLHttpRequest zur Verfügung hat, mit dem man HTTP-Requests absetzen und das Ergebnis wieder empfangen kann. Das eignet sich durchaus für Speichern im Hintergrund.

    Realisieren könntest Du das z.b. in dem Du mit dem Event-Handler onblur darauf achtest, ob ein Formularfeld verlassen (sprich: ausgefüllt) wurde. Dann wird im Hintergrund mittels Javascript ein HTTP-Request mit dem Inhalt des Feldes abgesetzt. Auf der Serverseite bräuchtest Du dann entsprechende reduzierte PHP-Funktionen, die auch bei Bedarf Fehlermeldungen zurückgeben, die Dein Javascript dann dem HTTP-Request entnehmen und in die Seite einmontieren. Zwei Dinge solltest Du beachten:

    Visuelle Rückmeldungen sind trotzdem wichtig. Insbesondere eine Art Statusmeldung bei den Formularfeldern, reiner Text oder Icons („Fehler“, „wird gespeichert“, „gespeichert“). Auch wenn Deine Benutzer es nicht gewohnt zu sein scheinen, viele haben sich an das Web und die klassische Formularbedienungsweise gewöhnt. Es sollte schon offensichtlich sein, dass das Formular automatisch dafür sorgt, dass die Eingaben gespeichert werden.

    Und natürlich der klassische Hinweis: Man sollte niemals das Vorhandensein von Javascript voraussetzen, d.h. Dein Formular sollte auch ohne JS funktionstüchtig sein. Es böte sich an, erst ein klassisches Formular zu entwickeln (hast Du ja schon) und dann bei window.onload (und dem Feststellen, dass die für AJAX benötigten Funktionen & Objekte vorhanden sind) das Formular ajaxifizieren, z.b. den nun nicht mehr benötigten Submit-Button vorsichtig aus dem Dokument raus zu operieren.

    Automagisch speichernde Formulare gehören mit zu den beliebtesten Dingen des derzeitigen AJAX-Hypes, da gibt es inzwischen einige Beispiele dazu. Der oben verlinkte Wikipedia-Artikel hat Links, wenn Du denen folgst, dürftest Du bestimmt fündig werden.

    Tim

    1. Hi,

      die user haben sich nun beschwert, dass wenn sie aus unachtsam nicht den speicher-button dedrückt hatten und auf eine andere site gewechselt haben, dass alle daten dann natürlich verloren sind/sprich ja nicht gespeichert.

      Recht doofe User, wenn Du mich fragst.

      sag denen das mal ins Gesicht.   :-)

      Gruss,
      Ludger

    2. Moin,

      Derzeit wird eine Javascript-Technik namens AJAX recht gehypt...

      Eine ähnliche Technik gibt es schon länger. Nennt sich Javascript-Remotescripting: http://www.ashleyit.com/rs/main.htm.

      MfG
      MarkX.

      1. Hallo,

        Eine ähnliche Technik gibt es schon länger. Nennt sich Javascript-Remotescripting: http://www.ashleyit.com/rs/main.htm.

        Jupp. Aber hat sich schon 2000 nicht wirklich durchgesetzt und ... nun ja ... unsichtbare iframes zum Laden externer Inhalte zu verwenden finde ich etwas von hinten durch die Brust ins Auge.

        Tim

        1. Moin,

          Jupp. Aber hat sich schon 2000 nicht wirklich durchgesetzt und ... nun ja ... unsichtbare iframes zum Laden externer Inhalte zu verwenden finde ich etwas von hinten durch die Brust ins Auge.

          Hm. Unsichtbare iframes sind dafür aber gar nicht notwendig, oder was meinst Du jetzt?

          MfG
          MarkX.

          1. Hallo,

            Hm. Unsichtbare iframes sind dafür aber gar nicht notwendig, oder was meinst Du jetzt?

            Schau Dir doch mal die von Dir verlinkte Seite genauer an. Lassen wir mal die IE-Implementierung mit Java (Java!!) beseite und gucken uns nur die Bibliotheken JSRS und RSLite an. Erstere baut ein iframe ein, zweitere nutzt ein Bild. Wie üblich halt früher, wenn man mit JS Requests machen will. Das was diese Bibliotheken machen, ist nichts anderes, als all die Kärnerarbeit so abzukapseln, dass man aus Benutzersicht bequem Requests absetzen kann, ohne sich um den ganzen Kleinscheiss kümmern zu müssen. Ebenso wie man es bei XMLHttpRequest macht - ohne diese kompliziertere Variante mit einem mehr an JS-Code nötig zu haben.

            Tim

            1. Moin,

              Schau Dir doch mal die von Dir verlinkte Seite genauer an. Lassen wir mal die IE-Implementierung mit Java (Java!!) beseite und gucken uns nur die Bibliotheken JSRS und [link:http://www.ashleyit.com/rs/rslite/rslite.js@title=RSLite an.

              Na gut, ich bin kein Javascript-Experte. Zur Implementierung ist ein Verstehen dieser Bibliotheken aus meiner Sicht nicht notwendig.

              ... Ebenso wie man es bei XMLHttpRequest macht - ohne diese kompliziertere Variante mit einem mehr an JS-Code nötig zu haben.

              Nunja, wie gesagt. Kompliziert ist die _Implementierung_ aus meiner Erfahrung jedenfalls nicht. Welcher Javascript-Code für die Funktionalität verantwortlich ist, ist für mich nicht relevant, solange die gängigen Browser dies unterstützen (was der Fall ist).

              MfG
              MarkX.

    3. hi,

      Realisieren könntest Du das z.b. in dem Du mit dem Event-Handler onblur darauf achtest, ob ein Formularfeld verlassen (sprich: ausgefüllt) wurde. Dann wird im Hintergrund mittels Javascript ein HTTP-Request mit dem Inhalt des Feldes abgesetzt.

      mal davon ausgehend, dass der reine HTTP-traffic dabei ähnlich hoch liegt wie der hier für das anfordern sonstiger ressourcen üblicherweise mit ca. ein bis zwei KByte geschätzte - so viel daten jedes mal übertragen, wenn der user irgendein popeliges feld wie username oder emailadresse ausgefüllt hat?
      absoluter overkill.

      gruß,
      wahsaga

      --
      /voodoo.css:
      #GeorgeWBush { position:absolute; bottom:-6ft; }
      1. Hallo Christoph,

        mal davon ausgehend, dass der reine HTTP-traffic dabei ähnlich hoch liegt wie der hier für das anfordern sonstiger ressourcen üblicherweise mit ca. ein bis zwei KByte geschätzte

        Eher weniger. Man kann ja handschneidern, was man überträgt, bleiben also nur die Header für Request und Antwort und eventueller Ballast über. Das kann ein handgeklöppeltes XML sein oder auch nur Text. OK rein mit HTTP-Daten würde man schon auf 1 KB kommen, ja. Aber Traffic soll ja billig sein, hört man immer wieder.

        so viel daten jedes mal übertragen, wenn der user irgendein popeliges feld wie username oder emailadresse ausgefüllt hat? absoluter overkill.

        Wenn's der Usability dient … ;)

        Kommt immer auf den Einsatzzweck an. Bei längeren Formularen kann man das auch in regelmäßigen Abständen nach Änderung auf der Seite machen, andererseits hätte man bei manchen Dingen gerne ein Rückmeldung. Z.b. beim Aussuchen eines Benutzernamens - wenn man noch ein längeres Formular vor sich hat, wäre es ganz geschickt, wenn dort die Fehlermeldung „Der Benutzername "harter_hengst" ist schon registriert" eingeblendet würde.

        Tim

        1. Hallo Willy!

          Hallo Christoph,

          mal davon ausgehend, dass der reine HTTP-traffic dabei ähnlich hoch liegt wie der hier für das anfordern sonstiger ressourcen üblicherweise mit ca. ein bis zwei KByte geschätzte

          Eher weniger. Man kann ja handschneidern, was man überträgt, bleiben also nur die Header für Request und Antwort und eventueller Ballast über. Das kann ein handgeklöppeltes XML sein oder auch nur Text. OK rein mit HTTP-Daten würde man schon auf 1 KB kommen, ja. Aber Traffic soll ja billig sein, hört man immer wieder.

          Es ist ja nicht der traffic der den Braten ein wenig fett macht, sondern die zusaetzlich zu verwaltende Logik.

          so viel daten jedes mal übertragen, wenn der user irgendein popeliges feld wie username oder emailadresse ausgefüllt hat? absoluter overkill.

          Wenn's der Usability dient … ;)

          "Usability" kann natuerlich auch bedeuten "user doof, user soll doof bleiben, sonst user ungluecklich".

          „Der Benutzername "harter_hengst" ist schon registriert"

          Immer noch besser als "Willy".

          Gruss,
          Ludger

          1. Hallo,

            „Der Benutzername "harter_hengst" ist schon registriert"

            Immer noch besser als "Willy".

            »»sag denen das mal ins Gesicht

            Thomas

  6. Hallo,

    Das besagte onunload-Event ist nicht so praktisch, denn darüber kann man das Verlassen der Seite nicht abbrechen, sondern nur lustig z.B. ein Popup-Fenster öffnen, das gerne geblockt wird.

    Der onbeforeunload-Event-Handler ist geeigneter, Gecko und MSIE kennen ihn. Damit kann man ein Meldungsfenster erscheinen lassen, in dem der Anwender auf das nicht abgesendete Formular aufmerksam gemacht wird. Dort kann er dann ggf. Abbrechen wählen.
    AJAX-Gefummel brauchen - wenn man nicht schon jede Feldänderung direkt an den Server senden will - somit nur Opera und Konqueror. Opera macht das recht gut. Konqueror sendet zwar den Request, wartet aber trotz synchronem Request nicht mit zum readyState 4, bevor er die Seite wechselt. Ich würde im Konqueror nicht darauf vertrauen, dass der Request immer ankommt.

    Mal ein (längeres, aber trotzdem primitives) Beispiel (das Serialisieren der Formulardaten ist natürlich stümperhaft und funktioniert gerade mit dem Testformular - es geht ums Prinzip):

    <html><head><title>Formular speichern</title>  
    <script type="text/javascript">  
    [code lang=javascript]function xmlhttp () {  
     _xmlhttp = false;  
     if (typeof(ActiveXObject) != "undefined") {  
      try {  
       _xmlhttp  = new ActiveXObject("Microsoft.XMLHTTP");  
      } catch (e) {  
       _xmlhttp  = false;  
      }  
     } else if (typeof(XMLHttpRequest) != 'undefined') {  
      _xmlhttp = new XMLHttpRequest();  
     }  
     return _xmlhttp;  
    }  
    function urlencode (str) {  
     var code = "";  
     for (var i = 0; i < str.length; i++) {  
      if (str.charAt(i) == " ") {  
       code += "+";  
      } else if (str.charAt(i) == "+") {  
       code += "%2B";  
      } else if (str.charCodeAt(i) > 127) {  
       code += encodeURI(str.charAt(i));  
      } else {  
       code += escape(str.charAt(i));  
      }  
     }  
     return code;  
    }  
    function autosave (form) {  
     var serialized_form = "";  
     for (var i = 0; i < form.elements.length; i++) {  
      if (form.elements[i].type == "text" && !form.elements[i].disabled) {  
       serialized_form += urlencode(form.elements[i].name) + "=" + urlencode(form.elements[i].value);  
       if (form.elements.length - i > 2)  
        serialized_form += "&";  
      }  
     }  
     var conn = xmlhttp();  
     if (!conn) return;  
     conn.open("POST", form.action, false);  
     conn.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");  
     conn.onreadystatechange = function (e) {  
      if (this.readyState != 4)  
       return;  
      if (this.responseText == "saved") {  
       window.alert("Ihre Formulardaten wurden erfolgreich gespeichert.");  
      } else {  
       window.alert("Es gab einen Fehler beim Speichern der Formulardaten. Betätigen Sie bitte gleich »Zurück« und senden Sie das Formular über den Knopf »Daten speichern« ab.");  
      }  
     };  
     conn.send(serialized_form);  
    }  
    function beforeunload () {  
     if (form_changed && !form_submitted) {  
      unload_stopped = true;  
      return "Sie verlassen die Seite, ohne dass Ihre Formulareingaben gespeichert worden sind. Bitte wählen Sie »Abbrechen« und senden Sie das Formular über den Knopf »Daten speichern« ab, sonst gehen die Eingaben verloren.";  
     }  
    }  
    function unload () {  
     if (form_changed && !form_submitted && !unload_stopped) {  
      window.alert("Sie verlassen die Seite, ohne dass Ihre Formulareingaben gespeichert worden sind. Es wird versucht, die Daten automatisch zu speichern.");  
      autosave(document.forms.formular);  
     }  
    }  
    function load () {  
     document.forms.formular.elements[0].onchange = form_change;  
     document.forms.formular.onsubmit = form_submit;  
    }  
    function form_change () {  
     form_changed = true;  
    }  
    function form_submit () {  
     form_submitted = true;  
    }  
      
    var form_changed = false;  
    var form_submitted = false;  
    var unload_stopped = false;  
    window.onload = load;  
    window.onbeforeunload = beforeunload;  
    window.onunload = unload;  
    
    ~~~</script>  
    </head><body>  
      
    <form action="save.php" method="post" accept-charset="utf-8" id="formular">  
    <p><input type="text" name="=%&amp; +#-.,öäü" value="=%&amp; +#-.,öäü"></p>  
    <p><input type="submit" value="Daten speichern"></p>  
    </form>  
      
    <p><a href="js-save-form.html">weg</a></p>  
      
    </body></html>[/code]  
      
    Mathias