Formular serialisieren Javascript (kein Framework)


139

Sie fragen sich, ob es in Javascript eine Funktion ohne JQuery oder ein Framework gibt, mit der ich das Formular serialisieren und auf die serialisierte Version zugreifen kann?


1
Was meinst du mit "Zugriff auf die Serialisierungsversion"? Ich habe ein Skript entwickelt, das keine Abhängigkeiten von Drittanbietern aufweist, die das HTML-Formular in ein JSON-ähnliches Objekt konvertieren können, das mehrdimensional ist: github.com/serbanghita/formToObject - wenn es hilft, eine Antwort zu
löschen

Antworten:


39

Die Miniaturbibliothek aus der Serialisierung basiert nicht auf einem Framework. Abgesehen davon müssen Sie die Serialisierungsfunktion selbst implementieren. (obwohl bei einem Gewicht von 1,2 Kilobyte, warum nicht verwenden?)


2
Das war perfekt. Aber hatte eine hinzuzufügen , case 'email':in dem Eingabeabschnitt der Code
aravind

Oh, jetzt sehe ich, Google Code funktioniert nicht ohne Javascript. Es spuckt einfachThat's an error
user1040495

3
Bitte geben Sie einen Code und nicht nur einen Link zu einer Bibliothek an. Wenn die Bibliothek Open Source ist, sollten Sie in der Lage sein, den entsprechenden Code zu kopieren.
Luke

171

Hier ist ein reiner JavaScript-Ansatz:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

Obwohl es nur für POST-Anfragen zu funktionieren scheint.

https://developer.mozilla.org/en-US/docs/Web/API/FormData


13
Beachten Sie, dass dies mehrteilig sendet, was mit einigen einfachen REST-Diensten (z. B. Federn-MongoDB) schlecht funktioniert
Jason McCarrell

Ich denke, Sie haben Recht, dass es nur mit POST-Anfragen funktioniert. Das war aus den Dokumenten nicht sofort ersichtlich.
Manisha

das funktioniert bei mir nicht. Die Form ist tief verschachtelt. Das FormData-Objekt ist leer…
Chitzui

Beachten Sie , können Sie verwenden müssen , req.open("POST", "<your-url>");bevor req.send(data);Ansonsten hatte ich den Fehler InvalidStateError: XMLHttpRequest state must be OPENED.auf Firefox 66. Es sollte auch mit anderen Anforderungen arbeiten wie PUT Sie POST mit PUT ersetzen.
Taufe

1
Denken Sie darüber nach: Wie können Sie ein FormData-Objekt mit der Methode "GET" senden? Ja, FormData funktioniert nur mit "POST".
Rex der Seltsame

88

Nur für moderne Browser

Wenn Sie auf Browser abzielen, die die URLSearchParamsAPI ( neueste Browser ) und den FormData(formElement)Konstruktor ( neueste Browser außer Edge ) unterstützen, verwenden Sie Folgendes:

new URLSearchParams(new FormData(formElement)).toString()

Überall außer IE

Verwenden Sie für Browser, die URLSearchParamsden FormData(formElement)Konstruktor unterstützen, aber nicht den Konstruktor, diese FormData-Polyfüllung und diesen Code (funktioniert überall außer im Internet Explorer ):

new URLSearchParams(Array.from(new FormData(formElement))).toString()

Beispiel

Kompatibel mit IE 10

Verwenden Sie für noch ältere Browser (z. B. IE 10) die FormData-Polyfüllung , Array.fromggf. eine Polyfüllung , und diesen Code:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')

Ist .toString()das hier wirklich notwendig?
Ollie Williams

1
Wenn Sie einen String wollen und nicht URLSearchParams, dann ja. Die Konvertierung von Zeichenfolgen erfolgt implizit auch, wenn Sie sie interpolieren oder zu einer Zeichenfolge hinzufügen. In diesem Fall ist der explizite toStringAufruf nicht erforderlich.
Glebm


Welchen Fehler erhalten Sie und um welche Version von Safari handelt es sich? Vielleicht new FormData(formElement)wird dort noch nicht unterstützt?
Glebm

@glebm Ja, es wird in Safari nicht unterstützt. Haben Sie eine andere Lösung gefunden?
RishiAgar

