ฉันจะรับข้อมูลแบบฟอร์มด้วย JavaScript / jQuery ได้อย่างไร


404

มีวิธีการหนึ่งบรรทัดที่ง่ายในการรับข้อมูลของแบบฟอร์มหรือไม่หากว่าจะต้องส่งในรูปแบบ HTML แบบคลาสสิกเท่านั้น?

ตัวอย่างเช่น:

<form>
    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />
    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
</form>

เอาท์พุท:

{
    "foo": "1",
    "bar": "xxx",
    "this": "hi"
}

บางสิ่งเช่นนี้เรียบง่ายเกินไปเนื่องจากไม่รวมถึง textareas, selects, ปุ่มเรดิโอและช่องทำเครื่องหมาย:

$("#form input").each(function () {
    data[theFieldName] = theFieldValue;
});

3
คำถามอื่นที่คล้ายกับนี้: stackoverflow.com/questions/169506/ …
Marcelo Rodovalho

คำตอบ:


431
$('form').serialize() //this produces: "foo=1&bar=xxx&this=hi"

การสาธิต


15
ปิด แต่บางทีสิ่งที่ส่งกลับอาร์เรย์ด้วยคู่ค่าคีย์แทนสายเดียว?
Bart van Heukelom

80
Nvm พบในความคิดเห็นสำหรับฟังก์ชั่น serialize () มันเรียกว่า serializeArray มันส่งกลับอาร์เรย์ของอาร์เรย์ (ซึ่งมีรายการ "ชื่อ" และ "ค่า") แต่ที่ควรจะง่ายพอที่จะแปลง
Bart van Heukelom

22
และการใช้_.object($("#myform").serializeArray().map(function(v) {return [v.name, v.value];} ))
ไลเดอร์ไลบรารี่

8
@BartvanHeukelom ฉันรู้ว่านี่คือ 4 ปีต่อมา แต่ .serializeArray () จะส่งกลับอาร์เรย์
TJ WealthEngine API Evangelist

6
ตรวจสอบให้แน่ใจว่าทุกแท็กอินพุตมีแอตทริบิวต์ชื่อไม่เช่นนั้นจะไม่ส่งคืนสิ่งใด
Eugene Kulabuhov

505

ใช้$('form').serializeArray()ซึ่งส่งคืนอาร์เรย์ :

[
  {"name":"foo","value":"1"},
  {"name":"bar","value":"xxx"},
  {"name":"this","value":"hi"}
]

ตัวเลือกอื่นคือ$('form').serialize()ซึ่งจะส่งคืนสตริง :

"foo=1&bar=xxx&this=hi"

ดูตัวอย่าง jsfiddle นี้


91
serializeArrayจะมีประโยชน์มากกว่านี้มากถ้ามันส่งคืนออบเจกต์ด้วยคู่ของคีย์
GetFree

8
ฉันยอมรับว่าวัตถุจะเหมาะ อย่างไรก็ตามมีปัญหา - กุญแจได้รับอนุญาตให้มีหลายค่า คุณจะคืนค่าวัตถุ "array of values" หรือ key- "ค่าแรก" หรืออย่างอื่นได้หรือไม่ ฉันคิดว่าพวก jQuery ไม่ได้เลือกข้อใดข้อหนึ่งข้างต้น :)
เปาโล

ระวังปัญหาเกี่ยวกับค่าหลายค่า (ตามที่ @Paul กล่าวถึงข้างต้น) ช่องทำเครื่องหมายและอินพุตหลายรายการที่ใช้name="multiple[]"ไม่ได้ วิธีแก้ปัญหาสำหรับวิธี POST เหมือนกันเพียงแค่ใช้ $ ('form') serialize () นอกจากนี้วิธีการ POST นั้นมีความยาวไม่เกิน 2,000 ตัวอักษรเนื่องจาก GET ใช้ในเบราว์เซอร์ส่วนใหญ่ดังนั้นสามารถใช้งานได้แม้กับข้อมูลขนาดใหญ่
Artru

โปรดระวังว่าในการบันทึกค่าจากอินพุตแบบฟอร์มใด ๆ อินพุตจะต้องมีnameแอตทริบิวต์
Chris - Jr

@ รับฟรีทำไมไม่ใช้เพียงฟังก์ชั่นแผนที่ jQuery? ฟังก์ชัน getFormData (ฟอร์ม) {var rawJson = form.serializeArray (); var model = {}; $ .map (rawJson, ฟังก์ชั่น (n, i) {model [n ['ชื่อ']] = n ['ค่า'];}); แบบจำลองการคืน }
Tom McDonough

196

อัพเดตคำตอบสำหรับปี 2014: HTML5 FormDataทำสิ่งนี้

var formData = new FormData(document.querySelector('form'))

จากนั้นคุณสามารถโพสต์ formData ได้ตามที่เป็นอยู่ - ประกอบด้วยชื่อและค่าทั้งหมดที่ใช้ในแบบฟอร์ม


13
บวกหนึ่งเป็น FormData ดีและมีประโยชน์ แต่น่าสังเกตว่าถ้าคุณต้องการอ่านข้อมูลใน FormData มันไม่ง่ายนัก (ดูstackoverflow.com/questions/7752188/ … )
StackExchange What The Heck

