직렬화 자바 스크립트 양식 (프레임 워크 없음)


141

jquery 또는 프레임 워크없이 양식을 직렬화하고 직렬화 된 버전에 액세스 할 수있는 프레임 워크가없는 Javascript 기능이 있습니까?


1
"직렬화 버전 액세스"란 무엇을 의미합니까? : 나는 다차원 객체와 같은 JSON에 HTML 양식을 변환 할 수있는 제 3 자 종속성이없는 스크립트 개발했습니다 github.com/serbanghita/formToObject 는 응답 드롭 도움이된다면 -
SERBAN Ghiţă

답변:


39

소형 직렬화 라이브러리 는 프레임 워크에 의존하지 않습니다. 이와 같은 것 외에 직렬화 기능을 직접 구현해야합니다. (무게 1.2 킬로바이트이지만 사용하지 않겠습니까?)


2
이것은 완벽했다. 그러나 case 'email':코드의 입력 섹션에 a를 추가해야 했습니다
aravind

아, 이제는 자바 스크립트가 없으면 googlecode가 작동하지 않는다는 것을 알았습니다. 그것은 단순히 뱉어That's an error
user1040495

3
라이브러리에 대한 링크뿐만 아니라 일부 코드를 포함하십시오. 라이브러리가 오픈 소스 인 경우 관련 코드를 복사 할 수 있어야합니다.
Luke

171

순수한 JavaScript 접근 방식은 다음과 같습니다.

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

POST 요청에서만 작동하는 것 같습니다.

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


13
이것은 multipart를 전송하는데, 이는 간단한 REST 서비스 (예 : feathers-mongoDB)에서 제대로 작동하지 않습니다.
Jason McCarrell 1

POST 요청에서만 작동하는 것이 옳습니다. 그것은 문서에서 즉시 명확하지 않았습니다.
manisha

이것은 나를 위해 작동하지 않습니다. 양식은 깊이 중첩되어 있습니다. FormData 객체가 비어 있습니다…
chitzui

참고로, 그렇지 않으면 Firefox 66 에서 오류가 발생 req.open("POST", "<your-url>");하기 전에 사용해야 할 수도 있습니다 . PUT과 같은 다른 요청에서도 작동해야합니다. POST를 PUT으로 바꾸는 것입니다. req.send(data);InvalidStateError: XMLHttpRequest state must be OPENED.
baptx

1
"GET"메소드를 사용하여 FormData 객체를 어떻게 보낼 수 있습니까? 예, FormData는 "POST"에서만 작동합니다.
렉스 이상한

88

최신 브라우저 만

URLSearchParamsAPI ( 가장 최근 브라우저 ) 및 FormData(formElement)생성자 ( 가장 최근 브라우저 제외 ) 를 지원하는 브라우저를 대상으로하는 경우 다음을 사용하십시오.

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

IE를 제외한 모든 곳

생성자 를 지원 URLSearchParams하지만 지원 하지 않는 브라우저의 경우이 FormData polyfill 및이 코드를 사용하십시오 (IE를 제외한 모든 곳에서 작동).FormData(formElement)

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

IE 10과 호환

구형 브라우저 (예 : IE 10)의 경우 FormData polyfill , Array.from필요한 경우 polyfill 및이 코드를 사용하십시오.

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

여기 .toString()정말로 필요합니까?
Ollie Williams

1
문자열이 아닌을 원하면 URLSearchParams예. 문자열을 보간하거나 문자열에 추가하면 문자열 변환이 암시 적으로 발생 toString합니다.이 경우 명시 적 호출이 필요하지 않습니다.
glebm

한 - 라이너 않았다 하지 년 4 월 2018로 iOS의 사파리에 나를 위해 작동
jchook

어떤 오류가 발생하며 어떤 버전의 Safari입니까? 아마도 new FormData(formElement)아직 지원되지 않습니다?
glebm

@glebm 예 Safari에서 지원되지 않습니다. 다른 솔루션을 찾으셨습니까?
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("&");
}

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


1
이 직렬화는 공백이 "+"로 표시되는 표준 양식 직렬화와 호환되지 않는 것 같습니다. 위의 코드는 encodeURIComponent 만 사용 하며 공간을 "% 20"으로 인코딩합니다. 적합성이 필요한 경우, 정규식을 사용하여 전송 전에 "% 20"을 "+"로 변환 할 수 있습니다.
RobG

