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?
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?
Antworten:
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?)
case 'email':
in dem Eingabeabschnitt der Code
That's an error
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.
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.
Wenn Sie auf Browser abzielen, die die URLSearchParams
API ( neueste Browser ) und den FormData(formElement)
Konstruktor ( neueste Browser außer Edge ) unterstützen, verwenden Sie Folgendes:
new URLSearchParams(new FormData(formElement)).toString()
Verwenden Sie für Browser, die URLSearchParams
den 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()
Verwenden Sie für noch ältere Browser (z. B. IE 10) die FormData-Polyfüllung , Array.from
ggf. eine Polyfüllung , und diesen Code:
Array.from(
new FormData(formElement),
e => e.map(encodeURIComponent).join('=')
).join('&')
.toString()
das hier wirklich notwendig?
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 toString
Aufruf nicht erforderlich.
new FormData(formElement)
wird dort noch nicht unterstützt?
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
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.
form.nodeName.toLowerCase() == "form"
anstelle vonform.nodeName == "FORM"
Ich begann mit der Antwort von Johndave Decano.
Dies sollte einige der Probleme beheben, die in den Antworten auf seine Funktion erwähnt wurden.
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))">
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?
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>
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.
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.
Eine überarbeitete Version von @ SimonSteinbergers Code, die weniger Variablen verwendet und die Geschwindigkeit von forEach
Schleifen nutzt (die etwas schneller als for
s 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, '+');
}
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);
}
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
// 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);
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
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.
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;
}
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>
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>
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);
}
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;
}
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;
}
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);
}
select
alle fehl