1
โปรดทราบว่า FormData เป็นส่วนหนึ่งของคุณสมบัติขั้นสูง XMLHttpRequest (ก่อนหน้านี้รู้จักกันในชื่อ XMLHttpRequest ระดับ 2) ดังนั้นคุณต้องพึ่งพาpolyfillสำหรับ Internet Explorer <10 caniuse.com/#feat=xhr2
Pier-Luc Gendreau

3
@yochannah ไม่เป็นเช่นนั้น แน่นอนว่าไม่มีใครสามารถเข้าถึงและแก้ไขข้อมูลเช่นวัตถุปกติ แต่ก็ยังเป็นเรื่องเล็กน้อยที่จะได้รับข้อมูล ลองดูentries()วิธีการ[หน้า MDN ]
เว็บและการไหล

@ เว็บและการไหลขอบคุณสำหรับการชี้ออก! ฉันชอบเมื่อเบราว์เซอร์เพิ่มคุณสมบัติใหม่และมีประโยชน์ :) เวลาพวกเขาเปลี่ยนไป
StackExchange What The Heck

ฉันกำลังพยายามใช้ FormData เพื่อส่งวัตถุไปยังสคริปต์ Flask-python ของฉัน แต่ดูเหมือนว่าจะไม่ได้มาเป็นวัตถุคำขอปกติที่ฉันสามารถแกะกล่องออกมาได้ ใครสามารถชี้ไปที่คำอธิบายของขั้นตอนพิเศษเพื่อจัดการกับฝั่งเซิร์ฟเวอร์ได้หรือไม่? นั่นคือสิ่งที่ฉันว่างเปล่า
manisha

181

ขึ้นอยู่กับjQuery.serializeArrayส่งคืนคู่ค่าคีย์

var data = $('#form').serializeArray().reduce(function(obj, item) {
    obj[item.name] = item.value;
    return obj;
}, {});

12
คู่คีย์ - ค่าที่นี่พวกทุกคนมาที่นี่! มันเป็นทอง !!! ขอบคุณ! ถ้าฉันต้องการค่าขององค์ประกอบชื่อ "ผู้ค้าปลีก" ฉันจะทำสิ่งนี้ console.log ($ ('# form') serializeArray (). ลด (ฟังก์ชั่น (obj, รายการ) {obj [item.name] = item ค่า; ส่งคืน obj;}, {}) ['ผู้ค้าปลีก']);
Yevgeniy Afanasyev

ฉันสร้างเมื่อวานนี้เป็นวิธี JQuery ตามคำตอบนี้ แต่ทำงานกับ multiselects และอาร์เรย์อินพุต (พร้อมชื่อ 'ตัวอย่าง []') คุณสามารถค้นหาได้ในคำตอบของฉันด้านล่าง อย่างไรก็ตามแนวทางที่ดี Neuront ขอบคุณ! :)
manuman94

อันนี้เหมาะกับฉันที่สุดจากคำตอบทั้งหมด!
VPetrovic

IMHO นี้เป็นคำตอบที่ดีที่สุด!
ราหุล

74
document.querySelector('form').addEventListener('submit', (e) => {
  const formData = new FormData(e.target);
  // Now you can use formData.get('foo'), for example.
  // Don't forget e.preventDefault() if you want to stop normal form .submission
});

นี่คือคำตอบของ nitpicky แต่ให้ฉันอธิบายว่าทำไมนี่จึงเป็นทางออกที่ดีกว่า:

  • เราจัดการการส่งแบบฟอร์มอย่างถูกต้องมากกว่าการกดปุ่ม บางคนชอบกดลงบนช่อง บางคนใช้อุปกรณ์อินพุตอื่นเช่นอินพุตเสียงพูดหรืออุปกรณ์ช่วยการเข้าถึงอื่น ๆ จัดการกับการส่งแบบฟอร์มและคุณแก้ไขมันได้อย่างถูกต้องสำหรับทุกคน

  • เรากำลังขุดลงในข้อมูลแบบฟอร์มสำหรับแบบฟอร์มจริงที่ส่งมา หากคุณเปลี่ยนตัวเลือกแบบฟอร์มของคุณในภายหลังคุณไม่จำเป็นต้องเปลี่ยนตัวเลือกสำหรับฟิลด์ทั้งหมด นอกจากนี้คุณอาจมีหลายรูปแบบที่มีชื่ออินพุตเดียวกัน ไม่จำเป็นต้องแก้ความสับสนด้วยรหัสประจำตัวที่มากเกินไปและอะไรที่ไม่เพียงแค่ติดตามอินพุตตามแบบฟอร์มที่ส่งมา สิ่งนี้ยังช่วยให้คุณใช้ตัวจัดการเหตุการณ์เดี่ยวสำหรับหลาย ๆ รูปแบบหากเหมาะสมกับสถานการณ์ของคุณ

  • อินเทอร์เฟซ FormData ค่อนข้างใหม่ แต่ได้รับการสนับสนุนอย่างดีจากเบราว์เซอร์ เป็นวิธีที่ยอดเยี่ยมในการสร้างการรวบรวมข้อมูลเพื่อรับคุณค่าที่แท้จริงของสิ่งที่อยู่ในฟอร์ม หากไม่มีคุณจะต้องวนซ้ำองค์ประกอบทั้งหมด (เช่นกับform.elements) และหาว่ามีอะไรที่ถูกตรวจสอบอะไรที่ไม่ได้มีคุณค่าอะไรบ้างและเป็นไปได้ทั้งหมดหากคุณต้องการการสนับสนุนเบราว์เซอร์เก่า แต่ FormData อินเตอร์เฟสนั้นง่ายกว่า

  • ฉันใช้ ES6 ที่นี่ ... ไม่ได้ต้องการโดยวิธีการใด ๆ ดังนั้นเปลี่ยนเป็น ES5 ที่เข้ากันได้ถ้าคุณต้องการการสนับสนุนเบราว์เซอร์รุ่นเก่า