34
function serialize (form) {
    if (!form || form.nodeName !== "FORM") {
            return;
    }
    var i, j, q = [];
    for (i = form.elements.length - 1; i >= 0; i = i - 1) {
        if (form.elements[i].name === "") {
            continue;
        }
        switch (form.elements[i].nodeName) {
            case 'INPUT':
                switch (form.elements[i].type) {
                    case 'text':
                    case 'tel':
                    case 'email':
                    case 'hidden':
                    case 'password':
                    case 'button':
                    case 'reset':
                    case 'submit':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'checkbox':
                    case 'radio':
                        if (form.elements[i].checked) {
                                q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        }                                               
                        break;
                }
                break;
                case 'file':
                break; 
            case 'TEXTAREA':
                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                    break;
            case 'SELECT':
                switch (form.elements[i].type) {
                    case 'select-one':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'select-multiple':
                        for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
                            if (form.elements[i].options[j].selected) {
                                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
                            }
                        }
                        break;
                }
                break;
            case 'BUTTON':
                switch (form.elements[i].type) {
                    case 'reset':
                    case 'submit':
                    case 'button':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                }
                break;
            }
        }
    return q.join("&");
}

Quelle: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js


1
Diese Serialisierung scheint nicht mit der Standardformularserialisierung kompatibel zu sein, bei der Leerzeichen durch "+" dargestellt werden. Das obige verwendet nur encodeURIComponent , die den Speicherplatz als "% 20" codiert. Wenn Konformität erforderlich ist, kann am Ende ein regulärer Ausdruck verwendet werden, um "% 20" vor der Übertragung in "+" umzuwandeln.
RobG

3
Ich habe eine solche modifizierte Version zu gist.github.com/brettz9/7147458 hinzugefügt (mit einigen anderen Verbesserungen)
Brett Zamir

3
Senden-Schaltflächen sollten nicht unbedingt gesendet werden, Reset-Schaltflächen sollten niemals gesendet werden und Schaltflächen nur dort, wo sie zum Senden verwendet werden und in diesem Fall als Senden-Schaltfläche behandelt werden. Siehe HTML5 4.10.22 Formularübermittlung .
RobG

Serialisierungstyp E-Mail nicht serialisieren.
Ivan

24

Hier ist eine leicht modifizierte Version von TibTibs:

function serialize(form) {
    var field, s = [];
    if (typeof form == 'object' && form.nodeName == "FORM") {
        var len = form.elements.length;
        for (i=0; i<len; i++) {
            field = form.elements[i];
            if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
                if (field.type == 'select-multiple') {
                    for (j=form.elements[i].options.length-1; j>=0; j--) {
                        if(field.options[j].selected)
                            s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[j].value);
                    }
                } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
                    s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value);
                }
            }
        }
    }
    return s.join('&').replace(/%20/g, '+');
}

Deaktivierte Felder werden verworfen und Namen werden auch URL-codiert. Die Regex-Ersetzung von% 20 Zeichen erfolgt nur einmal, bevor die Zeichenfolge zurückgegeben wird.

Die Abfragezeichenfolge hat dieselbe Form wie das Ergebnis der $ .serialize () -Methode von jQuery.


6
+1, um sich die Zeit zu nehmen, den Code zu verbessern. Ich genieße es, wenn Leute meine Fehler finden, da dies eine gute Lernmöglichkeit ist. +1, damit es auch gut aussieht. -1, weil ich nicht +2 = (
TibTibs

1
Sie könnten form.nodeName.toLowerCase() == "form"anstelle vonform.nodeName == "FORM"
StefanNch

12

Ich begann mit der Antwort von Johndave Decano.

Dies sollte einige der Probleme beheben, die in den Antworten auf seine Funktion erwähnt wurden.

  1. Ersetzen Sie% 20 durch ein + Symbol.
  2. Senden / Schaltflächentypen werden nur gesendet, wenn sie zum Senden des Formulars angeklickt wurden.
  3. Reset-Tasten werden ignoriert.
  4. Der Code schien mir redundant zu sein, da er unabhängig von den Feldtypen im Wesentlichen dasselbe tut. Ganz zu schweigen von der Inkompatibilität mit HTML5-Feldtypen wie 'tel' und 'email'. Daher habe ich die meisten Details mit den switch-Anweisungen entfernt.

Schaltflächentypen werden weiterhin ignoriert, wenn sie keinen Namenswert haben.

function serialize(form, evt){
    var evt    = evt || window.event;
    evt.target = evt.target || evt.srcElement || null;
    var field, query='';
    if(typeof form == 'object' && form.nodeName == "FORM"){
        for(i=form.elements.length-1; i>=0; i--){
            field = form.elements[i];
            if(field.name && field.type != 'file' && field.type != 'reset'){
                if(field.type == 'select-multiple'){
                    for(j=form.elements[i].options.length-1; j>=0; j--){
                        if(field.options[j].selected){
                            query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
                        }
                    }
                }
                else{
                    if((field.type != 'submit' && field.type != 'button') || evt.target == field){
                        if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
                            query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
                        }   
                    }
                }
            }
        }
    }
    return query.substr(1);
}

