Frontend: Formulareintrag editierbar machen

Hallo,

ich suche einen eleganten Tip von Euch.

Problemstellung:

In einem Formular (html/php) wird ein zuvor in einem anderen Formular gemachter Eintrag angezeigt. Dieser Eintrag soll explizit NICHT in einem input-field (welcher Art auch immer) angezeigt werden, sodnern wirklich nur als Textbeitrag.

Frage:

Wie gestalte ich den Eintrag so, dass er clientmäßig in ein value eines input-fields gewandelt werden kann. Eine Möglichkeit wäre sicher das editable-field-plugin, dass es zu jquery gibt.

Aber vielleicht habt ihr ja noch bessere Ideen für mich.

Habt Ihr das schonmal für Euch irgendwie elegant lösen können?

Grüße, Leif

  1. Hallihallo!

    Habt Ihr das schonmal für Euch irgendwie elegant lösen können?

    Vielleicht nicht das Eleganteste, aber ohne zusätzliches JQuery Plugin:

    • den "editable" Text in ein span- Element packen
    • das span- Element hat einen onclick- Handler, der
         - den Text innerhalb des span ausliest,
         - das span unsichtbar macht,
         - ein input- Feld hinter dem span einfügt, und den ausgelesenen Text als value einsetzt

    In meinem Fall habe ich dann noch zusätzlich:

    • das input- Element mit einem onblur- Handler versehen, der:
         - den Value per Ajax an den Server überträgt (Falls er sich geändert hat, zum Vergleich habe ich ja noch den "alten" Value)
         - das input- Element wieder aus dem DOM entfernt, und
         - das unsichtbare Span- Element wieder einblendet und ggf. den neuen Text einsetzt

    Obwohl ich in meinem Projekt JQuery benutze, habe ich es "per Hand" wie oben beschrieben gemacht, weil ich nicht einsehen wollte, nur wegen einer solchen "Kleinigkeit" extra NOCH ein Plugin einzubinden. So weiss ich wenigstens genau, was da passiert :)

    Beste Grüsse,
        Tobias Hahner

    1. Obwohl ich in meinem Projekt JQuery benutze, habe ich es "per Hand" wie oben beschrieben gemacht, weil ich nicht einsehen wollte, nur wegen einer solchen "Kleinigkeit" extra NOCH ein Plugin einzubinden. So weiss ich wenigstens genau, was da passiert :)

      Hallo Tobias,

      genau DAS ist auch mein Grund, warum ich es ohne jquery machen möchte, obwohl ich im Gesamtprojekt jquery nutze.

      Deine Lösung hört sich klasse an, hast Du eventuelle nen Link zu Deinem Projekt opder auch zu einer entsprechenden Testseite für mich, damit ichs mir mal anschauen kann?

      Grüße, Leifr

      1. Hallihallo!

        Deine Lösung hört sich klasse an, hast Du eventuelle nen Link zu Deinem Projekt opder auch zu einer entsprechenden Testseite für mich, damit ichs mir mal anschauen kann?

        Leider ist mein Projekt ein Intranet- Projekt, so dass ich Dir für den Moment keinen Link bieten kann.
        Ich kann Dir aber bis zum späten Abend eine Testseite basteln (muss gleich wieder zur Arbeit), dann kannst es Dir in einer abgespeckten Version anschauen :)

        Beste Grüsse,
            Tobias Hahner

        1. Hallo Tobias,

          Leider ist mein Projekt ein Intranet- Projekt, so dass ich Dir für den Moment keinen Link bieten kann.

          Ok.

          Ich kann Dir aber bis zum späten Abend eine Testseite basteln (muss gleich wieder zur Arbeit), dann kannst es Dir in einer abgespeckten Version anschauen :)

          Das machst Du für mich? Große Klasse!
          Freu' ich mich wirklich drüber.

          Bis hierhin erstmal bedankt.

          Bis später, Leif

          1. Hallihallo!

            Ich kann Dir aber bis zum späten Abend eine Testseite basteln (muss gleich wieder zur Arbeit), dann kannst es Dir in einer abgespeckten Version anschauen :)

            OK, hat leider doch ein Bisschen länger gedauert als geplant, aber hier ist die Quick&Dirty Version:
            Funpic-Seite, sorry für die Werbung

            Ich hoffe, Du kannst damit was anfangen…

            Bis später

            Viel später :)

            Beste Grüsse,
                Tobias Hahner

            1. Hallo Tobias,

              OK, hat leider doch ein Bisschen länger gedauert als geplant, aber hier ist die Quick&Dirty Version:
              Funpic-Seite, sorry für die Werbung

              Ich hoffe, Du kannst damit was anfangen…

              Klasse! Das ist die Eleganz, die ich gesucht habe.
              Sehr schöne und saubere Lösung.

              Also erstmal vielen Danke für die Arbeit, die Du Dir dafür gemacht hast.
              Nun werde ich mir das mal im Detail ansehen gehen.

              Kann ich Dich eigentlich über die obige Mailadresse erreichen? Ich werde nämlich im Verlaufe diesen oder nächsten jahres auch eine Lagerverwaltung nachrüsten müssen. Vielleicht lassen sich dabei Synergien nutzen.

              Bis dahin nochmal danke, Leif

              1. Hallihallo!

                Klasse! Das ist die Eleganz, die ich gesucht habe.
                Sehr schöne und saubere Lösung.

                Freut mich, dass ich Dir helfen konnte :)

                Kann ich Dich eigentlich über die obige Mailadresse erreichen?

                Japp, die Adresse wird zwar ohne Ende mit Spam vollgemüllt, wird aber immer noch aktiv genutzt.

                Vielleicht liest man sich ja :)

                Beste Grüsse,
                    Tobias Hahner

            2. Ich hoffe, Du kannst damit was anfangen…

              Hi,

              ich hab mir das auch angeschaut. Sieht gut aus. Darf ich das auch benutzen?

              Und wie muss ich das erweitern, um auch Textareas und inputfelder zu benutzen zu können? Ich hab das selber versucht umzubauen. Aber ich habs nicht geschaft. Entweder Textarea hab ich geschaft oder input. Und bei Textarea fehlten dann die Zeilenumbrüche, wenn der Text als html angezeigt wird.

              Kannst Du mir dabei helfen?

              Vg, Friedhelm

              1. Hallihallo!

                ich hab mir das auch angeschaut. Sieht gut aus. Darf ich das auch benutzen?

                Natürlich, das darf Jeder. Ich halte meine Umsetzung jetzt auch nicht für sooo super, dass ich da irgendwelche Ansprüche stellen wollte...

                Und wie muss ich das erweitern, um auch Textareas und inputfelder zu benutzen zu können? Ich hab das selber versucht umzubauen. Aber ich habs nicht geschaft. Entweder Textarea hab ich geschaft oder input.

                Man müsste irgendwie der Funktion sagen, ob sie nun ein Input-Feld oder eine Textarea erzeugen soll. Spontan würde mir da einfallen, das über Klassen zu machen, z.B. class="einzeilig" und class="mehrzeilig" im entsprechenden Span- Element.

                Und bei Textarea fehlten dann die Zeilenumbrüche, wenn der Text als html angezeigt wird.

                Dazu müsste man "eigentlich" nur die Umbrüche (Schnellschuss: ich würde mal sagen die Zeichenfolge \r\n, ist aber OS-abhängig, glaube ich) in einen HTML- Zeilenumbruch (<br>, oder <br />, je nachdem) umwandeln. Dafür gibt es die Javascript- Methode replace. Von der verlinkten Seite aus führt auch ein Link zum RegExp- Objekt, welches Du dafür brauchst.

                Kannst Du mir dabei helfen?

                Ich hoffe, das war Hilfe genug :)

                Beste Grüsse,
                    Tobias Hahner

                1. Hi,

                  das über Klassen zu machen, z.B. class="einzeilig" und class="mehrzeilig" im entsprechenden Span- Element.

                  Super Idee und das krieg ich auch hin glaub ich.

                  Dazu müsste man "eigentlich" nur die Umbrüche (Schnellschuss: ich würde mal sagen die Zeichenfolge \r\n, ist aber OS-abhängig, glaube ich) in einen HTML- Zeilenumbruch (<br>, oder <br />, je nachdem) umwandeln.

                  Hab ich auch gedacht und deine Funktion umgebaut. Aber anstatt den Zeilenumbruch zu machen, wird wirklich ein <br> eingefügt :-( Hab ich das was falsch gemacht? Oder es an der falschen Stelle eingefügt?

                    
                  function attachInputField() {  
                  // blende das span aus:  
                  helpers.elem.css('display','none');  
                  // hänge ein input mit dem im span enthaltenen Text hinter das span  
                  //helpers.inp = $('<input class="temp" type="text" value="'+helpers.text+'">').insertAfter(helpers.elem);  
                  helpers.inp = $('<textarea rows="3" cols="100">'+helpers.text+'</textarea>').insertAfter(helpers.elem);  
                  // gib dem input einen onblur- eventhandler (s.weiter unten)  
                  helpers.inp.blur(function(){  
                  helpers.newtext = helpers.inp.val();  
                  helpers.newtext = helpers.newtext.replace(/(\r\n)|(\r)|(\n)/g, '<br>');  
                  detachInputField();  
                  });  
                  helpers.inp.focus();  
                  }  
                  
                  

                  Vg, Friedhelm

                  P.S: Danke das ich deinen code benutzen darf!

                  1. Hallihallo!

                    Dazu müsste man "eigentlich" nur die Umbrüche (Schnellschuss: ich würde mal sagen die Zeichenfolge \r\n, ist aber OS-abhängig, glaube ich) in einen HTML- Zeilenumbruch (<br>, oder <br />, je nachdem) umwandeln.

                    Hab ich auch gedacht und deine Funktion umgebaut. Aber anstatt den Zeilenumbruch zu machen, wird wirklich ein <br> eingefügt :-( Hab ich das was falsch gemacht? Oder es an der falschen Stelle eingefügt?

                    Nein, hast Du nicht. Der "Fehler" liegt an anderer Stelle:

                    function attachInputField() {
                    // blende das span aus:
                    helpers.elem.css('display','none');
                    // hänge ein input mit dem im span enthaltenen Text hinter das span
                    //helpers.inp = $('<input class="temp" type="text" value="'+helpers.text+'">').insertAfter(helpers.elem);
                    helpers.inp = $('<textarea rows="3" cols="100">'+helpers.text+'</textarea>').insertAfter(helpers.elem);
                    // gib dem input einen onblur- eventhandler (s.weiter unten)
                    helpers.inp.blur(function(){
                    helpers.newtext = helpers.inp.val();
                    helpers.newtext = helpers.newtext.replace(/(\r\n)|(\r)|(\n)/g, '<br>');

                    // und zwar hier:

                    detachInputField();
                    });
                    helpers.inp.focus();
                    }

                      
                    In der Funktion detachInputFields (die Du für die Textareas ja auch modifizieren musst), gibt es die Zeile  
                    ~~~javascript
                      
                    // setze den neuen Text in das span ein  
                    helpers.elem.text(helpers.newtext);  
                    
                    

                    Der "Fehler" liegt wohl nun darin, dass die Methode "text" den Text, den sie einsetzen soll, auch wirklich als Text behandelt. Das ist eigentlich kein Fehler, sondern es werden die Regeln des Kontextwechsels beachtet.

                    Um HTML- Code in ein Element einzusetzen, gibt es eine ganz ähnliche Funktion. Ändere einfach die Zeile um in

                      
                    helpers.elem.html(helpers.newtext);  
                    
                    

                    Sei Dir aber dabei der Gefahren bewusst! Auf diese Weise ist es möglich, quasi beliebigen Code, auch Javascript, über die Textarea einzuschleusen!
                    Du musst also tierisch aufpassen, dass da kein Schindluder getrieben werden kann.

                    Vereinfacht gesagt, musst Du dafür sorgen, dass eventuell eingegebener HTML-Code nicht aus der Textarea einfach übernommen werden darf. In PHP wäre die geeignete Funktion dafür htmlspecialchars. Leider gibt es die von Haus aus in Javascript nicht, aber da wir ja eh schon JQuery benutzen, kann man sich die eben noch ungewünschten Eigenschaften von text() zunutze machen:

                      
                    function htmlspecialchars(irgendwas) {  
                    // erzeuge ein Dummy- Element, um die Maskierungseigenschaften von .text() benutzen zu können. Extrahiere anschliessend den umgewandelten Inhalt und gib ihn zurück  
                    return $('<span>').text(irgendwas).html();  
                    }  
                    
                    

                    Bedenke, dass erst nach der Verwendung dieser htmlspecialchars- Funktion die Zeilenumbrüche ersetzt werden dürfen, sonst bist Du wieder da, wo Du eben noch warst ;)

                    Beste Grüsse,
                        Tobias Hahner

                    1. Hi Tobias,

                      Der "Fehler" liegt wohl nun darin, dass die Methode "text" den Text, den sie einsetzen soll, auch wirklich als Text behandelt. Das ist eigentlich kein Fehler, sondern es werden die Regeln des Kontextwechsels beachtet.

                      Das wußte ich nicht. Ich bin Javascript-Newbie.

                      Sei Dir aber dabei der Gefahren bewusst! Auf diese Weise ist es möglich, quasi beliebigen Code, auch Javascript, über die Textarea einzuschleusen!
                      Du musst also tierisch aufpassen, dass da kein Schindluder getrieben werden kann.

                      Bist Du da sicher?
                      Es geht doch hierbei nur und ausschließlich um die clientseitige Umsetzung des Codes.
                      Sobald der User das an den Server schickt und es in der Datenbank landet, wird dochh vor dem nächsten serverseitigem Einsetzen des Inhalts alles wieder durch die php seitige htmlspecialchars funktion gejagt.

                      Soll heißen, wer auch immer meint, hier die verteufelsten Javascripte in die Textarea zu schreiben, macht max. seinen eigenen Client Probleme, aber nicht meiner Anwendung oder gar anderen Usern?

                      Oder übersehe ich da etwas?

                      Grüße,

                      Friedhelm

                      1. Hi Tobias,

                        noch eine Frage: An welcher Stelle wandel ich die <br> wieder in \r\n um, damit beim Klick auf den html-Text auch in der Textarea die Zeilenumbrüche wieder angezeit werden?

                        Grüße, Friedhelm

                        1. und noch eine:

                          Ich möchte das nicht per Ajax übertragen. Also muß ich meine Textareas ja mit Namen oder Namen+ID versehen, um sie im action-script im $_POST-Array zu erhalten. Wie mache ich das hier?

                          Grüße, Friedhelm

  2. Grüße,
    warum? wieso muss es editierbar UND kein inputfeld sein?
    MFG
    bleicher

    --
    __________________________-

    FirefoxMyth
    1. warum? wieso muss es editierbar UND kein inputfeld sein?

      Hi bleicher,

      weil inputfelder doof aussehen ;-)

      Grüße, Leif

      1. Grüße,

        weil inputfelder doof aussehen ;-)

        CSS?
        MFG
        bleicher

        --
        __________________________-

        FirefoxMyth
        1. CSS?

          ...macht aus einem Inputfeld nichts anderes als ein ggf. buntes, formatiertes Inputfeld ;-)
          Das passt aber nicht in mein Formulardesign. <-- (viel Information auf relativ wenig Platz. Zu viele Inputfelder würden dort den User zu sehr verwirren)

          Gruß, Leif

          1. Hallo,

            Das passt aber nicht in mein Formulardesign. <-- (viel Information auf relativ wenig Platz. Zu viele Inputfelder würden dort den User zu sehr verwirren)

            Ich würde die Seite gerne mal sehen - ich kann mir absolut nicht vorstellen, wie sowas aussehen soll. Wieso gehen Input-Felder nicht und andere Elemente schon? Bei gleicher Information, die angezeigt werden soll, kann doch nicht das Input-Feld zu mehr verbrauchtem Platz oder Unübersichtlichkeit führen. Oder doch?

            Für mich ist der einzige Grund solche Inhalte nicht (direkt) mit Inputs bearbeiten zu lassen, wenn es sich um HTML-Code handelt der im WYSIWYG-Modus bearbeitet wird. Meinst du etwa sowas?
            Dazu nutze ich TinyMCE und das klappt wunderbar...

            Gruß
            Alex

            1. Hallihallo!

              Ich würde die Seite gerne mal sehen - ich kann mir absolut nicht vorstellen, wie sowas aussehen soll. Wieso gehen Input-Felder nicht und andere Elemente schon? Bei gleicher Information, die angezeigt werden soll, kann doch nicht das Input-Feld zu mehr verbrauchtem Platz oder Unübersichtlichkeit führen. Oder doch?

              Ein denkbarer Fall wäre zum Beispiel (so ist es bei mir) Folgender:
              In einer Lagerverwaltung kann der Nutzer zum jedem Artikel alle denkbaren Details anzeigen lassen. Hauptaugenmerk ist hierbei auf _anzeigen lassen_.
              Bei entsprechender Berechtigung darf er sie auch ändern, aber das soll auf keinen Fall aus Versehen passieren. (etwa, weil mal wieder etwas auf der Tastatur liegt).
              Ausserdem ist ein durchgehend gleich formatierter Text wesentlich besser geeignet, um auf die Schnelle die gesuchten Informationen zu finden.

              Also stellt man erstmal Alles ganz normal dar, und erst wenn der Nutzer aktiv auf eine Information klickt (oder doppelklickt, gibts ja auch), kann er diese Information ändern. (Sofern er denn die Berechtigung dazu hat)

              Die tägliche Arbeit mit dem System und das Feedback meiner Kollegen sagt mir, dass diese Art der Umsetzung gut ist und genau zu den Anforderungen passt.

              Beste Grüsse,
                  Tobias Hahner

              1. Hallo,

                danke für diene Antwort - klingt interessant.

                Aber auch, wenn man soetwas realisieren will, kann man mit Inputfeldern  arbeiten. Man kann sie entweder gleich als Input darstellen aber bis zum Doppelklick deaktiviert lassen, oder man stellst sie als normaler Tabelleninhalt (oder so ähnlich) dar und lässt diesen per Doppelklick in ein Inputfeld setzen - ich sehe da nicht so das Problem.

                Ich nutze in meinem Prokekt auch sowas ähnliches. Jedoch mit weniger komplexen Inhalten - klappt wunderbar.

                Gruß
                Alex

                1. Habe gerade dein Beispiel im anderen Antwort-Posting gesehen - das ist ja doch so wie ich es hier auch beschrieben habe.

                  Schaut gut aus.

              2. Ein denkbarer Fall wäre zum Beispiel (so ist es bei mir) Folgender:
                In einer Lagerverwaltung kann der Nutzer zum jedem Artikel alle denkbaren Details anzeigen lassen. Hauptaugenmerk ist hierbei auf _anzeigen lassen_.
                Bei entsprechender Berechtigung darf er sie auch ändern, aber das soll auf keinen Fall aus Versehen passieren. (etwa, weil mal wieder etwas auf der Tastatur liegt).

                Absolut meine Denkweise. Und auch bei mir hat es etwas mit Berechtigungen zu tun und, dass das Designbild immer dasselbe sein soll. (egal, ob der User berechtigt ist oder nicht)

                Also stellt man erstmal Alles ganz normal dar, und erst wenn der Nutzer aktiv auf eine Information klickt (oder doppelklickt, gibts ja auch), kann er diese Information ändern. (Sofern er denn die Berechtigung dazu hat)

                So ist es. :-)

                Grüße, Leif

          2. Grüße,
            borderloses input ist optisch von einem Textknoten nicht zu unterscheiden, wo ist das Problem?
            MFG
            bleicher

            --
            __________________________-

            FirefoxMyth
            1. Grüße,
              borderloses input ist optisch von einem Textknoten nicht zu unterscheiden, wo ist das Problem?

              Hi Bleicher,

              1. Es ist zu unterscheiden. Alleine, wenn der Value zu lang ist und daher Scrollbalken erscheinen.

              2. Text wächst innerhalb einer Tabelle in der Breite und Höhe einfach mit. Textareas machen das nicht.

              3. Selbst wenn es nicht zu unterscheiden wäre: Woher soll der User dann wissen, dass er das editieren kann?

              4. Wenn Du auf die ersten 3 Fragen sinnvolle Antworten hast, beschäftige ich mich gerne mit Deiner Alternative. Ansonsten finde ich die Idee besser, aus einem Text clientmäßig erst eine Textarea zu machen.

              Grüße, Leif

              1. Grüße,

                1. Es ist zu unterscheiden. Alleine, wenn der Value zu lang ist und daher Scrollbalken erscheinen.

                wenn du shcon bei JS bist - pass die länge an

                1. Text wächst innerhalb einer Tabelle in der Breite und Höhe einfach mit. Textareas machen das nicht.

                100% width?

                1. Selbst wenn es nicht zu unterscheiden wäre: Woher soll der User dann wissen, dass er das editieren kann?

                woher soll er das bei einem sonstigen elemtn wissen?
                MFG
                bleicher

                --
                __________________________-

                FirefoxMyth
                1. wenn du shcon bei JS bist - pass die länge an

                  Text kürzen? Oder erst Text einlesen, Länge messen, Zeilenumbrüche zählen und dann die Textarea darauf anpassen? Was ein Aufstand...

                  1. Text wächst innerhalb einer Tabelle in der Breite und Höhe einfach mit. Textareas machen das nicht.

                  100% width?

                  Ok.

                  1. Selbst wenn es nicht zu unterscheiden wäre: Woher soll der User dann wissen, dass er das editieren kann?

                  Man könnte den Text als Link formatieren und bei Klick drauf gehts in die Textarea... aber genau das steht in der Ausgangsfrage. Das ich eben elegante Lösungen suche.

                  Und Deine Lösung finde ich bisher eher nicht sonderlich elegant. ;-)

                  Dennoch Danke für Deine Mithilfe und Grüße an Dich

                  Leif

          3. Hallo,

            warum? wieso muss es editierbar UND kein inputfeld sein?

            weil inputfelder doof aussehen ;-)

            CSS?

            ...macht aus einem Inputfeld nichts anderes als ein ggf. buntes, formatiertes Inputfeld ;-)

            Schon mal probiert? Anscheinend nicht. Nimm einem Input-Feld den Rahmen weg und schon sieht es wie ganz normaler Text aus. Von wegen bunt formatiert...

            Du hast lediglich ein Darstellungsproblem, dann löse es auch wie ein Darstellungsproblem, nämlich durch Formatierung und nicht durch ein kompliziertes Getrickse mit Scripts.

            Gruß, Don P