fyi วัตถุ FormData ไม่เปิดเผยค่าของพวกเขา ในการรับวัตถุธรรมดาจากมันให้ดูstackoverflow.com/questions/41431322/…
phil294

2
@ Blauhirn เรื่องไร้สาระแน่นอนว่าพวกเขาเปิดเผยค่า รหัสในคำตอบของฉันใช้งานได้ คุณควรลอง นี่ฉันทำไวโอลินได้สำหรับคุณ: jsfiddle.net/zv9s1xq5 ถ้าคุณต้องการ iterator formData.entries()ใช้
แบรด

ฉันรู้ว่ามันใช้งานได้ แต่คุณสมบัติไม่สามารถเข้าถึงได้โดยกุญแจ ตัวอย่างเช่นformData.foo ไม่ได้กำหนด เท่าที่เห็นในคำตอบของคุณ.get() จำเป็นต้องเรียกสิ่งที่ฉันคิดว่าไม่สะดวก บางที "ไม่เปิดเผย" มาผิดทาง ดังนั้นในการสร้างบางสิ่งเช่น{ foo: 'bar' }จากsubmitเหตุการณ์คุณต้องทำซ้ำสิ่งเหล่านั้นด้วยตนเอง . To get a plain object from it, see [link]ดังนั้น
phil294

1
@Blauhirn คุณผิดเกี่ยวกับเรื่องนี้ XMLHttpRequest รองรับ FormData โดยตรง xhr.send(formData);
แบรด

1
@Blauhirn JSON.stringify([...formData]) หรือถ้าคุณต้องการคีย์ของคุณ / ค่าแยก ... [...formData].reduce((prev, cur) => { prev[cur[0]] = cur[1]; return prev;}, {})
แบรด

25

ใช้ .serializeArray () เพื่อรับข้อมูลในรูปแบบอาเรย์แล้วแปลงเป็นวัตถุ:

function getFormObj(formId) {
    var formObj = {};
    var inputs = $('#'+formId).serializeArray();
    $.each(inputs, function (i, input) {
        formObj[input.name] = input.value;
    });
    return formObj;
}

<input type="checkbox" name="someList" value="one" /> <input type="checkbox" name="someList" value="two" />นี้เขียนทับช่องทำเครื่องหมายของฉันถ้าฉันมีบางอย่างเช่น หากตรวจสอบทั้งคู่วัตถุจะมีค่าช่องทำเครื่องหมายที่สองเท่านั้น
dmathisen

2
นี่เป็นกรณีที่someListไม่ควรtype="radio"?
dylanjameswagner

upvote เนื่องจากคำตอบที่ยอมรับไม่ได้ส่งคืนวัตถุด้วยคีย์ดังนี้:name:value
Matt-the-Marxist

24

นี่คือโซลูตรอนที่ง่ายและสั้นจริงๆที่แม้ไม่ต้องการ Jquery

var formElements=document.getElementById("myForm").elements;    
var postData={};
for (var i=0; i<formElements.length; i++)
    if (formElements[i].type!="submit")//we dont want to include the submit-buttom
        postData[formElements[i].name]=formElements[i].value;

1
วิธีนี้ใช้ไม่ได้กับปุ่มตัวเลือก: ตัวเลือกสุดท้ายจะเป็นตัวเลือกที่เก็บไว้postDataเสมอ
Kyle Falconer

3
ขอบคุณที่ให้คำตอบกับเรา
เกลนเพียร์ซ

23

มันคือ 2019 และมีวิธีที่ดีกว่าในการทำสิ่งนี้:

const form = document.querySelector('form');
const data = new URLSearchParams(new FormData(form).entries());

หรือถ้าคุณต้องการวัตถุธรรมดาแทน

const form = document.querySelector('form');
const data = Object.fromEntries(new FormData(form).entries());

แม้ว่าจะทราบว่าวิธีนี้ใช้ไม่ได้กับคีย์ซ้ำเช่นที่คุณได้รับจากช่องทำเครื่องหมายเลือกหลายและทำซ้ำด้วยชื่อเดียวกัน


โดยสิ้นเชิง แม้ว่าฉันไม่ได้รับอาร์เรย์สำหรับรายการของอินพุตที่ทุกคนมีชื่อเดียวกันซึ่งหมายความว่าฉันต้องใช้document.getElementsByClassNameและสำหรับวง แต่เดี๋ยวก่อนยังดีกว่าที่ต้องการ jQuery และอื่น ๆ
alphanumeric0101

1
คำตอบนี้เป็นที่ชื่นชอบ แต่มันควรอ่านแทนเพียงdocument.querySelector querySelector
adabru

หมายเหตุ "FormData จะใช้เฉพาะฟิลด์ป้อนข้อมูลที่ใช้ชื่อแอตทริบิวต์" - จากMDN
binaryfunt


13

ฉันใช้สิ่งนี้:

ปลั๊กอิน jQuery

(function($){
  $.fn.getFormData = function(){
    var data = {};
    var dataArray = $(this).serializeArray();
    for(var i=0;i<dataArray.length;i++){
      data[dataArray[i].name] = dataArray[i].value;
    }
    return data;
  }
})(jQuery);