3
이러한 수정 된 버전을 gist.github.com/brettz9/7147458에 추가 했습니다 (다른 개선 사항 포함)
Brett Zamir

3
제출 버튼을 반드시 제출할 필요는 없으며, 재설정 버튼을 제출해서는 안되며, 제출에 사용 된 버튼 만 제출 버튼으로 간주됩니다. HTML5 4.10.22 양식 제출을 참조하십시오 .
RobG

입력 유형 이메일을 직렬화하지 마십시오.
Ivan

25

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, '+');
}

비활성화 된 필드는 버리고 이름도 URL로 인코딩됩니다. % 20 문자의 정규식 바꾸기는 문자열을 반환하기 전에 한 번만 발생합니다.

쿼리 문자열은 jQuery의 $ .serialize () 메서드의 결과와 동일한 형식입니다.


6
코드를 개선하기 위해 시간을내어 +1 좋은 학습 기회이기 때문에 사람들이 내 결함을 발견하면 즐깁니다. 보기 좋게 유지하기위한 +1 +1을 줄 수 없기 때문에 -1 = (
TibTibs

1
form.nodeName.toLowerCase() == "form"대신 추가 할 수 있습니다form.nodeName == "FORM"
StefanNch

12

나는 Johndave Decano의 답변으로 시작했습니다.

이것은 그의 기능에 대한 답변에서 언급 된 몇 가지 문제를 해결해야합니다.

  1. % 20을 + 기호로 바꿉니다.
  2. 제출 / 단추 유형은 클릭하여 양식을 제출 한 경우에만 제출됩니다.
  3. 리셋 버튼은 무시됩니다.
  4. 필드 유형에 관계없이 본질적으로 동일한 작업을 수행하기 때문에 코드가 중복 된 것처럼 보입니다. 'tel'및 'email'과 같은 HTML5 필드 유형과의 비 호환성을 언급하지 않았으므로 switch 문으로 대부분의 세부 사항을 제거했습니다.

이름 값이없는 버튼 유형은 여전히 ​​무시됩니다.

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

이것이 현재이 기능을 사용하는 방법입니다.

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

6
멋지게 리팩토링 된 코드의 경우 +1 비활성화 된 필드를 무시하고 -1은 쿼리 문자열에 나타나지 않아야합니다. 양식 요소의 반복 계산을 피하는 매우 우아한 for 문에 +1 총계 : +1 :-) 감사합니다!
Simon Steinberger

비활성화 된 필드에 대한 좋은 참고 사항, 최근에 내가 작성중인 새로운 기능 으로이 문제가 발생했습니다. 재미있는 댓글 읽기를 즐기기 때문에 둘 다 +1합니다. :)
TibTibs

11

json 형식의 POST를 사용하여 "myForm"양식을 제출해야하는 경우 다음을 수행 할 수 있습니다.

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

두 번째 줄은 다음과 같은 배열에서 변환됩니다.

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

... 다음과 같은 일반 객체로

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

... mapFn을 Array.from ()에 전달 하여이 변환을 수행합니다. 이 mapFn은 각 [ "a", "b"] 쌍에 적용되어 { "a": "b"}로 변환되어 배열에 각각 하나의 속성 만있는 많은 객체가 포함됩니다. mapFn은 "파괴"를 사용하여 쌍의 첫 번째 부분과 두 번째 부분의 이름을 가져오고 ES6 "ComputedPropertyName"을 사용하여 mapFn이 반환 한 객체의 속성 이름을 설정합니다 (이것이 "[ x] : "x : 무엇인가"보다는 ""

이 모든 단일 속성 개체는 모든 단일 속성 개체를 모든 속성을 가진 단일 개체로 병합하는 Object.assign () 함수의 인수로 전달됩니다.

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

매개 변수의 파괴 : https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

: 자세한 내용은 여기 계산 된 속성 이름에 자바 스크립트 객체 리터럴에서 속성 이름과 변수?


내가 두 번째 줄을 이해하지 못하는 경우에도 나를 위해 작동합니다. 그것에 대해 더 많은 정보를 줄 수 있습니까 ??
Espoir Murhabazi

스프레드 연산자와 기본 Object 및 Array 메서드를 사용하는 멋진 답변.
Vinny Fonseca

이 접근법은 IE (.entries ())에서 지원되지 않습니다.
친구

Object.entries ()의 MDN 페이지에는 IE에 사용할 수있는 짧은 polyfill ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)이 있지만 IE는 스프레드 연산자도 지원하지 않습니다.
molsson 2016 년

