pl: Formularfelder auf anderes Formular übertragen

S.Thema. Also das andere Formular gibt es schon und zwar 1:1 mit denselben Feldern. Es sollen nur die Werte übertragen werden. Die Namen der Felder sollten dem genügen, es soll also nicht ID basierend sein, die aus dem Origin Formular gewonne Datenstruktur kennt die Felder dem Namen nach und die dazugehörigen Werte.

Problem dabei: Type checkbox, radio, select finden sich nur in der Datenstruktur wenn sie checked/selected sind.

Ich finde einfach keinen Ansatz, Idee?

MFG

  1. Lieber pl,

    also JavaScript?

    Du willst Deiner Beschreibung nach wohl ein Formular in einem neuen Dokument via JavaScript replizieren. Stimmt das so?

    Dann sollte das JavaScript die Struktur des Formulars und seine möglichen Optionen (Du schriebst von select-Feldern und Radiobuttons/Checkboxen) kennen, um die "übertragenen" (wie wird übertragen?) Name-Value-Paare korrekt verarbeiten zu können.

    Liebe Grüße,

    Felix Riesterer.

    1. Im Grunde genommen brauchen wir ja nur einen Iterator. Die Frage ist nur, worüber der laufen soll 😉

      Für FormData gibt es einen, für Formulare jedoch nicht. Man könnte über document.forms[1].elements iterieren und bei jedem Element in die Daten (FormData) schauen ob es einen Eintrag gibt. Nehmen wir mal an die Daten lägen in einem Array vor. Dann müsste man sich aber auch merken welcher Eintrag bereits zugewiesen wurde und welcher nicht. Und schließlich kann es ja auch mehrere textfelder mit demselben Namen geben.

      Wird schwierig.

      1. Lieber pl,

        ich habe noch immer nicht verstanden, was Du genau erreichen willst. Deine Formulierungen sind für mich nicht aussagekräftig genug, um diese Erkenntnis zu ermöglichen. Tut mir leid, dass ich Dir nicht helfen kann.

        Liebe Grüße,

        Felix Riesterer.

        1. Hier mein Ansatz der schon ganz ordentlich funktioniert. Da bin ich wohl doch auf dem richtigem Weg 😉

          1. Wenn ich einmal auf Daten übertragen habe, dann mich doch nochmals entscheide etwas anderes zu übertragen werden die Daten unten nicht aktualisiert, nur so als Hinweis.

            Für was braucht man so etwas?

            1. Wenn ich einmal auf Daten übertragen habe, dann mich doch nochmals entscheide etwas anderes zu übertragen werden die Daten unten nicht aktualisiert, nur so als Hinweis.

              Das ist richtig. Hat aber keine Auswirkung, weil der Informationsfluß nur einmal stattfindet.

              Für was braucht man so etwas?

              für xhr.responseType="document" zum Übertragen der Responsedaten in das im DOM vorliegende Formular. Ich muss noch ein bischen testen ob es alle Fälle abdeckt. Sieht bis jetzt ganz gut aus 😉

              MFG

              1. Hallo pl,

                wenn ich eine Checkbox ausmache, wird das nicht übertragen. Weil

                • du checked nur setzt, aber nicht rücksetzt
                • deine Checkboxen alle den gleichen name haben

                Rolf

                --
                sumpsi - posui - clusi
                1. Und was schlägst Du vor? MFG

                  1. Hallo pl,

                    vor dem Übertragen alle Checkboxen entchecken, oder jede Checkbox ins slice-Array, aber mit einem checked-Zustand dabei.

                    Hast Du schonmal nachgedacht über:

                    • aus sampleForm ein assoziatives Array zurückzugeben? Der Feldname ist der Key, und der Wert ist ein Array. Im Array steht an i-ter Position der Zustand des i-ten Feldes mit diesem Name. Dadurch musst Du im slice-Array nicht rumslicen, sondern kannst über Position matchen.
                    • DOM Methoden wie querySelector/querySelectorAll zu benutzen, bspw. um alle form-Elemente mit einem name-Attribut zu finden?

                    Rolf

                    --
                    sumpsi - posui - clusi
                    1. hi @Rolf B

                      vor dem Übertragen alle Checkboxen entchecken, oder jede Checkbox ins slice-Array, aber mit einem checked-Zustand dabei.

                      Wie ich schon schrieb, das ist nicht erforderlich. Weil die Datenübertragung nur einmal stattfindet und ab diesem Zeitpunkt Geschichte ist.

                      Hast Du schonmal nachgedacht über:

                      • aus sampleForm ein assoziatives Array zurückzugeben?

                      Natürlich. Die Funktionen gibt es schon.

                      • DOM Methoden wie querySelector/querySelectorAll zu benutzen, bspw. um alle form-Elemente mit einem name-Attribut zu finden?

                      Brauchen wir nicht. Weil über document.forms[index].elements iteriert wird. MFG

                      PS: Du kannst es gerne verbessern und Deine Lösung hier vorstellen.

                      1. Hallo pl,

                        Wie ich schon schrieb, das ist nicht erforderlich.

                        Ja, sorry, das hatte ich überlesen. Damit ist ein Reset implizit gegeben.

                        Rolf

                        --
                        sumpsi - posui - clusi
                        1. Wobei ich eher am Überlegen bin, checkboxn, radiobuts und selects aus der Zuweisung rauszunehmen. Für meine Freunde in der Schweiz

                          MFG

                        2. Hi @Rolf B

                          Damit ist ein Reset implizit gegeben.

                          Mit einem form.reset() ist es übrigens nicht getan. Wenn der Ausgangszustand checked ist, muss da schon ein explizites el.checked = false erfolgen. I.d.R. ändert jedoch eine Response nichts an Checkboxen.

                          MFG

                    2. moin,

                      • aus sampleForm ein assoziatives Array zurückzugeben?

                      warum nicht gleich eine FormData Instanz? .getAll() bekommt den Key und liefert ein Array mit den Werten. Damit gänge es auch und auch das Zurückschreiben des Arrays ist möglich (nach dem Löschen zutreffender Werte). Das Löschen ist insofern wichtig als daß Werte nicht mehrfach zugewiesen werden.

                      MFG

                      1. Hallo pl,

                        das Löschen ist, meine ich, ein mühsamer Umweg um einen ordentlichen Algorithmus herum.

                        Iteriere über die Keys im Formdata und suche dir pro Key alle form Elemente mit diesem Name (querySelectorAll). Dann kannst du 1:1 übertragen. Natürlich nicht bei Elementen zu deren Identifikation du den value hinzunehmen musst, aber die brauchen eh Sonderbehandlung.

                        Rolf

                        --
                        sumpsi - posui - clusi
                        1. problematische Seite

                          hi @Rolf B

                          das Löschen ist, meine ich, ein mühsamer Umweg um einen ordentlichen Algorithmus herum.

                          .shift() ist die Alternative

                          Iteriere über die Keys im Formdata

                          Nein das wäre ja genau falschherum. Denn es gibt im Ziel-Formular ja Elemente deren Values nicht in der FormData Instanz vorliegen. Ergo muss über die Elemente des Zielformulars iteriert werden.

                          Meine FormData Lösung ist unterdessen soweit funktional. Hab ich was übersehen?

                          MFG

                          1. problematische Seite

                            Hallo pl,

                            Hab ich was übersehen?

                            sieht auf Anhieb nicht so aus.

                            Nein das wäre ja genau falschherum.

                            Das dachte ich anfangs auch, aber - was machst Du denn mit Elementen des target form, deren name im FormData nicht drin ist?

                            Die sind im source form nicht enthalten. Entweder sind sie irrtümlich im target form, dann sollte der Irrtum korrigiert werden. Oder sie wurden mit Vorsatz hinzugefügt, und warum sollte man sie dann überschreiben?

                            Rolf

                            --
                            sumpsi - posui - clusi
                            1. problematische Seite

                              was machst Du denn mit Elementen des target form, deren name im FormData nicht drin ist?

                              Gar nichts. Und wie schon gesagt, die Formulare sind ja identisch, also sind auch die Namen identisch. Synopsis:

                              transform(document.forms[0], this.response.forms[0]);
                              

                              MFG

                              1. problematische Seite

                                Hallo pl,

                                Gar nichts.

                                Sag ich ja! Demnach ist es egal, woher Du die name Werte bekommst.

                                Rolf

                                --
                                sumpsi - posui - clusi
                                1. problematische Seite

                                  Die Idee einer Umkehrfunktion betrachte ich hiermit als machbar. Ich habe nun einige weitere Anwendungen damit modernisiert, progressive Enhancement wird damit zu einer einfachen Sache.

                                  Echt der Hammer 😉

                                  Fazit: Nachdenken lohnt sich immer, reicht aber nicht immer. Man muss es einfach mal machen, erst die Praxis zeigt den Mehrwert.

                                2. problematische Seite

                                  Moin,

                                  natürlich kannst Du es auch andersherum machen, nur wird das halt ziemlich umständlich. Beispielsweise könntest Du das Quellformular auf eine FormData Instanz lesen, darüber iterieren und bei jedem Eintrag das Zielformular durchlaufen um zu schauen wo die Daten hinkommen. Bei mehreren Inputfelder mit gleichem Namen oder Optionfelder unter einem Select hättest Du dann prächtig ineinandergeschachtelte Schleifenstrukturen.

                                  MFG

                                  1. problematische Seite

                                    Hallo pl,

                                    so viele Schleifen sind es gar nicht - ich habe es jetzt mal gefiddelt und der Code ist im Prinzip identisch, egal wo die Namen her kommen.

                                    Allerdings: Wenn FormData die Quelle ist, brauche ich Reset-Code, um die Eingabefelder mit den Namen, die im FormData mangels Inhalt nicht drinstehen (Checkbox, Radio, Multiselect), vorab zu leeren.

                                    Darum ist's mit dem Form als Namensgeber besser. Die Schleifentiefe ist in meiner Version trotzdem 2 bis 4 (bei Multiselect und Checkbox/Radio ist die tiefste Schleife der include-Aufruf). Das liegt aber daran, dass ich versucht habe, die Programmstruktur auf die logische Datenstruktur zu matchen, nicht auf die phyische Datenstruktur. Der gute alte Michael A. Jackson[1] hat mir das so beigebracht.

                                    Bei Dir ist sie 1 bis 3, dafür musst Du im FormData herummanipulieren und jede Menge Arraywerte shiften. Die Anzahl der durchlaufenen Schleifenkerne sollte bei Dir und mir aber gleich sein, weil wir ja gleich viele Elemente verarbeiten :). Deine innerste for-Schleife bei select und checkbox könntest Du übrigens ebenfalls durch vals.includes(...) ersetzen, und type="select" kannst Du analog zu text/textarea behandeln, da kann man einfach den value zuweisen.

                                    Fiddle: https://jsfiddle.net/Rolf_b/cgn3vwey/

                                    Rolf

                                    --
                                    sumpsi - posui - clusi

                                    1. nicht zu verwechseln mit Michael "Pädo" J. Jackson! ↩︎

                                    1. problematische Seite

                                      Sieht gut aus! Ich meine die Funktionalität, nicht den Code. Switches sind auch nicht so mein Ding. Hab ich noch nie gebraucht 😉

                                      .-.-.

          2. Lieber pl,

            na, dann frohes Schaffen!

            Liebe Grüße,

            Felix Riesterer.

            1. problematische Seite

              Anwendung siehe Link. Es dient der Entkopplung von JS in Progressive Enhancement. Echt der Hammer! MFG