แบบฟอร์ม HTML

<form id='myform'>
  <input name='myVar1' />
  <input name='myVar2' />
</form>

รับข้อมูล

var myData = $("#myForm").getFormData();

โปรดทราบว่าปลั๊กอินนี้ไม่สามารถใช้งานได้ในกรณีที่มีหลายรายการที่มีชื่อเดียวกันอยู่ รายการสุดท้ายจะแทนที่รายการก่อนหน้าในขณะที่พฤติกรรมที่คาดหวังจะได้รับค่าทั้งหมดในฐานะArray
มิลลี่

1
เพิ่งทราบว่าอีกหนึ่งปีต่อมาฉันคิดว่านี่เป็นคำตอบที่แย่มากและไม่มีใครควรใช้มัน ดังที่ความคิดเห็นก่อนหน้าระบุไว้สิ่งต่าง ๆ เช่นปุ่มตัวเลือกจะไม่ทำงาน มีคำตอบที่ดีกว่าใช้หนึ่งในนั้นแทน
ดัสติน Poissant


11

นี่คือการใช้งาน JavaScript ที่ใช้งานได้อย่างถูกต้องซึ่งจัดการกับช่องทำเครื่องหมายปุ่มตัวเลือกและตัวเลื่อนอย่างถูกต้อง (อาจเป็นประเภทอินพุตอื่นเช่นกัน แต่ฉันได้ทดสอบสิ่งเหล่านี้เท่านั้น)

function setOrPush(target, val) {
    var result = val;
    if (target) {
        result = [target];
        result.push(val);
    }
    return result;
}

function getFormResults(formElement) {
    var formElements = formElement.elements;
    var formParams = {};
    var i = 0;
    var elem = null;
    for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
            case 'submit':
                break;
            case 'radio':
                if (elem.checked) {
                    formParams[elem.name] = elem.value;
                }
                break;
            case 'checkbox':
                if (elem.checked) {
                    formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
                }
                break;
            default:
                formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
    }
    return formParams;
}

ตัวอย่างการทำงาน:

    function setOrPush(target, val) {
      var result = val;
      if (target) {
        result = [target];
        result.push(val);
      }
      return result;
    }

    function getFormResults(formElement) {
      var formElements = formElement.elements;
      var formParams = {};
      var i = 0;
      var elem = null;
      for (i = 0; i < formElements.length; i += 1) {
        elem = formElements[i];
        switch (elem.type) {
          case 'submit':
            break;
          case 'radio':
            if (elem.checked) {
              formParams[elem.name] = elem.value;
            }
            break;
          case 'checkbox':
            if (elem.checked) {
              formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
            }
            break;
          default:
            formParams[elem.name] = setOrPush(formParams[elem.name], elem.value);
        }
      }
      return formParams;
    }

    //
    // Boilerplate for running the snippet/form
    //

    function ok() {
      var params = getFormResults(document.getElementById('main_form'));
      document.getElementById('results_wrapper').innerHTML = JSON.stringify(params, null, ' ');
    }

    (function() {
      var main_form = document.getElementById('main_form');
      main_form.addEventListener('submit', function(event) {
        event.preventDefault();
        ok();
      }, false);
    })();
<form id="main_form">
  <div id="questions_wrapper">
    <p>what is a?</p>
    <div>
      <input type="radio" required="" name="q_0" value="a" id="a_0">
      <label for="a_0">a</label>
      <input type="radio" required="" name="q_0" value="b" id="a_1">
      <label for="a_1">b</label>
      <input type="radio" required="" name="q_0" value="c" id="a_2">
      <label for="a_2">c</label>
      <input type="radio" required="" name="q_0" value="d" id="a_3">
      <label for="a_3">d</label>
    </div>
    <div class="question range">
      <label for="a_13">A?</label>
      <input type="range" required="" name="q_3" id="a_13" min="0" max="10" step="1" list="q_3_dl">
      <datalist id="q_3_dl">
        <option value="0"></option>
        <option value="1"></option>
        <option value="2"></option>
        <option value="3"></option>
        <option value="4"></option>
        <option value="5"></option>
        <option value="6"></option>
        <option value="7"></option>
        <option value="8"></option>
        <option value="9"></option>
        <option value="10"></option>
      </datalist>
    </div>
    <p>A and/or B?</p>
    <div>
      <input type="checkbox" name="q_4" value="A" id="a_14">
      <label for="a_14">A</label>
      <input type="checkbox" name="q_4" value="B" id="a_15">
      <label for="a_15">B</label>
    </div>
  </div>
  <button id="btn" type="submit">OK</button>
</form>
<div id="results_wrapper"></div>

แก้ไข:

หากคุณกำลังมองหาการใช้งานที่สมบูรณ์ยิ่งขึ้นลองดูที่ส่วนของโครงการที่ฉันทำไว้ ฉันจะอัปเดตคำถามนี้ในที่สุดด้วยโซลูชันที่สมบูรณ์ที่ฉันคิดขึ้นมา แต่อาจเป็นประโยชน์กับใครบางคน


1
วิธีแก้ปัญหาที่ดี :) ฉันพบข้อผิดพลาดหนึ่งข้อด้วยฟังก์ชัน setOrPush ไม่รวมการตรวจสอบเพื่อดูว่าเป้าหมายเป็นอาร์เรย์อยู่แล้วหรือไม่ทำให้เกิดการสร้างอาร์เรย์ที่ซ้อนกันในกรณีที่ช่องทำเครื่องหมายที่เลือกหลายรายการมีชื่อเดียวกัน
Wouter van Dam