So benutze ich derzeit diese Funktion.

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">

6
+1 für den schön überarbeiteten Code. -1 zum Ignorieren deaktivierter Felder, die nicht in der Abfragezeichenfolge erscheinen sollten. +1 für die sehr elegante for-Anweisung, die ein wiederholtes Zählen von Formularelementen vermeidet. Gesamt: +1 :-) Danke!
Simon Steinberger

Gute Anmerkung zu den deaktivierten Feldern, ich bin kürzlich mit einer neuen Funktion darauf gestoßen, die ich geschrieben habe. +1 an euch beide, weil ich gerne lustige Kommentare lese. :)
TibTibs

11

Wenn Sie das Formular "myForm" mit POST im JSON-Format senden müssen, haben Sie folgende Möglichkeiten:

const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
  method: 'POST',
  body: JSON.stringify(json)
});

Die zweite Zeile konvertiert aus einem Array wie:

[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]

... in ein reguläres Objekt, wie:

{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }

... führt diese Konvertierung durch, indem ein mapFn an Array.from () übergeben wird. Diese mapFn wird auf jedes ["a", "b"] Paar angewendet und konvertiert sie in {"a": "b"}, sodass das Array viele Objekte mit jeweils nur einer Eigenschaft enthält. MapFn verwendet "destructuring", um Namen des ersten und zweiten Teils des Paares abzurufen, und es verwendet auch einen ES6 "ComputedPropertyName", um den Eigenschaftsnamen in dem von mapFn zurückgegebenen Objekt festzulegen (aus diesem Grund heißt es "[] x]: etwas "statt nur" x: etwas ".

Alle diese Objekte mit einzelnen Eigenschaften werden dann an Argumente der Funktion Object.assign () übergeben, mit der alle Objekte mit einzelnen Eigenschaften zu einem einzigen Objekt mit allen Eigenschaften zusammengeführt werden.

Array.from (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Destrukturierung in Parametern: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

Mehr zu berechneten Eigenschaftsnamen hier: Variable als Eigenschaftsname in einem JavaScript-Objektliteral?


Es funktioniert für mich, auch wenn ich die zweite Zeile nicht verstehe. Können Sie bitte weitere Informationen dazu geben?
Espoir Murhabazi

Schöne Antwort mit Spread-Operator und nativen Object- und Array-Methoden.
Vinny Fonseca

Beachten Sie, dass dieser Ansatz in IE (.entries ()) nicht unterstützt wird
Typ

Die MDN-Seite für Object.entries () enthält eine kurze Polyfüllung, die Sie für den IE verwenden können: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…, aber der IE unterstützt auch den Spread-Operator nicht.
Molsson

Sie können das Formular mit der neuen Methode Object.fromEntries (neue FormData (myFormElement)) serialisieren.
Miguel Savignano

10

Funktioniert in allen Browsern.

const formSerialize = formElement => {
  const values = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    values[inputs[i].name] = inputs[i].value;
  }
  return values;
}

const dumpValues = form => () => {
  
  const r = formSerialize(form);
  console.log(r);
  console.log(JSON.stringify(r));
}

const form = document.querySelector('form');

dumpValues(form)();

form.addEventListener('change',dumpValues(form));
<form action="/my-handling-form-page" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name" value="John">
  </div>
  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_mail" value="john@jonhson.j">
  </div>
  <div>
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div>
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message">Hello My Friend</textarea>
  </div>
</form>


Ich nehme an, der Autor hat nach einer Serialisierung in URI gefragt.
Jaskmar

Ich würde gerne sehen, dass dies für Formulare mit mehreren Auswahloptionen funktioniert.
Zach Smith

@ ZachSmith Es hat bereits funktioniert, aber ich habe ein Beispiel hinzugefügt, damit Sie es überprüfen können
David Lemon

8
HTMLElement.prototype.serialize = function(){
    var obj = {};
    var elements = this.querySelectorAll( "input, select, textarea" );
    for( var i = 0; i < elements.length; ++i ) {
        var element = elements[i];
        var name = element.name;
        var value = element.value;

        if( name ) {
            obj[ name ] = value;
        }
    }
    return JSON.stringify( obj );
}

So verwenden:

var dataToSend = document.querySelector("form").serialize();

Ich hoffe ich habe geholfen.


3
Funktioniert nicht mit Kontrollkästchen. Hier müssen Sie den Eingabetyp explizit überprüfen.
Adrian Preuß

5

Wenn Sie die Eingaben für ein Ereignis serialisieren möchten. Hier ist ein reiner JavaScript-Ansatz, den ich verwende.

// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
  data[input.name] = input.value;
});

