hình thức tuần tự hóa javascript (không có khung)


140

Tự hỏi có một chức năng trong javascript mà không có jquery hoặc bất kỳ khung nào cho phép tôi tuần tự hóa biểu mẫu và truy cập phiên bản nối tiếp không?


1
Bạn có ý nghĩa gì khi "truy cập phiên bản nối tiếp"? Tôi đã phát triển một tập lệnh không có sự phụ thuộc của bên thứ 3 có thể chuyển đổi biểu mẫu HTML thành một đối tượng giống như JSON, đó là đa chiều: github.com/serbanghita/formToObject - nếu nó giúp trả lời
Șerban Ghiță

Câu trả lời:


39

Thư viện thu nhỏ nối tiếp không dựa vào khung. Khác với những thứ tương tự, bạn sẽ cần phải tự thực hiện chức năng tuần tự hóa. (mặc dù với trọng lượng 1,2 kilobyte, tại sao không sử dụng nó?)


2
Điều này là hoàn hảo. Nhưng phải thêm một case 'email':phần trong phần đầu vào của mã
aravind

oh, bây giờ tôi thấy, googlecode không hoạt động mà không có javascript. Nó chỉ đơn giản là nhổThat's an error
user1040495

3
Vui lòng bao gồm một số mã và không chỉ là một liên kết đến một thư viện. Nếu thư viện là nguồn mở, bạn sẽ có thể sao chép mã liên quan.
Luke

171

Đây là cách tiếp cận JavaScript thuần túy:

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

Mặc dù nó dường như chỉ hoạt động cho các yêu cầu POST.

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


13
Lưu ý, điều này sẽ gửi nhiều phần, hoạt động kém với một số dịch vụ REST đơn giản (ví dụ: lông-mongoDB)
Jason McCarrell

Tôi nghĩ bạn đúng khi nó chỉ hoạt động với các yêu cầu POST. Điều đó không ngay lập tức rõ ràng từ các tài liệu.
manisha

Điều này không làm việc cho tôi. Các hình thức được lồng sâu. Đối tượng FormData trống rỗng
chitzui

Lưu ý, bạn có thể phải sử dụng req.open("POST", "<your-url>");trước khi req.send(data);khác Nếu tôi gặp lỗi InvalidStateError: XMLHttpRequest state must be OPENED.trên Firefox 66. Nó cũng hoạt động với các yêu cầu khác giống như PUT là bạn thay thế POST bằng PUT.
baptx

1
Hãy suy nghĩ về nó: làm thế nào bạn có thể gửi một đối tượng FormData bằng phương thức "GET"? Có, FormData chỉ hoạt động với "POST".
Rex the Strange

88

Chỉ dành cho trình duyệt hiện đại

Nếu bạn nhắm mục tiêu các trình duyệt hỗ trợ URLSearchParamsAPI ( hầu hết các trình duyệt gần đây ) và hàm FormData(formElement)tạo ( hầu hết các trình duyệt gần đây trừ Edge ), hãy sử dụng:

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

Ở mọi nơi trừ IE

Đối với các trình duyệt hỗ trợ URLSearchParamsnhưng không phải là hàm FormData(formElement)tạo, hãy sử dụng polyfill FormData này và mã này (hoạt động ở mọi nơi trừ IE):

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

Thí dụ

Tương thích với IE 10

Đối với các trình duyệt cũ hơn (ví dụ IE 10), hãy sử dụng polyfill FormData , một Array.frompolyfill nếu cần thiết và mã này:

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

.toString()thực sự cần thiết ở đây?
Ollie Williams

1
Nếu bạn muốn một chuỗi và không URLSearchParams, thì có. Chuyển đổi chuỗi cũng xảy ra ngầm nếu bạn nội suy hoặc thêm nó vào chuỗi, trong trường hợp đó, toStringcuộc gọi rõ ràng là không cần thiết.
glebm

One-liner không hoạt động với tôi trên iOS Safari kể từ tháng 4 năm 2018
jchook

Bạn gặp lỗi gì và phiên bản Safari là gì? Có lẽ new FormData(formElement)chưa được hỗ trợ ở đó?
glebm

@glebm vâng, nó không được hỗ trợ trong Safari, bạn có tìm thấy giải pháp nào khác không?
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("&");
}

Nguồn: http://code.google.com.vn/p/form-serialize/source/browse/trunk/serialize-0.1.js


1
Sự tuần tự hóa đó dường như không tương thích với tuần tự hóa dạng chuẩn, trong đó khoảng trắng được biểu thị bằng "+". Ở trên chỉ sử dụng encodeURIComponent , sẽ mã hóa không gian dưới dạng "% 20". Nếu cần phải tuân thủ, một biểu thức chính quy có thể được sử dụng ở cuối để chuyển đổi "% 20" thành "+" trước khi truyền.
RobG

3
Tôi đã thêm một phiên bản sửa đổi như vậy vào gist.github.com/brettz9/7147458 (với một số cải tiến khác)
Brett Zamir