@ KyleFalconer ดีมาก! ทำไมคุณไม่รวมกรณีสวิตช์สำหรับวิทยุและช่องทำเครื่องหมาย - มันจะทำงานได้อย่างถูกต้อง (ฉันเดา)
อีธาน

@Ethan เป็นเพราะช่องทำเครื่องหมายสามารถเลือกได้หลายค่าและวิทยุสามารถเลือกได้เพียงค่าเดียวดังนั้นวิธีที่ฉันจัดเก็บการเปลี่ยนแปลงค่า
Kyle Falconer

@ KyleFalconer ใช่ฉันเข้าใจแล้ว รหัสสำหรับการจัดการ 'ช่องทำเครื่องหมาย' ยังดูแลตัวเลือกเดียวที่เป็นไปได้สำหรับ 'วิทยุ' โดยอาศัยชุดคำสั่ง 'SetOrPush'
อีธาน

@Ethan Oh ฉันคิดว่าฉันรู้ว่าสิ่งที่คุณพูด มันสามารถทำได้ทั้งสองทาง แต่ฉันคิดว่าฉันทำอย่างนี้เพราะฉันต้องการเพียงหนึ่งค่าไม่ใช่อาเรย์ของค่า
Kyle Falconer

9

หากคุณใช้ jQuery นี่คือฟังก์ชั่นเล็ก ๆ น้อย ๆ ที่จะทำสิ่งที่คุณกำลังมองหา

ขั้นแรกให้เพิ่ม ID ในแบบฟอร์มของคุณ (ยกเว้นว่าเป็นแบบฟอร์มเดียวบนหน้าเว็บจากนั้นคุณสามารถใช้ 'แบบฟอร์ม' เป็นแบบสอบถามแบบโดม)

<form id="some-form">
 <input type="radio" name="foo" value="1" checked="checked" />
 <input type="radio" name="foo" value="0" />
 <input name="bar" value="xxx" />
 <select name="this">
  <option value="hi" selected="selected">Hi</option>
  <option value="ho">Ho</option>
</form>

<script>
//read in a form's data and convert it to a key:value object
function getFormData(dom_query){
    var out = {};
    var s_data = $(dom_query).serializeArray();
    //transform into simple data/value object
    for(var i = 0; i<s_data.length; i++){
        var record = s_data[i];
        out[record.name] = record.value;
    }
    return out;
}

console.log(getFormData('#some-form'));
</script>

ผลลัพธ์จะมีลักษณะดังนี้:

{
 "foo": "1",
 "bar": "xxx",
 "this": "hi"
}

7

คุณยังสามารถใช้วัตถุFormData ; วัตถุ FormData ช่วยให้คุณสามารถรวบรวมชุดของคู่คีย์ / ค่าที่จะส่งโดยใช้ XMLHttpRequest มีวัตถุประสงค์หลักเพื่อใช้ในการส่งข้อมูลแบบฟอร์ม แต่สามารถใช้อย่างอิสระจากแบบฟอร์มเพื่อส่งข้อมูลแบบคีย์

        var formElement = document.getElementById("myform_id");
        var formData = new FormData(formElement);
        console.log(formData);

ขอบคุณ แต่ถ้าคุณไม่มี ID ล่ะ ถ้าคุณมีแบบฟอร์มเป็นวัตถุ JQuery var form = $ (นี่) .closest ('form'); ? ควร var formElement = document.getElementById (ฟอร์ม [0]); ทำงานแทนสายภาคเรียนของคุณ? มันไม่ทำงานโชคไม่ดี คุณรู้ไหมว่าทำไม?
Yevgeniy Afanasyev