Daten sind ein JavaScript-Objekt der Eingaben.


2
Dies sollte bei den meisten Elementen funktionieren. Auf keinen Fall Textarea / Select, aber
Jaggedsoft

Ist das Slice.Call dasselbe wie Array.from?
user1040495

5

Eine überarbeitete Version von @ SimonSteinbergers Code, die weniger Variablen verwendet und die Geschwindigkeit von forEachSchleifen nutzt (die etwas schneller als fors sind)

function serialize(form) {
    var result = [];
    if (typeof form === 'object' && form.nodeName === 'FORM')
        Array.prototype.slice.call(form.elements).forEach(function(control) {
            if (
                control.name && 
                !control.disabled && 
                ['file', 'reset', 'submit', 'button'].indexOf(control.type) === -1
            )
                if (control.type === 'select-multiple')
                    Array.prototype.slice.call(control.options).forEach(function(option) {
                        if (option.selected) 
                            result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(option.value));
                    });
                else if (
                    ['checkbox', 'radio'].indexOf(control.type) === -1 || 
                    control.checked
                ) result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
        });
        return result.join('&').replace(/%20/g, '+');
}

3

Ich habe TibTibs Antwort in etwas umgestaltet, das viel klarer zu lesen ist. Aufgrund der Breite von 80 Zeichen und einiger Kommentare ist es etwas länger.

Außerdem werden leere Feldnamen und leere Werte ignoriert.

// Serialize the specified form into a query string.
//
// Returns a blank string if +form+ is not actually a form element.
function $serialize(form, evt) {
  if(typeof(form) !== 'object' && form.nodeName !== "FORM")
    return '';

  var evt    = evt || window.event || { target: null };
  evt.target = evt.target || evt.srcElement || null;
  var field, query = '';

  // Transform a form field into a query-string-friendly
  // serialized form.
  //
  // [NOTE]: Replaces blank spaces from its standard '%20' representation
  //         into the non-standard (though widely used) '+'.
  var encode = function(field, name) {
    if (field.disabled) return '';

    return '&' + (name || field.name) + '=' +
           encodeURIComponent(field.value).replace(/%20/g,'+');
  }

  // Fields without names can't be serialized.
  var hasName = function(el) {
    return (el.name && el.name.length > 0)
  }

  // Ignore the usual suspects: file inputs, reset buttons,
  // buttons that did not submit the form and unchecked
  // radio buttons and checkboxes.
  var ignorableField = function(el, evt) {
    return ((el.type == 'file' || el.type == 'reset')
        || ((el.type == 'submit' || el.type == 'button') && evt.target != el)
        || ((el.type == 'checkbox' || el.type == 'radio') && !el.checked))
  }

  var parseMultiSelect = function(field) {
    var q = '';

    for (var j=field.options.length-1; j>=0; j--) {
      if (field.options[j].selected) {
        q += encode(field.options[j], field.name);
      }
    }

    return q;
  };

  for(i = form.elements.length - 1; i >= 0; i--) {
    field = form.elements[i];

    if (!hasName(field) || field.value == '' || ignorableField(field, evt))
      continue;

    query += (field.type == 'select-multiple') ? parseMultiSelect(field)
                                               : encode(field);
  }

  return (query.length == 0) ? '' : query.substr(1);
}

Ich habe dies direkt in meine App kopiert und Mehrfachauswahl scheint nicht zu funktionieren (die Werte sind dupliziert)
anastymisch

@anastymous Danke für den Fang, es wurde behoben.
Brian Edmonds

Hallo Brian, wofür ist evt ? und was soll ich dafür geben? Firefox sagt mir, dass es nicht definiert ist.
anastymous

