Ingin tahu apakah ada fungsi dalam javascript tanpa jquery atau kerangka kerja apa pun yang memungkinkan saya untuk membuat serialisasi formulir dan mengakses versi serial?
Ingin tahu apakah ada fungsi dalam javascript tanpa jquery atau kerangka kerja apa pun yang memungkinkan saya untuk membuat serialisasi formulir dan mengakses versi serial?
Jawaban:
Miniatur dari perpustakaan berseri tidak bergantung pada kerangka kerja. Selain itu, Anda harus mengimplementasikan fungsi serialisasi sendiri. (meski dengan berat 1,2 kilobyte, mengapa tidak menggunakannya?)
case 'email':
di bagian input kode
That's an error
Berikut adalah pendekatan JavaScript murni:
var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);
Meskipun tampaknya hanya berfungsi untuk permintaan POST.
req.open("POST", "<your-url>");
sebelumnya. req.send(data);
Jika tidak, saya mengalami kesalahan InvalidStateError: XMLHttpRequest state must be OPENED.
pada Firefox 66. Seharusnya bekerja dengan permintaan lain juga seperti PUT adalah Anda mengganti POST dengan PUT.
Jika Anda menargetkan browser yang mendukung URLSearchParams
API ( browser terbaru ) dan FormData(formElement)
konstruktor ( browser terbaru ), gunakan ini:
new URLSearchParams(new FormData(formElement)).toString()
Untuk browser yang mendukung URLSearchParams
tetapi bukan FormData(formElement)
konstruktornya, gunakan polyfill FormData ini dan kode ini (berfungsi di mana saja kecuali IE):
new URLSearchParams(Array.from(new FormData(formElement))).toString()
Untuk browser yang lebih lama lagi (misalnya IE 10), gunakan polyfill FormData , sebuah Array.from
polyfill jika perlu dan kode ini:
Array.from(
new FormData(formElement),
e => e.map(encodeURIComponent).join('=')
).join('&')
.toString()
benar-benar perlu di sini?
URLSearchParams
, maka ya. Konversi string juga terjadi secara implisit jika Anda menginterpolasi atau menambahkannya ke string, dalam hal ini toString
panggilan eksplisit tidak diperlukan.
new FormData(formElement)
belum didukung di sana?
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("&");
}
Sumber: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js
Ini adalah versi TibTibs 'yang sedikit dimodifikasi:
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, '+');
}
Bidang yang dinonaktifkan akan dibuang dan nama juga dikodekan URL. Penggantian ekspresi reguler dari% 20 karakter terjadi hanya sekali, sebelum mengembalikan string.
String kueri dalam bentuk yang identik dengan hasil dari metode $ .serialize () jQuery.
form.nodeName.toLowerCase() == "form"
alih-alihform.nodeName == "FORM"
Saya mulai dengan jawaban dari Johndave Decano.
Ini harus memperbaiki beberapa masalah yang disebutkan dalam membalas fungsinya.
Jenis tombol akan tetap diabaikan jika tidak memiliki nilai nama.
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);
}
Beginilah cara saya saat ini menggunakan fungsi ini.
<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
Jika Anda perlu mengirimkan formulir "myForm" menggunakan POST dalam format json, Anda dapat melakukan:
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)
});
Baris kedua dikonversi dari array seperti:
[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]
... menjadi objek biasa, seperti:
{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }
... ia melakukan konversi ini dengan meneruskan mapFn ke Array.from (). MapFn ini diterapkan ke setiap pasangan ["a", "b"] dan mengubahnya menjadi {"a": "b"} sehingga larik berisi banyak objek dengan hanya satu properti di masing-masing. MapFn menggunakan "destructuring" untuk mendapatkan nama dari bagian pertama dan kedua dari pasangan, dan juga menggunakan "ComputedPropertyName" ES6 untuk menyetel nama properti dalam objek yang dikembalikan oleh mapFn (inilah mengapa dikatakan "[ x]: sesuatu "bukan hanya" x: sesuatu ".
Semua objek properti tunggal ini kemudian dilewatkan ke dalam argumen fungsi Object.assign () yang menggabungkan semua objek properti tunggal menjadi satu objek yang memiliki semua properti.
Array.from (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Penghancuran dalam parameter: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/
Lebih lanjut tentang nama properti yang dihitung di sini: Variabel sebagai nama properti dalam literal objek JavaScript?
Bekerja di semua browser.
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 );
}
Untuk menggunakan seperti ini:
var dataToSend = document.querySelector("form").serialize();
Saya harap saya telah membantu.
Jika Anda ingin membuat serial input pada sebuah acara. Inilah pendekatan JavaScript murni yang saya gunakan.
// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
data[input.name] = input.value;
});
Data akan menjadi objek JavaScript dari input.
Versi kode @ SimonSteinberger yang difaktorkan ulang menggunakan lebih sedikit variabel dan memanfaatkan kecepatan forEach
loop (yang sedikit lebih cepat dari for
s)
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, '+');
}
Saya mengubah jawaban TibTibs menjadi sesuatu yang lebih jelas untuk dibaca. Ini sedikit lebih panjang karena lebar 80 karakter dan beberapa komentar.
Selain itu, ini mengabaikan nama bidang kosong dan nilai kosong.
// 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 };
(seperti yang telah dilakukan edit) Intinya adalah untuk melewati acara yang memicu serialisasi, jika ada, seperti formulir "kirim" acara, atau "klik" tombol. Jika formulir memiliki beberapa tombol untuk pengiriman, Anda hanya ingin memperhitungkan nilai tombol yang memicu acara dan mengabaikan yang lain. Saya telah meretas contoh yang sangat mendasar dari perilaku ini di dump.bedmonds.net/serialize-js
Ini dapat dilakukan dengan fungsi yang sangat sederhana sebagai berikut
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>
// 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);
Saya telah mengambil metode entries () formData dari jawaban @moison dan dari MDN dikatakan bahwa:
Metode FormData.entries () mengembalikan sebuah iterator yang memungkinkan untuk melewati semua pasangan kunci / nilai yang terdapat dalam objek ini. Kunci dari setiap pasangan adalah objek USVString; nilai USVString, atau Blob.
tetapi satu-satunya masalah adalah browser seluler (android dan safari tidak didukung) dan juga desktop IE dan Safari
tetapi pada dasarnya inilah pendekatan saya:
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'
};
kodenya dapat ditemukan di sini
Menggunakan fungsi pengurangan JavaScript seharusnya melakukan trik untuk semua browser, termasuk IE9>:
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;
},[]);
Contoh langsung dibawah.
Memperbaiki jawaban David Lemon.
Ini mengonversi data formulir ke JSON dan memungkinkan Anda menyetel formulir dari objek data.
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>
Saya harap ini akan berhasil
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;
}
Berikut adalah pendekatan JavaScript murni:
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;
}
Untuk tujuan debugging, ini mungkin membantu Anda:
function print_form_data(form) {
const form_data = new FormData(form);
for (const item of form_data.entries()) {
console.log(item);
}
return false;
}
Saya bisa saja gila tetapi saya menemukan jawaban ini sangat membengkak. Inilah solusi saya
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
, dsb