ที่จริงแล้ว FormData ไม่รองรับเบราว์เซอร์ทั้งหมด :( ดังนั้นควรใช้วิธีการอื่นที่ดีกว่า
numediaweb

ขอบคุณ ฉันใช้โครเมียมรุ่นล่าสุด แต่ก็ยังใช้งานไม่ได้ ดังนั้นฉันจึงไปกับ #neuront คำตอบจากที่นั่น
Yevgeniy Afanasyev

6

สิ่งนี้จะผนวกฟิลด์แบบฟอร์มทั้งหมดไปยังวัตถุ JavaScript "res":

var res = {};
$("#form input, #form select, #form textarea").each(function(i, obj) {
    res[obj.name] = $(obj).val();
})

อาจเป็นเพราะคำตอบเดียวกันนี้ถูกโพสต์ไปแล้วในปี 2010
nathanvda

ฉันไม่รู้ สำหรับคำตอบสั้น ๆ เช่นนี้ก็ไม่น่าแปลกใจ และยังอ้างอิงอยู่ที่ไหน
gamliela

อย่างจริงจัง? คุณไม่เชื่อความคิดเห็นของฉันโดยไม่มีการอ้างอิงและคุณไม่สามารถแม้แต่ดูรายการคำตอบเพื่อดูว่าพวกเขาเหมือนกันหรือไม่ stackoverflow.com/a/2276469/216513
nathanvda

ฉันคิดว่าคุณหมายถึงคำตอบในคำถามอื่น ฉันจำรายละเอียดตอนนี้ไม่ได้และเหตุผลของฉัน อาจเป็นเพราะมันไม่เหมือนกัน
gamliela

1
คำตอบที่สมบูรณ์แบบสำหรับคนที่ต้องการให้มันทำงานสำหรับการป้อนข้อมูลให้เลือกหลายรายการและ textarea เนื่องจากการใช้การทำให้เป็นอันดับคุณจะไม่ได้รับรายการทั้งหมดที่เลือกในแท็กที่เลือก แต่การใช้. val () คุณจะได้รับสิ่งที่คุณต้องการเป็นอาร์เรย์อย่างแน่นอน คำตอบที่ง่ายตรงไปตรงมา
Sailesh Kotha

6

ฉันได้รวมคำตอบเพื่อให้วัตถุที่ต้องการคืน

function getFormData(form) {
var rawJson = form.serializeArray();
var model = {};

$.map(rawJson, function (n, i) {
    model[n['name']] = n['value'];
});

return model;
}

สิ่งนี้จะไม่จัดการกับอาร์เรย์เลย ควรที่จะเป็นอันดับfoo[bar][] = 'qux' { foo: { bar: [ 'qux' ] } }
แอมเฟตามาจิน

6

จากการตอบสนองของนิวรอนท์ฉันได้สร้างวิธีการ JQuery แบบง่าย ๆ ที่ได้รับข้อมูลในรูปแบบคู่ค่าคีย์ แต่มันใช้งานได้สำหรับการเลือกหลายตัวและสำหรับอินพุตแบบอาเรย์ที่มี name = 'example []'

นี่คือวิธีการใช้งาน:

var form_data = $("#form").getFormObject();

คุณสามารถค้นหาตัวอย่างด้านล่างของคำจำกัดความและวิธีการทำงาน

// Function start
$.fn.getFormObject = function() {
    var object = $(this).serializeArray().reduce(function(obj, item) {
        var name = item.name.replace("[]", "");
        if ( typeof obj[name] !== "undefined" ) {
            if ( !Array.isArray(obj[name]) ) {
                obj[name] = [ obj[name], item.value ];
            } else {
               obj[name].push(item.value);
            }
        } else {
            obj[name] = item.value;
        }
        return obj;
    }, {});
    return object;
}
// Function ends

// This is how it's used
$("#getObject").click( function() {
  var form_data = $("#form").getFormObject();
  console.log(form_data);
});
/* Only to make view better ;) */
#getObject {
  padding: 10px;
  cursor:pointer;
  background:#0098EE;
  color:white;
  display:inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<form id="form">
  <input type="text" name="text" value="Hola amigo" /> 
  
  <input type="text" name="text_array[]" value="Array 1" /> 
  <input type="text" name="text_array[]" value="Array 2" /> 
  <input type="text" name="text_array[]" value="Array 3" /> 
  
  <select name="multiselect" multiple>
    <option name="option1" selected> option 1 </option>
    <option name="option2" selected> option 2 </option>
  </select>
  
  <input type="checkbox" name="checkbox" value="checkbox1" checked/>
  <input type="checkbox" name="checkbox" value="checkbox2" checked/>
  
  <input type="radio" name="radio" value="radio1" checked/>
  <input type="radio" name="radio" value="radio2"/>

</form>

<div id="getObject"> Get object (check the console!) </div>



4
function getFormData($form){
    var unindexed_array = $form.serializeArray();
    var indexed_array = {};

    $.map(unindexed_array, function(n, i){
        if(indexed_array[n['name']] == undefined){
            indexed_array[n['name']] = [n['value']];
        }else{
            indexed_array[n['name']].push(n['value']);
        }
    });

    return indexed_array;
}

4

คุณสามารถใช้ฟังก์ชันนี้เพื่อให้มีวัตถุหรือ JSON จากแบบฟอร์ม

สำหรับใช้งาน:

var object = formService.getObjectFormFields("#idform");

 function  getObjectFormFields(formSelector)
        {
            /// <summary>Função que retorna objeto com base nas propriedades name dos elementos do formulário.</summary>
            /// <param name="formSelector" type="String">Seletor do formulário</param>

            var form = $(formSelector);

            var result = {};
            var arrayAuxiliar = [];
            form.find(":input:text").each(function (index, element)
            {
                var name = $(element).attr('name');

                var value = $(element).val();
                result[name] = value;
            });

            form.find(":input[type=hidden]").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });


            form.find(":input:checked").each(function (index, element)
            {
                var name;
                var value;
                if ($(this).attr("type") == "radio")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    result[name] = value;
                }
                else if ($(this).attr("type") == "checkbox")
                {
                    name = $(element).attr('name');
                    value = $(element).val();
                    if (result[name])
                    {
                        if (Array.isArray(result[name]))
                        {
                            result[name].push(value);
                        } else
                        {
                            var aux = result[name];
                            result[name] = [];
                            result[name].push(aux);
                            result[name].push(value);
                        }

                    } else
                    {
                        result[name] = [];
                        result[name].push(value);
                    }
                }

            });

            form.find("select option:selected").each(function (index, element)
            {
                var name = $(element).parent().attr('name');
                var value = $(element).val();
                result[name] = value;

            });

            arrayAuxiliar = [];
            form.find("checkbox:checked").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = arrayAuxiliar.push(value);
            });

            form.find("textarea").each(function (index, element)
            {
                var name = $(element).attr('name');
                var value = $(element).val();
                result[name] = value;
            });

            return result;
        }