Hallo Anastym, nochmals vielen Dank für den Haken, es sollte behoben werden, indem die Zuweisung auf evt geändert wird evt = evt || window.event || { target: null };(wie bei der Bearbeitung). Der Punkt dahinter besteht darin, das Ereignis zu übergeben, das die Serialisierung ausgelöst hat, falls es eines gibt, wie z. B. ein Formular "Submit" -Ereignis oder "Klick" einer Schaltfläche. Wenn ein Formular mehrere Schaltflächen zum Senden enthält, möchten Sie nur den Wert der Schaltfläche berücksichtigen, die das Ereignis ausgelöst hat, und die anderen ignorieren. Ich habe ein sehr rudimentäres Beispiel für dieses Verhalten auf dump.bedmonds.net/serialize-js
Brian Edmonds

2
  // supports IE8 and IE9 
  function serialize(form) {
    var inputs = form.elements;
    var array = [];
    for(i=0; i < inputs.length; i++) {
      var inputNameValue = inputs[i].name + '=' + inputs[i].value;
      array.push(inputNameValue);
    }
    return array.join('&');
  }
 //using the serialize function written above
 var form = document.getElementById("form");//get the id of your form. i am assuming the id to be named form.
 var form_data = serialize(form);
 var xhr = new XMLHttpRequest();
 xhr.send(form_data);

 //does not work with IE8 AND IE9
 var form = document.querySelector('form');
 var data = new FormData(form);
 var xhr = new XMLHttpRequest();
 xhr.send(data);

2

Ich habe die Einträge () -Methode von Formulardaten aus @moison Antwort gepackt und von MDN es wird gesagt , dass:

Die FormData.entries () -Methode gibt einen Iterator zurück, mit dem alle in diesem Objekt enthaltenen Schlüssel / Wert-Paare durchlaufen werden können. Der Schlüssel jedes Paares ist ein USVString-Objekt. Der Wert ist entweder ein USVString oder ein Blob.

Das einzige Problem ist jedoch, dass der mobile Browser (Android und Safari werden nicht unterstützt) sowie der IE und der Safari-Desktop ebenfalls vorhanden sind

aber im Grunde ist hier mein Ansatz:

let theForm =  document.getElementById("contact"); 

theForm.onsubmit = function(event) {
    event.preventDefault();

    let rawData = new FormData(theForm);
    let data = {};

   for(let pair of rawData.entries()) {
     data[pair[0]] = pair[1]; 
    }
    let contactData = JSON.stringify(data);
    console.warn(contactData);
    //here you can send a post request with content-type :'application.json'

};

Den Code finden Sie hier


2

Die Verwendung der JavaScript-Reduzierungsfunktion sollte für alle Browser, einschließlich IE9>, einen Trick darstellen:

Array.prototype.slice.call(form.elements) // convert form elements to array
    .reduce(function(acc,cur){   // reduce 
        var o = {type : cur.type, name : cur.name, value : cur.value}; // get needed keys
        if(['checkbox','radio'].indexOf(cur.type) !==-1){
            o.checked = cur.checked;
        } else if(cur.type === 'select-multiple'){
            o.value=[];
            for(i=0;i<cur.length;i++){
                o.value.push({
                    value : cur.options[i].value,
                    selected : cur.options[i].selected
                });
            }
        }
        acc.push(o);
        return acc;
 },[]);

Live Beispiel unten.


funktioniert das bei Mehrfachauswahl? Wenn ich Ihren Code verwende, wird nur das erste Element des mehrfach ausgewählten Optionswerts zurückgegeben
Zach Smith,

@ZachSmith Ich habe meine Antwort so aktualisiert, dass sie mehrere ausgewählte Elemente enthält.
Crashtestxxx

0

Ich hoffe das wird funktionieren

var serializeForm = (formElement) => {
  const formData = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    if(inputs[i].name!=="")
        formData[inputs[i].name] = inputs[i].value;
  }
  return formData;
}

0

Die Antwort von David Lemon verbessern.

Dadurch werden Formulardaten in JSON konvertiert und Sie können das Formular aus einem Datenobjekt festlegen.

const main = () => {
  const form = document.forms['info'];
  const data = {
    "user_name"       : "John",
    "user_email"      : "john@jonhson.com",
    "user_created"    : "2020-03-24",
    "user_age"        : 42,
    "user_subscribed" : true,
    "user_interests"  : "sports",
    "user_message"    : "Hello My Friend"
  };

  populateForm(form, data);
  updateJsonView(form);
  form.addEventListener('change', (e) => updateJsonView(form));
}