3
Các nút gửi không nhất thiết phải được gửi, các nút đặt lại không bao giờ được gửi và chỉ các nút được sử dụng để gửi và được coi là nút gửi trong trường hợp đó. Xem HTML5 4.10.22 Gửi mẫu .
RobG

không tuần tự hóa email loại đầu vào.
Ivan

24

Đây là một phiên bản sửa đổi một chút của 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, '+');
}

Các trường bị vô hiệu hóa bị loại bỏ và tên cũng được mã hóa URL. Regex thay thế% 20 ký tự chỉ diễn ra một lần, trước khi trả về chuỗi.

Chuỗi truy vấn có dạng giống hệt với kết quả từ phương thức $ .serialize () của jQuery.


6
+1 để dành thời gian cải thiện mã. Tôi thích khi mọi người tìm thấy sai sót của tôi, vì đó là một cơ hội học tập tốt. +1 để giữ cho nó trông cũng đẹp. -1 vì tôi không thể cho +2 = (
TibTibs

1
bạn có thể thêm form.nodeName.toLowerCase() == "form"thay vìform.nodeName == "FORM"
StefanNch

12

Tôi bắt đầu với câu trả lời từ Johndave Decano.

Điều này sẽ khắc phục một số vấn đề được đề cập trong trả lời cho chức năng của mình.

  1. Thay% 20 bằng ký hiệu +.
  2. Các loại Gửi / Nút sẽ chỉ được gửi nếu chúng được bấm để gửi biểu mẫu.
  3. Các nút đặt lại sẽ bị bỏ qua.
  4. Mã dường như dư thừa đối với tôi vì về cơ bản nó đang làm điều tương tự bất kể các loại trường. Chưa kể đến việc không tương thích với các loại trường HTML5 như 'tel' và 'email', do đó tôi đã loại bỏ hầu hết các chi tiết cụ thể bằng các câu lệnh chuyển đổi.

Các loại nút sẽ vẫn bị bỏ qua nếu chúng không có giá trị tên.

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);
}

Đây là cách tôi hiện đang sử dụng chức năng này.

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

6
+1 cho mã được tái cấu trúc độc đáo. -1 để bỏ qua các trường bị vô hiệu hóa, không nên xuất hiện trong chuỗi truy vấn. +1 cho câu lệnh rất tao nhã, tránh lặp lại việc đếm các phần tử biểu mẫu. Tổng cộng: +1 :-) Cảm ơn!
Simon Steinberger

Lưu ý tốt về các trường bị vô hiệu hóa, tôi đã chạy vào đây gần đây với một chức năng mới mà tôi đang viết. +1 cho cả hai bạn, vì tôi thích đọc những bình luận vui vẻ. :)
TibTibs

11

Nếu bạn cần gửi biểu mẫu "myForm" bằng POST ở định dạng json, bạn có thể làm:

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)
});

Dòng thứ hai chuyển đổi từ một mảng như:

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

... thành một đối tượng thông thường, như:

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

... nó thực hiện chuyển đổi này bằng cách chuyển một mapFn vào Array.from (). MapFn này được áp dụng cho từng cặp ["a", "b"] và chuyển đổi chúng thành {"a": "b"} để mảng chứa nhiều đối tượng chỉ có một thuộc tính. MapFn đang sử dụng "phá hủy" để lấy tên của phần thứ nhất và thứ hai của cặp và nó cũng đang sử dụng "ComputingPropertyName" của ES6 để đặt tên thuộc tính trong đối tượng được mapFn trả về (đây là lý do tại sao nói "[ x]: một cái gì đó "chứ không chỉ là" x: một cái gì đó ".

Tất cả các đối tượng thuộc tính đơn lẻ này sau đó được chuyển vào các đối số của hàm Object.assign () để hợp nhất tất cả các đối tượng thuộc tính đơn lẻ thành một đối tượng có tất cả các thuộc tính.

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

Sự phá hủy trong các tham số: https://simonsmith.io/desturationuring-objects-as-feft-parameter-in-es6/

Thông tin thêm về tên thuộc tính được tính ở đây: Biến là tên thuộc tính trong một đối tượng JavaScript theo nghĩa đen?


Nó hoạt động với tôi ngay cả khi tôi không hiểu dòng thứ hai, bạn có thể cung cấp thêm thông tin về nó được không ??
Espoir Murhabazi

Câu trả lời hay bằng cách sử dụng toán tử trải rộng và các phương thức Object và Array gốc.
Vinny Fonseca

Lưu ý rằng phương pháp này không được hỗ trợ trong IE (.entries ())
anh chàng

Trang MDN cho Object.entries () có một polyfill ngắn mà bạn có thể sử dụng cho IE: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ tựa nhưng IE cũng không hỗ trợ toán tử lây lan.
molsson

bạn có thể tuần tự hóa biểu mẫu bằng phương thức mới Object.fromEntries (new FormData (myFormEuity)).
savuel savignano

10

Hoạt động trong tất cả các trình duyệt.

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>


cái này làm cho json, tôi giả sử tác giả đã hỏi về việc tuần tự hóa lên URI.
jaskmar

tôi rất thích thấy điều này làm việc cho nhiều hình thức lựa chọn.
Zach Smith

@ZachSmith Nó đã hoạt động, nhưng tôi đã thêm một ví dụ để bạn kiểm tra
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 );
}