2
แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงก์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงนั้นเปลี่ยนแปลง - จากการตรวจสอบ
Wahyu Kristianto

แต่ลิงค์นี้มีฟังก์ชั่นเพื่อช่วยเหลือเขา (ฉันคิดว่า) แต่ฉันจะใส่รหัสในครั้งต่อไป
Marcos Costa

3

ผมเขียนห้องสมุดในการแก้ปัญหามากนี้: JSONForms มันใช้รูปแบบผ่านแต่ละอินพุตและสร้างวัตถุ JSON ที่คุณสามารถอ่านได้ง่าย

สมมติว่าคุณมีแบบฟอร์มต่อไปนี้:

<form enctype='application/json'>
  <input name='places[0][city]' value='New York City'>
  <input type='number' name='places[0][population]' value='8175133'>
  <input name='places[1][city]' value='Los Angeles'>
  <input type='number' name='places[1][population]' value='3792621'>
  <input name='places[2][city]' value='Chicago'>
  <input type='number' name='places[2][population]' value='2695598'>
</form>

การส่งแบบฟอร์มไปยังวิธีการเข้ารหัสของ JSONForms จะส่งคืนวัตถุต่อไปนี้ให้คุณ:

{
  "places": [
    {
      "city": "New York City",
      "population": 8175133
    },
    {
      "city": "Los Angeles",
      "population": 3792621
    },
    {
      "city": "Chicago",
      "population": 2695598
    }
  ]
}

นี่คือตัวอย่างของแบบฟอร์มของคุณ


ดูและทำงานได้ดีขอบคุณ มีเพียงสิ่งเดียวรุ่นย่อที่เรียกว่าไฟล์แผนที่ควรเป็นตัวเลือก imo
adi518

2

$( "form" ).bind( "submit", function(e) {
    e.preventDefault();
    
    console.log(  $(this).serializeObject() );    

    //console.log(  $(this).serialize() );
    //console.log(  $(this).serializeArray() );

});


