bentuk serialisasi javascript (tanpa kerangka kerja)

148

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?

RussellHarrower
sumber
1
Apa yang Anda maksud dengan "akses versi serialisasi"? Saya telah mengembangkan skrip yang tidak memiliki dependensi pihak ketiga yang dapat mengubah bentuk HTML menjadi objek seperti JSON yang multidimensi: github.com/serbanghita/formToObject - jika itu membantu menjatuhkan balasan
Șerban Ghiță

Jawaban:

41

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?)

Lusitanian
sumber
2
Ini sempurna. Tetapi harus menambahkan case 'email':di bagian input kode
aravind
oh, sekarang saya mengerti, googlecode tidak berfungsi tanpa javascript. Ini hanya meludahThat's an error
pengguna1040495
3
Harap sertakan beberapa kode dan bukan hanya tautan ke perpustakaan. Jika perpustakaan adalah open source Anda harus dapat menyalin kode yang relevan.
Luke
180

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.

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

Artur Beljajev
sumber
14
Catatan, ini mengirimkan multi bagian, yang berfungsi buruk dengan beberapa layanan REST sederhana (mis. Feathers-mongoDB)
Jason McCarrell
Saya pikir Anda benar bahwa ini hanya berfungsi dengan permintaan POST. Itu tidak segera jelas dari dokumen.
manisha
ini tidak berhasil untuk saya. Formulirnya sangat bertingkat. Objek FormData kosong…
chitzui
Catatan, Anda mungkin harus menggunakan 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.
baptx
1
Pikirkan tentang itu: bagaimana Anda bisa mengirim objek FormData menggunakan metode "GET"? Ya, FormData hanya bekerja dengan "POST".
Rex the Strange
96

Hanya untuk browser modern

Jika Anda menargetkan browser yang mendukung URLSearchParamsAPI ( browser terbaru ) dan FormData(formElement)konstruktor ( browser terbaru ), gunakan ini:

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

Di mana-mana kecuali IE

Untuk browser yang mendukung URLSearchParamstetapi 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()

Contoh

Kompatibel dengan IE 10

Untuk browser yang lebih lama lagi (misalnya IE 10), gunakan polyfill FormData , sebuah Array.frompolyfill jika perlu dan kode ini:

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')
glebm
sumber
Apakah .toString()benar-benar perlu di sini?
Ollie Williams
1
Jika Anda menginginkan string dan tidak URLSearchParams, maka ya. Konversi string juga terjadi secara implisit jika Anda menginterpolasi atau menambahkannya ke string, dalam hal ini toStringpanggilan eksplisit tidak diperlukan.
glebm
One-liner tidak berfungsi untuk saya di iOS Safari mulai April 2018
jchook
Kesalahan apa yang Anda dapatkan dan versi Safari apa itu? Mungkin new FormData(formElement)belum didukung di sana?
glebm
@glebm ya tidak didukung di Safari, apakah Anda menemukan solusi lain?
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("&");
}

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

Johndave Decano
sumber
1
Serialisasi tersebut tampaknya tidak kompatibel dengan serialisasi bentuk standar, di mana spasi diwakili oleh "+". Di atas hanya menggunakan encodeURIComponent , yang akan menyandikan spasi sebagai "% 20". Jika kesesuaian diperlukan, ekspresi reguler dapat digunakan di bagian akhir untuk mengubah "% 20" menjadi "+" sebelum transmisi.
RobG
3
Saya telah menambahkan versi yang dimodifikasi ke gist.github.com/brettz9/7147458 (dengan beberapa peningkatan lainnya)
Brett Zamir
3
Tombol kirim tidak harus selalu dikirim, tombol reset tidak boleh dikirim, dan tombol hanya di tempat yang digunakan untuk mengirim dan diperlakukan sebagai tombol kirim dalam kasus itu. Lihat HTML5 4.10.22 Pengiriman formulir .
RobG
Jangan membuat email tipe input berseri.
Ivan
25

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.