const getFieldValue = (field, opts) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        return field.checked;
      case 'number':
        return field.value.includes('.')
          ? parseFloat(field.value)
          : parseInt(field.value, 10);
    }
  }
  if (opts && opts[field.name] && opts[field.name].type) {
    switch (opts[field.name].type) {
      case 'int':
        return parseInt(field.value, 10);
      case 'float':
        return parseFloat(field.value);
    }
  }
  return field.value;
}

const setFieldValue = (field, value) => {
  let type = field.getAttribute('type');
  if (type) {
    switch (type) {
      case 'checkbox':
        field.checked = value;
        break;
      default:
        field.value = value;
        break;
    }
  } else {
    field.value = value;
  }
}

const extractFormData = (form, opts) => {
  return Array.from(form.elements).reduce((data, element) => {
    return Object.assign(data, { [element.name] : getFieldValue(element, opts) });
  }, {});
};

const populateForm = (form, data) => {
  return Array.from(form.elements).forEach((element) => {
    setFieldValue(element, data[element.name]);
  });
};

const updateJsonView = (form) => {
  let fieldOptions = {};
  let formData = extractFormData(form, fieldOptions);
  let serializedData = JSON.stringify(formData, null, 2);
  document.querySelector('.json-view').textContent = serializedData;
};

main();
.form-field {
  margin-bottom: 0.5em;
}

.form-field label {
  display: inline-block;
  font-weight: bold;
  width: 7em;
  vertical-align: top;
}

.json-view {
  position: absolute;
  top: 0.667em;
  right: 0.667em;
  border: thin solid grey;
  padding: 0.5em;
  white-space: pre;
  font-family: monospace;
  overflow: scroll-y;
  max-height: 100%;
}
<form name="info" action="/my-handling-form-page" method="post">
  <div class="form-field">
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name">
  </div>
  <div class="form-field">
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_email">
  </div>
  <div class="form-field">
    <label for="created">Date of Birth:</label>
    <input type="date" id="created" name="user_created">
  </div>
  <div class="form-field">
    <label for="age">Age:</label>
    <input type="number" id="age" name="user_age">
  </div>
  <div class="form-field">
    <label for="subscribe">Subscribe:</label>
    <input type="checkbox" id="subscribe" name="user_subscribed">
  </div>
  <div class="form-field">
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="user_interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div class="form-field">
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message"></textarea>
  </div>
</form>
<div class="json-view"></div>


0

Dies könnte durch eine sehr einfache Funktion wie folgt erfolgen

function serialize(form) {
        let requestArray = [];
        form.querySelectorAll('[name]').forEach((elem) => {
            requestArray.push(elem.name + '=' + elem.value);
        });
        if(requestArray.length > 0)
            return requestArray.join('&');
        else
            return false;
    }

 serialized = serialize(document.querySelector('form'))
  console.log(serialized);
<form>

  <input type='text' name='fname' value='Johne'/>
  <input type='text' name='lname' value='Doe'/>
  <input type='text' name='contact[]' value='99999999'/>
  <input type='text' name='contact[]' value='34423434345'/>

</form>


0

Hier ist ein reiner JavaScript-Ansatz:

var form = document.querySelector('form');
var data = new FormData(form);

  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
  };
  xhttp.open("POST", "<YOUR-URL>", true);
  xhttp.send(data);
}

-1
document.serializeForm = function (selector) {
     var dictionary = {};
     var form = document.querySelector(selector);
     var formdata = new FormData(form);
     var done = false;
     var iterator = formdata.entries();
     do {
         var prop = iterator.next();
         if (prop.done && !prop.value) {
             done = true;
         }
         else {
             dictionary[prop.value[0]] = prop.value[1];
         }

     } while (!done);
     return dictionary;
}

Sieht ordentlich aus, berücksichtigt aber keine Optionsfelder oder Kontrollkästchen
Yvonne Aburrow

-1

Für Debugging-Zwecke kann dies hilfreich sein:

function print_form_data(form) {
    const form_data = new FormData(form);

    for (const item of form_data.entries()) {
        console.log(item);
    }

    return false;
}

-1

Ich könnte verrückt sein, aber ich finde diese Antworten ernsthaft aufgebläht. Hier ist meine Lösung

function serialiseForm(form) {
  var input = form.getElementsByTagName("input");
  var formData = {};
  for (var i = 0; i < input.length; i++) {
    formData[input[i].name] = input[i].value;
  }
  return formData = JSON.stringify(formData);
}

Wenn Sie Ihr Formular zum Abrufen von Elementen nach Eingabetyp verwenden, schlägt dies für selectalle fehl
Zach Smith,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.