Để sử dụng như thế này:

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

Tôi hy vọng tôi đã giúp.


3
Không làm việc với các hộp kiểm. Ở đây, bạn phải kiểm tra rõ ràng loại đầu vào.
Adrian Preuss

5

Nếu bạn đang tìm cách nối tiếp các đầu vào trong một sự kiện. Đây là một cách tiếp cận JavaScript thuần túy mà tôi sử dụng.

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

Dữ liệu sẽ là một đối tượng JavaScript của các đầu vào.


2
Điều này sẽ làm việc trên hầu hết các yếu tố. Tuy nhiên, chắc chắn không phải là textarea / select
jaggedsoft

đó có phải là lát.call giống như Array.from không?
dùng1040495

5

Một phiên bản được tái cấu trúc của mã @ SimonSteinberger sử dụng ít biến số hơn và tận dụng tốc độ của forEachcác vòng lặp (nhanh hơn một chút so với 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, '+');
}

3

Tôi đã tái cấu trúc câu trả lời của TibTib thành một thứ rõ ràng hơn để đọc. Nó dài hơn một chút vì độ rộng 80 ký tự và một vài bình luận.

Ngoài ra, nó bỏ qua tên trường trống và giá trị trống.

// 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);
}

Tôi đã sao chép điều này trực tiếp vào ứng dụng của mình và đa lựa chọn dường như không hoạt động (các giá trị được nhân đôi)
anastymous

@anastymous Cảm ơn bạn đã bắt, nó đã được sửa.
Brian Edmonds

Xin chào Brian, evt để làm gì? và những gì tôi nên vượt qua cho nó? Firefox đang nói với tôi rằng nó không được xác định.
anastymous

Xin chào anastymous, một lần nữa cảm ơn vì đã bắt được, nó nên được sửa bằng cách thay đổi gán cho evt evt = evt || window.event || { target: null };(như đã chỉnh sửa) Điểm đằng sau nó là để vượt qua sự kiện kích hoạt tuần tự hóa, nếu có một, chẳng hạn như một biểu mẫu Sự kiện "gửi" hoặc "nhấp chuột" của nút. Nếu một biểu mẫu có nhiều nút để gửi, bạn chỉ muốn tính đến giá trị của nút đã kích hoạt sự kiện và bỏ qua các nút khác. Tôi đã hack cùng một ví dụ rất thô sơ về hành vi này trên 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

Tôi đã nắm được phương thức entry () của formData từ câu trả lời @moison và từ MDN, nó nói rằng:

Phương thức FormData.entries () trả về một trình vòng lặp cho phép đi qua tất cả các cặp khóa / giá trị có trong đối tượng này. Khóa của mỗi cặp là một đối tượng USVString; giá trị là USVString hoặc Blob.

nhưng vấn đề duy nhất là trình duyệt di động (android và safari không được hỗ trợ) và cả máy tính để bàn IE và Safari

nhưng về cơ bản đây là cách tiếp cận của tôi:

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'

};

mã có thể được tìm thấy ở đây


2

Sử dụng chức năng giảm JavaScript sẽ thực hiện một mẹo cho tất cả các trình duyệt, bao gồm 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;
 },[]);

Sống ví dụ dưới đây.


điều này làm việc cho nhiều lựa chọn? dường như khi tôi sử dụng mã của mình, nó chỉ trả về mục đầu tiên của nhiều giá trị tùy chọn đã chọn
Zach Smith

@ZachSmith Tôi đã cập nhật câu trả lời của mình để bao gồm nhiều yếu tố được chọn.
crashtestxxx

0

Tôi hy vọng điều này sẽ làm việc

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

Cải thiện câu trả lời của David Lemon.

Điều này chuyển đổi dữ liệu biểu mẫu thành JSON và cho phép bạn đặt biểu mẫu từ một đối tượng dữ liệu.

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

Điều này có thể được thực hiện bởi chức năng rất đơn giản như sau

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

Đây là cách tiếp cận JavaScript thuần túy:

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;
}

Trông gọn gàng, nhưng nó không tính đến các nút radio hoặc hộp kiểm
Yvonne Aburrow 28/07/18

-1

Đối với mục đích gỡ lỗi, điều này có thể giúp bạn:

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

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

    return false;
}

-1

Tôi có thể bị điên nhưng tôi thấy những câu trả lời này thực sự nghiêm trọng. Đây là giải pháp của tôi

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);
}

dựa trên biểu mẫu của bạn để truy xuất các phần tử theo loại đầu vào sẽ thất bại select, et all
Zach Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.