$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();

    $.each( a, function() {
        if ( o[this.name] !== undefined) 
        {
            if ( ! o[this.name].push ) 
            {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        }
        else 
        {
            o[this.name] = this.value || '';
        }
    });

    return o;
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<form>

    <input type="radio" name="foo" value="1" checked="checked" />
    <input type="radio" name="foo" value="0" />
    <input name="bar" value="xxx" />

    <select name="this">
        <option value="hi" selected="selected">Hi</option>
        <option value="ho">Ho</option>
    </select>

    <input type="submit" value="Submit" />

</form>

Codepen


2

สำหรับผู้ที่ต้องการObjectใช้สตริงที่ต่อเนื่องกัน (เช่นที่ส่งคืนโดย$(form).serialize()และปรับปรุงเล็กน้อย$(form).serializeArray()) โปรดใช้รหัสด้านล่างนี้:

var Form = {
    _form: null,
    _validate: function(){
        if(!this._form || this._form.tagName.toLowerCase() !== "form") return false;
        if(!this._form.elements.length) return false;
    }, _loopFields: function(callback){
        var elements = this._form.elements;
        for(var i = 0; i < elements.length; i++){
            var element = form.elements[i];
            if(name !== ""){
                callback(this._valueOfField(element));
            }
        }
    }, _valueOfField: function(element){
        var type = element.type;
        var name = element.name.trim();
        var nodeName = element.nodeName.toLowerCase();
        switch(nodeName){
            case "input":
                if(type === "radio" || type === "checkbox"){
                    if(element.checked){
                        return element.value;
                    }
                }
                return element.value;
                break;
            case "select":
                if(type === "select-multiple"){
                    for(var i = 0; i < element.options.length; i++){
                        if(options[i].selected){
                            return element.value;
                        }
                    }
                }
                return element.value;
                break;
            case "button":
                switch(type){
                    case "reset": 
                    case "submit": 
                    case "button":
                        return element.value;
                        break;
                }
                break;
        } 
    }, serialize: function(form){
        var data = {};
        this._form = form;

        if(this._validate()){
            this._loopFields(function(value){
                if(value !== null) data[name] = value;
            });
        }
        return data;
    }
};

เพื่อรันมันเพียงใช้Form.serialize(form)และฟังก์ชั่นจะกลับมาObjectคล้ายกับนี้:

<!-- { username: "username", password: "password" } !-->
<input type="text" value="username">
<input type="password" value="password">

เป็นโบนัสหมายความว่าคุณไม่จำเป็นต้องติดตั้งjQueryทั้งชุดเพียงหนึ่งฟังก์ชันซีเรียลไลซ์


1

ฉันเขียนฟังก์ชั่นที่ดูแลช่องทำเครื่องหมายหลายช่องและหลายรายการที่เลือก ในกรณีเหล่านั้นจะส่งคืนอาร์เรย์

function getFormData(formId) {
    return $('#' + formId).serializeArray().reduce(function (obj, item) {
        var name = item.name,
            value = item.value;

        if (obj.hasOwnProperty(name)) {
            if (typeof obj[name] == "string") {
                obj[name] = [obj[name]];
                obj[name].push(value);
            } else {
                obj[name].push(value);
            }
        } else {
            obj[name] = value;
        }
        return obj;
    }, {});
}

1

แสดงฟิลด์องค์ประกอบอินพุตของแบบฟอร์มและไฟล์อินพุตเพื่อส่งแบบฟอร์มของคุณโดยไม่ต้องรีเฟรชหน้าเว็บและรับค่าทั้งหมดที่มีไฟล์รวมอยู่ในนั้น

<form id="imageUploadForm"   action="" method="post" enctype="multipart/form-data">
<input type="text" class="form-control" id="fname" name='fname' placeholder="First Name" >
<input type="text" class="form-control" name='lname' id="lname" placeholder="Last Name">
<input type="number" name='phoneno'  class="form-control" id="phoneno" placeholder="Phone Number">
<textarea class="form-control" name='address' id="address" rows="5" cols="5" placeholder="Your Address"></textarea>
<input type="file" name="file" id="file" >
<input type="submit" id="sub" value="Registration">					   
</form>
ที่หน้าปุ่มส่งจะส่งคำขอ Ajax ไปยังไฟล์ php ของคุณ
$('#imageUploadForm').on('submit',(function(e) 
{
     fname = $('#fname').val();
     lname =  $('#lname').val();
     address =  $('#address').val();
     phoneno =  $('#phoneno').val();
     file =  $('#file').val();
     e.preventDefault();
     var formData = new FormData(this);
     formData.append('file', $('#file')[0]);
     formData.append('fname',$('#fname').val());
     formData.append('lname',$('#lname').val());
     formData.append('phoneno',$('#phoneno').val());
     formData.append('address',$('#address').val());
     $.ajax({
		type:'POST',
                url: "test.php",
                //url: '<?php echo base_url().'edit_profile/edit_profile2';?>',

                data:formData,
                cache:false,
                contentType: false,
                processData: false,
                success:function(data)
                {
                     alert('Data with file are submitted !');

                }

     });

}))


FormData ใหม่ต้องการอะไรที่นี่?
Sahu V Kumar

1
@VishalKumarSahu ฉันกำลังอัปโหลดไฟล์ดังนั้นนั่นเป็นสาเหตุที่ฉันใช้ formData สำหรับสิ่งนั้น
Mohsin Shoukat

1
$(form).serializeArray().reduce(function (obj, item) {
      if (obj[item.name]) {
           if ($.isArray(obj[item.name])) {
               obj[item.name].push(item.value);
           } else {
                var previousValue = obj[item.name];
                obj[item.name] = [previousValue, item.value];
           }
      } else {
           obj[item.name] = item.value;
      }

     return obj;
}, {});

มันจะแก้ไขปัญหา: ไม่สามารถทำงานกับการเลือกหลายรายการได้


0

คุณไม่ถูกต้องทั้งหมด คุณไม่สามารถเขียน:

formObj[input.name] = input.value;

เนื่องจากวิธีนี้ถ้าคุณมีรายการแบบเลือกหลายรายการค่าจะถูกเขียนทับด้วยรายการสุดท้ายเนื่องจากมันถูกส่งเป็น: "param1": "value1", "param1": "value2"

ดังนั้นวิธีการที่ถูกต้องคือ:

if (formData[input.name] === undefined) {
    formData[input.name] = input.value;
}
else {
    var inputFieldArray = $.merge([], $.isArray(formData[input.name]) ? formData[input.name] : [formData[input.name]]);
    $.merge(inputFieldArray, [input.value]);
    formData[input.name] = $.merge([], inputFieldArray);
}

0

วิธีนี้ควรทำ มันเป็นอนุกรมข้อมูลในแบบฟอร์มแล้วแปลงเป็นวัตถุ ดูแลกลุ่มของช่องทำเครื่องหมายเช่นกัน

function getFormObj(formId) {
  var formParams = {};
  $('#' + formId)
    .serializeArray()
    .forEach(function(item) {
      if (formParams[item.name]) {
        formParams[item.name] = [formParams[item.name]];
        formParams[item.name].push(item.value)
      } else {
        formParams[item.name] = item.value
      }
    });
  return formParams;
}

ใช้งานได้กับช่องทำเครื่องหมาย แต่ไม่ใช้สำหรับปุ่มตัวเลือกที่ส่วนควบคุมใช้nameคุณสมบัติ
Kyle Falconer

0

นี่คือฟังก์ชั่นวานิลลา JS ที่ดีที่ฉันเขียนเพื่อดึงข้อมูลแบบฟอร์มเป็นวัตถุ นอกจากนี้ยังมีตัวเลือกสำหรับการเพิ่มส่วนเพิ่มเติมลงในวัตถุและสำหรับการล้างฟิลด์อินพุตแบบฟอร์ม

const extractFormData = ({ form, clear, add }) => {
  return [].slice.call(form.children).filter(node => node.nodeName === 'INPUT')
  .reduce((formData, input) => {
    const value = input.value
    if (clear) { input.value = '' }
    return {
      ...formData,
      [input.name]: value
    }
  }, add)
}

นี่คือตัวอย่างการใช้งานกับคำขอโพสต์:

submitGrudge(e) {
  e.preventDefault()

  const form = e.target
  const add = { id: Date.now(), forgiven: false }
  const grudge = extractFormData({ form, add, clear: true })

  // grudge = {
  //  "name": "Example name",
  //  "offense": "Example string",
  //  "date": "2017-02-16",
  //  "id": 1487877281983,
  //  "forgiven": false
  // }

  fetch('http://localhost:3001/api/grudge', {
    method: 'post',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(grudge)
  })
    .then(response => response.json())
    .then(grudges => this.setState({ grudges }))
    .catch(err => console.log('error: ', err))
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.