Javascript jquery veya form serileştirmek ve serileştirilmiş sürümü erişmek için herhangi bir çerçeve olmadan bir işlevi var mı?
Javascript jquery veya form serileştirmek ve serileştirilmiş sürümü erişmek için herhangi bir çerçeve olmadan bir işlevi var mı?
Yanıtlar:
Serileşen seri minyatür kütüphanesi bir çerçeveye dayanmaz. Bunun gibi bir şey dışında, serileştirme işlevini kendiniz uygulamanız gerekir. (1,2 kilobayt ağırlığında olsa da, neden kullanmıyorsunuz?)
case 'email':
kodun giriş bölümüne bir eklemek zorunda
That's an error
İşte saf JavaScript yaklaşımı:
var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);
Rağmen sadece POST istekleri için çalışıyor gibi görünüyor.
req.open("POST", "<your-url>");
önce kullanmak req.send(data);
zorunda kalabilirsiniz Aksi takdirde InvalidStateError: XMLHttpRequest state must be OPENED.
Firefox 66 üzerinde hata vardı. PUT gibi POST yerine PUT gibi diğer istekleri ile çalışması gerekir.
URLSearchParams
API'yı ( en son tarayıcılar ) ve FormData(formElement)
yapıcıyı ( Edge hariç en son tarayıcılar ) destekleyen tarayıcıları hedefliyorsanız , bunu kullanın:
new URLSearchParams(new FormData(formElement)).toString()
Yapıcıyı destekleyen URLSearchParams
ancak desteklemeyen tarayıcılar için FormData(formElement)
, bu FormData çoklu dolgusunu ve bu kodu kullanın (IE dışında her yerde çalışır):
new URLSearchParams(Array.from(new FormData(formElement))).toString()
Daha eski tarayıcılarda bile (örneğin IE 10) FormData çoklu dolgusunu , Array.from
gerekirse bir çoklu dolguyu ve bu kodu kullanın:
Array.from(
new FormData(formElement),
e => e.map(encodeURIComponent).join('=')
).join('&')
.toString()
gerçekten gerekli mi?
URLSearchParams
, evet. Dize dönüştürme ayrıca bir dizeye enterpolasyon yaparsanız veya bir dizeye eklerseniz örtük olarak gerçekleşir, bu durumda açık toString
çağrı gerekli değildir.
new FormData(formElement)
henüz orada desteklenmiyor mu?
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("&");
}
Kaynak: http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js
İşte TibTibs'in biraz değiştirilmiş bir versiyonu:
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, '+');
}
Devre dışı bırakılan alanlar atılır ve adlar da URL kodludur. % 20 karakterin normal ifadesinin değiştirilmesi, dizeyi döndürmeden önce yalnızca bir kez gerçekleşir.
Sorgu dizesi, jQuery'nin $ .serialize () yönteminin sonucuyla aynı biçimdedir.
form.nodeName.toLowerCase() == "form"
yerine ekleyebilirsinizform.nodeName == "FORM"
Johndave Decano'nun cevabı ile başladım.
Bu, işlevine verilen yanıtlarda belirtilen sorunlardan birkaçını düzeltmelidir.
Bir ad değeri yoksa, düğme türleri göz ardı edilir.
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);
}
Şu anda bu işlevi kullanıyorum.
<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">
POST kullanarak json biçiminde "myForm" formunu göndermeniz gerekiyorsa şunları yapabilirsiniz:
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)
});
İkinci satır aşağıdaki gibi bir diziden dönüştürülür:
[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]
... normal bir nesneye, örneğin:
{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }
... bu dönüşümü bir mapFn'yi Array.from () 'a aktararak yapar. Bu mapFn, her ["a", "b"] çiftine uygulanır ve bunları {"a": "b"} biçimine dönüştürür; böylece dizi, her birinde yalnızca bir özelliğe sahip çok sayıda nesne içerir. MapFn, çiftin ilk ve ikinci bölümlerinin adlarını almak için "yıkım" kullanır ve ayrıca mapFn tarafından döndürülen nesnede özellik adını ayarlamak için bir ES6 "ComputedPropertyName" kullanır (bu yüzden "[ x]: "x: bir şey" yerine "bir şey".
Bu tek özellik nesnelerinin tümü daha sonra tüm tek özellik nesnelerini tüm özelliklere sahip tek bir nesnede birleştiren Object.assign () işlevinin bağımsız değişkenlerine geçirilir.
Array.from (): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from
Parametrelerde yıkım: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/
Hesaplanan özellik adları hakkında daha fazla bilgi: Bir JavaScript nesnesi değişmezinde özellik adı olarak değişken mi?
Tüm tarayıcılarda çalışır.
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 );
}
Bunun gibi kullanmak için:
var dataToSend = document.querySelector("form").serialize();
Umarım yardımcı olmuşumdur.
Bir olaydaki girişleri serileştirmek istiyorsanız. İşte kullandığım saf bir JavaScript yaklaşımı.
// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
data[input.name] = input.value;
});
Veriler, girdilerin bir JavaScript nesnesi olacaktır.
@ SimonSteinberger'in kodunun daha az değişken kullanan ve forEach
döngülerin hızından yararlanan ( for
s'den biraz daha hızlı olan ) yeniden düzenlenmiş bir sürümü
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, '+');
}
TibTibs'in cevabını okunması çok daha açık bir şeye yeniden düzenledim. 80 karakter genişliği ve birkaç yorum nedeniyle biraz daha uzun.
Ayrıca, boş alan adlarını ve boş değerleri yok sayar.
// 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 };
(düzenleme yapıldığı gibi) Bunun arkasındaki nokta, eğer bir form gibi, seri hale getirmeyi tetikleyen olayı geçmektir "gönder" etkinliği veya bir düğmenin "tıklaması". Bir formun gönderilmek üzere birden çok düğmesi varsa, yalnızca olayı tetikleyen düğmenin değerini hesaba katmak ve diğerlerini yoksaymak istersiniz. Ben 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);
@Moison yanıt ve MDN formData girişleri () yöntem yakaladım ki şöyle dedi:
FormData.entries () yöntemi, bu nesnede bulunan tüm anahtar / değer çiftlerinden geçmesine izin veren bir yineleyici döndürür. Her çiftin anahtarı USVString nesnesidir; değer bir USVString veya bir Blob.
ancak tek sorun mobil tarayıcı (android ve safari desteklenmiyor) ve IE ve Safari masaüstünün de
ama temelde benim yaklaşımım:
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'
};
kod burada bulunabilir
JavaScript azaltma işlevinin kullanılması, IE9> dahil tüm tarayıcılar için bir hile yapmalıdır:
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;
},[]);
Canlı örnek feryat.
Umarım bu işe yarar
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;
}
David Lemon'un cevabını geliştirmek.
Bu, form verilerini JSON'a dönüştürür ve formu bir veri nesnesinden ayarlamanızı sağlar.
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>
Bu çok basit bir fonksiyonla aşağıdaki gibi yapılabilir
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>
İşte saf JavaScript yaklaşımı:
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;
}
Hata ayıklama amacıyla bu size yardımcı olabilir:
function print_form_data(form) {
const form_data = new FormData(form);
for (const item of form_data.entries()) {
console.log(item);
}
return false;
}
Delirmiş olabilirim ama bu cevapları ciddi şekilde şişkin buluyorum. İşte benim çözümüm
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
, hepsi için başarısız olur