Simon Steinberger
sumber
6
1 untuk meluangkan waktu untuk meningkatkan kode. Saya menikmati ketika orang menemukan kekurangan saya, karena ini adalah kesempatan belajar yang baik. 1 untuk menjaganya tetap terlihat bagus juga. -1 karena saya tidak bisa memberikan +2 = (
TibTibs
1
Anda dapat menambahkan form.nodeName.toLowerCase() == "form"alih-alihform.nodeName == "FORM"
StefanNch
12

Saya mulai dengan jawaban dari Johndave Decano.

Ini harus memperbaiki beberapa masalah yang disebutkan dalam membalas fungsinya.

  1. Gantikan% 20 dengan simbol +.
  2. Jenis Kirim / Tombol hanya akan dikirimkan jika diklik untuk mengirimkan formulir.
  3. Tombol reset akan diabaikan.
  4. Kode tersebut tampak berlebihan bagi saya karena pada dasarnya melakukan hal yang sama terlepas dari jenis bidangnya. Belum lagi ketidakcocokan dengan jenis bidang HTML5 seperti 'tel' dan 'email', jadi saya menghapus sebagian besar spesifik dengan pernyataan switch.

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))">
TibTibs
sumber
6
1 untuk kode refactored yang bagus. -1 untuk mengabaikan bidang yang dinonaktifkan, yang seharusnya tidak muncul dalam string kueri. 1 untuk pernyataan yang sangat elegan, yang menghindari penghitungan berulang elemen bentuk. Total: +1 :-) Terima kasih!
Simon Steinberger
Catatan yang bagus di bidang yang dinonaktifkan, saya menemukan ini baru-baru ini dengan fungsi baru yang saya tulis. +1 untuk Anda berdua, karena saya senang membaca komentar yang menyenangkan. :)
TibTibs
12

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?

molsson
sumber
Ini berfungsi untuk saya bahkan jika saya tidak memahami baris kedua, dapatkah Anda memberikan informasi lebih lanjut tentang itu ??
Espoir Murhabazi
Jawaban indah menggunakan operator penyebaran dan metode Objek dan Array asli.
Vinny Fonseca
Perhatikan bahwa pendekatan ini tidak didukung di IE (.entries ())
dude
Halaman MDN untuk Object.entries () memiliki polyfill pendek yang dapat Anda gunakan untuk IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… tetapi IE juga tidak mendukung operator penyebaran.
molsson
1
Anda dapat membuat serial formulir menggunakan metode baru Object.fromEntries (baru FormData (myFormElement)).
miguel savignano
9

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="[email protected]">
  </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>

David Lemon
sumber
yang satu ini bikin json, saya asumsikan penulis menanyakan tentang serialisasi ke URI.
jaskmar
Saya akan senang melihat ini berfungsi untuk beberapa formulir opsi pilihan.
Zach Smith
@ZachSmith Ini sudah berhasil, tapi saya menambahkan contoh untuk Anda periksa
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 );
}

Untuk menggunakan seperti ini:

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

Saya harap saya telah membantu.

Eduardo Borges
sumber
3
Tidak akan berfungsi dengan kotak centang. Di sini, Anda harus secara eksplisit memeriksa jenis masukan.
Adrian Preuss
5

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.

CAOakley
sumber
2
Ini harus bekerja pada sebagian besar elemen. Jelas bukan textarea / pilih, meskipun
jaggedsoft
apakah slice.call itu sama dengan Array.from?
pengguna1040495
5

Versi kode @ SimonSteinberger yang difaktorkan ulang menggunakan lebih sedikit variabel dan memanfaatkan kecepatan forEachloop (yang sedikit lebih cepat dari fors)

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, '+');
}
Stefan Gabos
sumber
3

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);
}
Brian Edmonds
sumber
Saya menyalin ini langsung ke aplikasi saya dan multi-pilih tampaknya tidak berfungsi (nilai digandakan)
wajar
@anastymous Terima kasih atas tangkapannya, ini telah diperbaiki.
Brian Edmonds
Hai Brian, evt untuk apa? dan apa yang harus saya lewatkan untuk itu? Firefox memberi tahu saya bahwa itu tidak ditentukan.
anastymous
Hai anastymous, terima kasih lagi untuk tangkapannya, itu harus diperbaiki dengan mengubah tugas ke evt ke 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
Brian Edmonds
3

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>

Anil
sumber
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);
Onome Mine Adamu
sumber
2

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

Espoir Murhabazi
sumber
2

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.

crashtestxxx
sumber
apakah ini berfungsi untuk banyak pilihan? tampaknya ketika saya menggunakan kode Anda, ia hanya mengembalikan item pertama dari beberapa nilai opsi yang dipilih
Zach Smith
@ZachSmith Saya telah memperbarui jawaban saya untuk menyertakan beberapa elemen terpilih.
crashtestxxx
1

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"      : "[email protected]",
    "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>

Tuan Polywhirl
sumber
0

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;
}
Manoj Rana
sumber
0

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);
}
RahmanRezaee
sumber
-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;
}
Hasan
sumber
Terlihat rapi, tetapi tidak memperhitungkan tombol radio atau kotak centang
Yvonne Aburrow
-1

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;
}
tobias47n9e
sumber
-1

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);
}
Michael Sherris Caley
sumber
mendasarkan formulir Anda untuk mengambil elemen dengan jenis masukan akan gagal untuk select, dsb
Zach Smith