새 메소드 Object.fromEntries (new FormData (myFormElement))를 사용하여 양식을 직렬화 할 수 있습니다.
미겔 사비 냐노

10

모든 브라우저에서 작동합니다.

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>


이것은 json을 만듭니다. 저는 저자가 URI로 직렬화하는 것을 요구한다고 가정합니다.
jaskmar

여러 선택 옵션 양식 에서이 작업을보고 싶습니다.
Zach Smith

@ZachSmith 그것은 이미 효과가 있었지만 그것을 확인하기위한 예제를 추가했습니다
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 );
}

이렇게 사용하려면

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

도움이 되었기를 바랍니다.


3
확인란에서는 작동하지 않습니다. 여기에서 입력 유형을 명시 적으로 확인해야합니다.
Adrian Preuss

5

이벤트의 입력을 직렬화하려는 경우. 여기에 내가 사용하는 순수한 JavaScript 접근법이 있습니다.

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

데이터는 입력의 JavaScript 객체입니다.


2
이것은 대부분의 요소에서 작동합니다. 그래도 텍스트 영역 / 선택이
아님

그 slice.call은 Array.from과 동일합니까?
user1040495

5

적은 변수를 사용하고 forEach루프 속도 ( fors 보다 약간 빠름 )를 이용하는 @SimonSteinberger 코드의 리팩토링 된 버전

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

나는 TibTibs 답변을 훨씬 더 명확하게 리팩토링했습니다. 80 자 너비와 약간의 주석으로 인해 조금 더 깁니다.

또한 빈 필드 이름과 빈 값은 무시합니다.

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

내가 직접 내 응용 프로그램과 이것을 복사 (값이 중복) 작업에 표시되지 않습니다 다중 선택
anastymous

@anastymous 캐치 주셔서 감사합니다, 그것은 수정되었습니다.
Brian Edmonds

안녕 브라이언, Evt 는 무엇입니까? 그리고 나는 그것을 위해 무엇을 전달해야합니까? Firefox가 정의되지 않았다고 알려줍니다.
anastymous

안녕하세요, 캐치에 다시 한 번 감사드립니다. 할당을 evt로 변경하여 수정해야합니다 evt = evt || window.event || { target: null };(편집이 완료 된 것처럼). "제출"이벤트 또는 버튼의 "클릭". 양식에 제출할 여러 단추가있는 경우 이벤트를 트리거 한 단추의 값만 설명하고 다른 단추는 무시하려고합니다. 나는 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

@moison answer 및 MDN 에서 formData의 entries () 메소드를 가져 왔습니다 .

FormData.entries () 메서드는이 객체에 포함 된 모든 키 / 값 쌍을 통과 할 수있는 반복자를 반환합니다. 각 쌍의 키는 USVString 객체입니다. USVString 또는 Blob 값입니다.

그러나 유일한 문제는 모바일 브라우저 (android 및 safari는 지원되지 않음)와 IE 및 Safari 데스크탑도 있다는 것입니다

그러나 기본적으로 여기에 내 접근 방식이 있습니다.

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'

};

코드는 여기 에서 찾을 수 있습니다


2

JavaScript reduce 함수를 사용하면 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;
 },[]);

라이브 예는 다음과 같습니다.


이것은 다중 선택에서 작동합니까? 내가 당신의 코드를 사용할 때 그것은 선택된 여러 옵션 값의 첫 번째 항목만을 반환하는 것 같습니다
Zach Smith

@ ZachSmith 여러 선택 요소를 포함하도록 답변을 업데이트했습니다.
crashtestxxx

0

이것이 효과가 있기를 바랍니다.

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

David Lemon의 답변을 개선합니다.

양식 데이터를 JSON으로 변환하고 데이터 객체에서 양식을 설정할 수 있습니다.

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

이것은 다음과 같이 매우 간단한 기능으로 수행 할 수 있습니다

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

순수한 JavaScript 접근 방식은 다음과 같습니다.

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

깔끔하게 보이지만 라디오 버튼이나 확인란은 고려하지 않습니다
Yvonne Aburrow

-1

디버깅 목적으로 도움이 될 수 있습니다.

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

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

    return false;
}

-1

나는 미쳤을 수 있지만이 답변이 심각하게 부풀어 오른 것을 발견했습니다. 여기 내 해결책이 있습니다.

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합니다.
Zach Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.