แปลงข้อมูลแบบฟอร์มเป็นวัตถุ JavaScript ด้วย jQuery


1624

ฉันจะแปลงองค์ประกอบทั้งหมดของฟอร์มเป็นวัตถุ JavaScript ได้อย่างไร

ฉันต้องการมีวิธีสร้างวัตถุ JavaScript จากแบบฟอร์มของฉันโดยอัตโนมัติโดยไม่ต้องวนซ้ำแต่ละองค์ประกอบ ฉันไม่ต้องการสตริงตามที่ส่งคืนโดย$('#formid').serialize();และฉันไม่ต้องการแผนที่ที่ส่งคืนโดย$('#formid').serializeArray();


16
เพราะสิ่งแรกที่ส่งกลับสตริงเหมือนกับสิ่งที่คุณจะได้รับถ้าคุณส่งแบบฟอร์มด้วยวิธีการ GET และอันที่สองให้อาร์เรย์ของออบเจ็กต์แต่ละอันมีค่าชื่อคู่ ฉันต้องการที่ถ้าฉันมีเขตข้อมูลที่ชื่อว่า "อีเมล" ฉันได้รับวัตถุที่จะช่วยให้ฉันสามารถดึงค่าที่มี obj.email ด้วย serializeArray () ฉันต้องทำอะไรบางอย่างเช่น obj [indexOfElement] .value
Yisroel

2
@James - คำตอบที่ยอมรับได้โดยใช้ไลบรารี JSON-js ของ D. Crockford นี่คือตัวอย่าง: github.com/tleese22/google-app-engine-jappstart/blob/master/src/…
Taylor Leese

4
@Taylor ใช่ฉันพูดว่าคำตอบที่ถูกต้องใช้ฟังก์ชั่น lib และ Tobias ของ Crockford เช่น: JSON.stringify ($ ('myForm') serializeObject ())
James McCormack

5
@Jonz - มีเหตุผลอื่นนอกเหนือจากการส่ง / ส่งสำหรับการใช้องค์ประกอบแบบฟอร์ม หากคุณกำลังยกระดับหนักด้วยค่าฟอร์มภายใน JavaScript (เช่นแอปหน้าเดียว) มันมีประโยชน์มากที่จะให้มันอยู่ในรูปแบบวัตถุสำหรับการเข้าถึงและจัดการ นอกจากนี้สตริงการโพสต์ HTTP และรับเคียวรีไม่ได้เป็นรูปแบบเฉพาะสำหรับการย้ายข้อมูล
Patrick M

3
js ที่ดีฉันเจอ >> github.com/marioizquierdo/jquery.serializeJSON
Bongs

คำตอบ:


1657

serializeArrayทำเช่นนั้นแล้ว คุณต้องนวดข้อมูลในรูปแบบที่คุณต้องการ:

function objectifyForm(formArray) {//serialize data function

  var returnArray = {};
  for (var i = 0; i < formArray.length; i++){
    returnArray[formArray[i]['name']] = formArray[i]['value'];
  }
  return returnArray;
}

ระวังช่องที่ซ่อนอยู่ซึ่งมีชื่อเหมือนกับอินพุตจริงเนื่องจากจะถูกเขียนทับ


4
อย่างที่ tvanfosson พูดทำไมทำซ้ำมากกว่าคอลเลคชั่นสองครั้ง
Yisroel

69
คุณหมายถึง "ทำไมใช้ serializeArray เพื่อรับข้อมูลตั้งแต่แรก?" เนื่องจาก serializeArray ได้ถูกเขียนไปแล้วจะมีการทดสอบหน่วยในเบราว์เซอร์หลายตัวและสามารถปรับปรุงในทางทฤษฎีใน jQuery รุ่นที่ใหม่กว่า ยิ่งคุณเขียนรหัสน้อยลงเท่าไรก็จะต้องเข้าถึงสิ่งที่ไม่สอดคล้องกันเช่นองค์ประกอบ DOM โดยตรงยิ่งรหัสของคุณจะมั่นคง
Tobias Cohen

56
ถูกเตือน serializeArray () จะไม่รวมองค์ประกอบที่ถูกปิดใช้งาน ฉันมักจะปิดการใช้งานองค์ประกอบการป้อนข้อมูลที่ซิงค์กับองค์ประกอบอื่น ๆ ในหน้า แต่ฉันยังต้องการให้พวกเขารวมอยู่ในวัตถุอนุกรมของฉัน คุณควรใช้บางอย่างที่ดีกว่า$.map( $("#container :input"), function(n, i) { /* n.name and $(n).val() */ } );ถ้าคุณจำเป็นต้องรวมองค์ประกอบที่ถูกปิดใช้งาน
Samuel Meacham

22
@TobiasCohen มันไม่ได้จัดการfoo[bar]-type อินพุตตามที่คาดไว้ไม่ต้องพูดถึงชื่อพันธุ์อื่น ๆ ส่วนใหญ่ หลังจากผิดหวังมากกับวิธีแก้ไขปัญหาตื้น ๆ นี้ฉันลงเอยด้วยการเขียนปลั๊กอิน jQuery ของฉันเอง - รายละเอียดในคำตอบที่ฉันให้ไว้สำหรับคำถามนี้
maček

6
@macek ฉันรู้ว่านี่เป็นเวลาไม่กี่เดือน แต่เมื่อใดที่อาร์เรย์ใช้ดัชนีที่ไม่ใช่ตัวเลขมาตั้งแต่เมื่อใด ไม่มีใครควรตั้งชื่ออินพุต foo [bar] และหวังว่าจะถือว่าเป็นอาร์เรย์ คุณกำลังทำให้อาร์เรย์และแฮชสับสนหรือไม่? ใช่ [] เป็นที่เข้าใจกันโดยทั่วไปว่าเป็น accessor แต่ไม่เพียง แต่สำหรับอาร์เรย์เท่านั้น นอกจากนี้ยังบอกว่ามันเป็น HTML ที่ถูกต้อง แต่ไม่ได้อยู่ในสเป็ค HTML ที่ขัดแย้งกัน ใช่เบราว์เซอร์อาจไม่สำลัก แต่มีผู้ให้บริการเว็บจำนวนมากที่รู้วิธีกำจัดความเป็นอาเรย์ ทำไม? เพราะมันไม่ได้อยู่ในสเป็ค HTML ดังนั้นจึงไม่ถูกต้องแน่นอน
kroehre

446

แปลงฟอร์มเป็น JSON เหมือนเจ้านาย


แหล่งที่มาปัจจุบันคือบน GitHubและซุ้ม

$ bower ติดตั้ง jquery-serialize-object


รหัสต่อไปนี้คือตอนนี้เลิกใช้

รหัสต่อไปนี้สามารถทำงานกับชื่ออินพุตทุกประเภท และจัดการกับมันตามที่คุณคาดหวัง

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

<!-- All of these will work! -->
<input name="honey[badger]" value="a">
<input name="wombat[]" value="b">
<input name="hello[panda][]" value="c">
<input name="animals[0][name]" value="d">
<input name="animals[0][breed]" value="e">
<input name="crazy[1][][wonky]" value="f">
<input name="dream[as][vividly][as][you][can]" value="g">
// Output
{
  "honey":{
    "badger":"a"
  },
  "wombat":["b"],
  "hello":{
    "panda":["c"]
  },
  "animals":[
    {
      "name":"d",
      "breed":"e"
    }
  ],
  "crazy":[
    null,
    [
      {"wonky":"f"}
    ]
  ],
  "dream":{
    "as":{
      "vividly":{
        "as":{
          "you":{
            "can":"g"
          }
        }
      }
    }
  }
}

การใช้

$('#my-form').serializeObject();

The Sorcery (JavaScript)

(function($){
    $.fn.serializeObject = function(){

        var self = this,
            json = {},
            push_counters = {},
            patterns = {
                "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
                "key":      /[a-zA-Z0-9_]+|(?=\[\])/g,
                "push":     /^$/,
                "fixed":    /^\d+$/,
                "named":    /^[a-zA-Z0-9_]+$/
            };


        this.build = function(base, key, value){
            base[key] = value;
            return base;
        };

        this.push_counter = function(key){
            if(push_counters[key] === undefined){
                push_counters[key] = 0;
            }
            return push_counters[key]++;
        };

        $.each($(this).serializeArray(), function(){

            // Skip invalid keys
            if(!patterns.validate.test(this.name)){
                return;
            }

            var k,
                keys = this.name.match(patterns.key),
                merge = this.value,
                reverse_key = this.name;

            while((k = keys.pop()) !== undefined){

                // Adjust reverse_key
                reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

                // Push
                if(k.match(patterns.push)){
                    merge = self.build([], self.push_counter(reverse_key), merge);
                }

                // Fixed
                else if(k.match(patterns.fixed)){
                    merge = self.build([], k, merge);
                }

                // Named
                else if(k.match(patterns.named)){
                    merge = self.build({}, k, merge);
                }
            }

            json = $.extend(true, json, merge);
        });

        return json;
    };
})(jQuery);

17
ดังนั้นมันใช้งานได้ดี แต่มันมีชื่อผิด: มันจะไม่ส่งคืน JSON ดังที่ชื่อมีความหมาย แต่จะส่งคืนวัตถุตามตัวอักษร นอกจากนี้สิ่งสำคัญคือต้องตรวจสอบ hasOwnProperty ไม่เช่นนั้นอาร์เรย์ของคุณจะมีอะไรที่แนบมากับต้นแบบเช่น: {numbers: ["1", "3", indexOf: function () {... }]}
frontendbeauty

5
@ frontendbeauty จริงๆแล้ว toJSON เป็นสิ่งที่สเปคบอกว่าควรเรียกว่า: developer.mozilla.org/en/JSON#toJSON()_methodผู้เรียกชื่อผิดที่โชคร้าย
Ryan Florence

4
@Marek ผมได้ทดสอบสำหรับที่นี่ในjsfiddle เคล็ดลับคือตั้งชื่อตัวเลือกของคุณอย่างถูกต้อง <select name="foo" multiple="multiple">จะไม่ทำงานในสถานการณ์ใด ๆ อย่างไรก็ตาม, ถ้าคุณใช้[], <select name="bar[]" multiple="multiple">มันจะใช้ได้ดี :)
maček

3
ต้องการชี้ให้เห็นว่าgithub.com/serbanghita/formToObjectเป็นวิธี JavaScript ที่คล้ายกัน (ไม่จำเป็นต้องใช้ไลบรารีของบุคคลที่สาม) ที่ทำงานเดียวกัน รองรับ 'หลาย' ละเว้นองค์ประกอบ 'ปิดใช้งาน'
Șerban Ghiță

8
โซลูชันนี้ควรอยู่ด้านบนเนื่องจากเกี่ยวข้องกับปัญหาของคีย์ที่ซ้อนกันเป็นชื่อองค์ประกอบของฟอร์ม
SquareCat

283

มีอะไรผิดปกติกับ:

var data = {};
$(".form-selector").serializeArray().map(function(x){data[x.name] = x.value;}); 

2
@LayZee - หากไม่มีสิ่งใดถูกเลือกทำไมคุณถึงต้องการที่ส่วนท้ายของคุณ หากคุณต้องเลือกตัวเลือกให้ตรวจสอบอินพุตก่อนทำการจัดลำดับ
Dementic

21
ถ้าคุณไม่ได้กลับมาอะไรทำไมคุณไม่เพียงแค่ใช้.eachแทน.map??
azerafati

10
มันง่ายมากเพราะไร้เดียงสาสุด ๆ ... ไม่จัดการช่องทำเครื่องหมายด้วยชื่อเดียวกัน แต่ละครั้งมันจะแทนที่รายการที่ตรวจสอบก่อนหน้า คุณจะต้องมีการตรวจจับประเภทอินพุตบางอย่างเพื่อให้แน่ใจว่ามันถูกต่อเนื่องอย่างถูกต้อง
Joshua F. Rountree

5
หากคุณต้องการโซลูชัน jQuery ที่แท้จริงคุณสามารถใช้var form = {}; $.each($(this).serializeArray(), function (i, field) { form[field.name] = field.value || ""; });
tfmontague

42
$(this).serializeArray().reduce(function(m,o){ m[o.name] = o.value; return m;}, {})
ไซต์

103

โซลูชันของ Tobias Cohen เวอร์ชันที่แก้ไขแล้ว หนึ่งนี้ได้อย่างถูกต้องจัดการค่า falsy ชอบและ0''

jQuery.fn.serializeObject = function() {
  var arrayData, objectData;
  arrayData = this.serializeArray();
  objectData = {};

  $.each(arrayData, function() {
    var value;

    if (this.value != null) {
      value = this.value;
    } else {
      value = '';
    }

    if (objectData[this.name] != null) {
      if (!objectData[this.name].push) {
        objectData[this.name] = [objectData[this.name]];
      }

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

  return objectData;
};

และเวอร์ชัน CoffeeScript เพื่อความสะดวกในการเขียนโค้ดของคุณ:

jQuery.fn.serializeObject = ->
  arrayData = @serializeArray()
  objectData = {}

  $.each arrayData, ->
    if @value?
      value = @value
    else
      value = ''

    if objectData[@name]?
      unless objectData[@name].push
        objectData[@name] = [objectData[@name]]

      objectData[@name].push value
    else
      objectData[@name] = value

  return objectData

ในกาแฟที่แรกถ้าบล็อกสามารถสั้นลงไปvalue = @value ? ''
nzifnab

และหากคุณพยายามทำให้เป็นแบบฟอร์มคล้ายกับ Rails คุณอาจต้องการลบองค์ประกอบขององค์ประกอบออกจากคีย์ที่สร้างขึ้น เพื่อให้บรรลุนั้นฉันได้เพิ่มพารามิเตอร์ใหม่keyMapและบรรทัดต่อไปนี้: key = if keyMap? then keyMap(@name) else @name. (name) -> name.match(/\[([^\]]+)]/)[1]ตอนนี้คุณสามารถส่งผ่านฟังก์ชั่นการทำแผนที่เช่น และจากนั้นหนึ่งจะต้องมีการเปลี่ยนแปลงตามมาทั้งหมด@nameจะkeyแน่นอน
Damir Zekić

@ DamirZekićถ้าองค์ประกอบรากของคุณคุณก็สามารถทำpost $('form').serializeObject().postไม่จำเป็นต้องทำแผนที่แฟนซี
maček

@ DamirZekićบรรทัดนี้กำลังทำอะไร if (!objectData[this.name].push)??
kittu

@kittu มันกำลังตรวจสอบว่าobjectData[this.name]มีวิธีการพุช (โดยประมาณหรือว่าเป็นอาร์เรย์) ถ้ามันเป็นอาร์เรย์มันจะผลักดันค่าถ้าไม่ใช่อาร์เรย์มันจะแปลงเป็นอาร์เรย์เพื่อให้หลายค่าที่มีคีย์เดียวกันจะถูกรวมเข้ากับอาร์เรย์
Daniel X Moore

63

ฉันชอบใช้Array.prototype.reduceเพราะมันเป็นหนึ่งซับและมันไม่ได้พึ่งพาUnderscore.jsหรือชอบ:

$('#formid').serializeArray()
    .reduce(function(a, x) { a[x.name] = x.value; return a; }, {});

นี่คล้ายกับคำตอบที่ใช้Array.prototype.mapแต่คุณไม่จำเป็นต้องทำให้ขอบเขตของคุณยุ่งเหยิงด้วยตัวแปรวัตถุเพิ่มเติม การช็อปปิ้งครบวงจร

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


มันค่อนข้างหรูหรา แต่น่าสังเกตว่าarray.prototype.reduce()ไม่มีใน IE8 เนื่องจากเป็นส่วนหนึ่งของข้อกำหนด ECMAScript 5 ดังนั้นถ้าคุณต้องการการสนับสนุน IE8 คุณจะต้องการใช้polyfillหรือสารละลายอื่นทั้งหมด
gfullam

3
จริง แต่มันง่ายพอที่จะเติมได้ นอกจากนี้อาการปวดหัวของ IE8 เกือบจะจบลงขอบคุณการทำงานที่ยอดเยี่ยมของ Microsoft กับ IE11 Enterprise Mode - ฉันไม่ตอบสนองต่อผู้ใช้แต่ละคนที่มี IE8 อีกต่อไป แต่เมื่อองค์กรที่มีพนักงาน 10,000 คนที่ใช้ IE8 มา ... โชคดีที่ Microsoft กำลังทำงานอย่างหนักเพื่อแก้ไขปัญหานั้น
Ethan Brown

1
คุณควรให้คนไอทีของคุณดูในโหมด IE11 Enterprise - มันมีเบราว์เซอร์ที่ทันสมัยและวิธีการเรียกใช้แอพที่รองรับ IE8 การเคลื่อนไหวอย่างชาญฉลาดในส่วนของ Microsoft: howtogeek.com/184634/…
Ethan Brown

30

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

$('form.myform').submit(function () {
  var $this = $(this)
    , viewArr = $this.serializeArray()
    , view = {};

  for (var i in viewArr) {
    view[viewArr[i].name] = viewArr[i].value;
  }

  //Do stuff with view object here (e.g. JSON.stringify?)
});

4
ไม่ได้จัดการกับข้อมูลในแบบฟอร์มที่ซ้อนกันนั่นคือเหตุผลที่คำตอบซับซ้อนกว่า
frontendbeauty

ทำงานได้ดีสำหรับฉัน ต้องการพื้นที่เก็บข้อมูลของคู่คีย์ - ค่า stringifying แล้วบันทึกไปยัง localStorage หรือคุกกี้ทำงานได้สวย
เกร็ก Pettit

23

ไม่มีทางที่จะทำสิ่งนี้ได้โดยไม่ต้องตรวจสอบองค์ประกอบแต่ละอย่าง สิ่งที่คุณอยากรู้คือ "มีคนอื่นเขียนวิธีที่แปลงแบบฟอร์มเป็นวัตถุ JSON แล้วหรือยัง?" สิ่งต่อไปนี้ควรใช้งานได้โปรดทราบว่าจะให้องค์ประกอบแบบฟอร์มที่จะส่งคืนทาง POST เท่านั้น (ต้องมีชื่อ) นี้จะไม่ได้ทดสอบ

function formToJSON( selector )
{
     var form = {};
     $(selector).find(':input[name]:enabled').each( function() {
         var self = $(this);
         var name = self.attr('name');
         if (form[name]) {
            form[name] = form[name] + ',' + self.val();
         }
         else {
            form[name] = self.val();
         }
     });

     return form;
}

จริงฉันชอบปลั๊กอินที่จะทำสิ่งนี้ให้ฉัน ข้อ จำกัด ของการมีชื่อไม่ใช่เรื่องใหญ่ สิ่งนี้จะดึงเขตข้อมูลทั้งหมดในแบบฟอร์มรวมถึง textareas และเลือก?
Yisroel

ไม่แน่ใจว่าคุณต้องการบัญชีสำหรับ [ปิดใช้งาน] แต่ฉันไม่คิดว่าควรจะส่ง / รับ
Meder omuraliev

อาจจะง่ายในการใช้ serializeArray () เพื่อให้ได้แผนที่และจากนั้นใช้รหัสคล้ายกับข้างต้นเพื่อแปลงเป็นวัตถุ JSON ปกติวิธีนี้ผมไม่ได้ติดต่อกับรูปแบบของตัวเอง
ยีส

2
การใช้ serializedArray จะใช้งานได้ แต่โดยหลักแล้วคุณจะต้องวนซ้ำคอลเลกชันสองครั้ง - หนึ่งครั้งเพื่อสร้างอาร์เรย์จากนั้นใช้อาร์เรย์ ฉันไม่เห็นความต้องการสิ่งนั้น
tvanfosson

ฉันจะปรับตัวเลือกสำหรับเปิด / ปิดการใช้งาน
tvanfosson


19

ฉันตรวจสอบว่ามีปัญหากับคำตอบอื่น ๆ ทั้งหมด, ว่าถ้าชื่ออินพุทเป็นอาร์เรย์, เช่นname[key]นั้น, มันควรจะสร้างเช่นนี้:

name:{ key : value }


ตัวอย่างเช่น:หากคุณมีรูปแบบ HTML คล้ายกับแบบฟอร์มด้านล่าง:

<form>
    <input name="name" value="value" >
    <input name="name1[key1]" value="value1" >
    <input name="name2[key2]" value="value2" >
    <input name="name3[key3]" value="value3" >
</form>

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

{
    name  : 'value',
    name1 : { key1 : 'value1' },
    name2 : { key2 : 'value2' },
    name3 : { key2 : 'value2' }
}

$.fn.getForm2obj = function() {
  var _ = {};
  $.map(this.serializeArray(), function(n) {
    const keys = n.name.match(/[a-zA-Z0-9_]+|(?=\[\])/g);
    if (keys.length > 1) {
      let tmp = _;
      pop = keys.pop();
      for (let i = 0; i < keys.length, j = keys[i]; i++) {
        tmp[j] = (!tmp[j] ? (pop == '') ? [] : {} : tmp[j]), tmp = tmp[j];
      }
      if (pop == '') tmp = (!Array.isArray(tmp) ? [] : tmp), tmp.push(n.value);
      else tmp[pop] = n.value;
    } else _[keys.pop()] = n.value;
  });
  return _;
}
console.log($('form').getForm2obj());
$('form input').change(function() {
  console.clear();
  console.log($('form').getForm2obj());
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<form>
  <input name="name" value="value">
  <input type="checkbox" name="name1[]" value="1" checked="checked">1
  <input type="checkbox" name="name1[]" value="2">2
  <input type="checkbox" name="name1[]" value="3">3<br>
  <input type="radio" name="gender" value="male" checked="checked">male
  <input type="radio" name="gender" value="female"> female
  <input name="name2[key1]" value="value1">
  <input name="one[another][another_one]" value="value4">
  <input name="name3[1][name]" value="value4">
  <input name="name3[2][name]" value="value4">
  <input name="[]" value="value5">
</form>


คำตอบนี้ครอบคลุมถึงกรณีที่กล่าวถึง แต่ไม่ครอบคลุมถึงกรณีเช่นกล่องกาเครื่องหมาย [] หรือแม้แต่อีก [หนึ่ง] [another_one]
Leonardo Beal

1
@ LeonardoBeal ฉันแก้ไข ans ของฉัน .. ตรวจสอบตอนนี้ .. !
Bhavik Hirani

ฉันเป็นผู้ลงคะแนนและฉันevalไม่ได้ลงคะแนนเพราะไม่ควรใช้ในลักษณะนี้เพราะevalเมื่อใช้ในวิธีนี้ส่งเสริมการปฏิบัติที่ไม่น่าเชื่อถืออย่างน่าเว่อร์ไร้ประสิทธิภาพและอาจไม่ปลอดภัย
Jack Giffin

2
ฉันไม่เห็นด้วยว่านี่เป็นคำตอบที่ดี และโปรดเมื่อคุณเขียนคำตอบให้โค้ดของคุณอธิบายตนเองหรืออธิบายมัน this.c = function(k,v){ eval("c = typeof "+k+";"); if(c == 'undefined') _t.b(k,v);}สั้นและไม่อธิบาย ผู้พัฒนาที่มีประสบการณ์น้อยจะคัดลอกสิ่งนี้โดยไม่เข้าใจว่าทำไมและวิธีการทำงาน
iRaS

2
@JackGiffin ลองดูรหัสใหม่ของฉันตอนนี้เพราะฉันได้ลบeval()รหัสออกไปแล้ว
Bhavik Hirani

17

ตกลงฉันรู้ว่านี่มีคำตอบที่ได้รับการตอบกลับสูง แต่คำถามที่คล้ายกันอีกข้อหนึ่งถูกถามเมื่อเร็ว ๆ นี้และฉันก็ถูกนำไปยังคำถามนี้เช่นกัน ฉันต้องการเสนอวิธีแก้ปัญหาของฉันเช่นกันเพราะเป็นข้อได้เปรียบเหนือโซลูชันที่ยอมรับ: คุณสามารถรวมองค์ประกอบของฟอร์มที่ปิดใช้งานได้ (ซึ่งบางครั้งก็มีความสำคัญขึ้นอยู่กับการทำงานของ UI)

นี่คือคำตอบของฉันจากคำถาม SO อื่น ๆ :

เริ่มแรกเราใช้serializeArray()วิธีของ jQuery แต่ไม่รวมองค์ประกอบของฟอร์มที่ปิดใช้งาน เรามักจะปิดการใช้งานองค์ประกอบของรูปแบบที่ "ซิงค์" ไปยังแหล่งข้อมูลอื่น ๆ บนหน้า แต่เรายังต้องรวมข้อมูลในวัตถุที่ต่อเนื่องกันของเรา ดังนั้นserializeArray()จะออก เราใช้:inputตัวเลือกเพื่อรับองค์ประกอบอินพุตทั้งหมด (ทั้งเปิดใช้งานและปิดใช้งาน) ในคอนเทนเนอร์ที่กำหนดและจากนั้น$.map()เพื่อสร้างวัตถุของเรา

var inputs = $("#container :input");
var obj = $.map(inputs, function(n, i)
{
    var o = {};
    o[n.name] = $(n).val();
    return o;
});
console.log(obj);

โปรดทราบว่าการดำเนินการนี้อินพุตของคุณแต่ละรายการจะต้องมีnameแอตทริบิวต์ซึ่งจะเป็นชื่อของคุณสมบัติของวัตถุผลลัพธ์

นั่นคือการดัดแปลงเล็กน้อยจากสิ่งที่เราใช้ เราจำเป็นต้องสร้างวัตถุที่มีโครงสร้างเป็น. NET IDictionary ดังนั้นเราจึงใช้สิ่งนี้: (ฉันให้ที่นี่ในกรณีที่มันมีประโยชน์)

var obj = $.map(inputs, function(n, i)
{
    return { Key: n.name, Value: $(n).val() };
});
console.log(obj);

ฉันชอบโซลูชันทั้งสองนี้เพราะใช้ง่ายของ$.map()ฟังก์ชั่นและคุณสามารถควบคุมตัวเลือกของคุณได้อย่างสมบูรณ์ (ดังนั้นองค์ประกอบใดที่คุณจะได้รับรวมถึงวัตถุที่เป็นผลลัพธ์ของคุณ) นอกจากนี้ไม่จำเป็นต้องมีปลั๊กอินเพิ่มเติม jQuery แบบธรรมดาธรรมดา


6
ฉันลองสิ่งนี้ในโครงการโดยใช้mapสิ่งนี้สร้างอาร์เรย์ของวัตถุที่มีคุณสมบัติเดียวมันไม่ยุบคุณสมบัติทั้งหมดเป็นวัตถุเดียว
joshperry

16

ฟังก์ชันนี้ควรจัดการกับอาร์เรย์หลายมิติพร้อมกับองค์ประกอบหลายรายการที่มีชื่อเดียวกัน

ฉันใช้มันมาสองสามปีแล้ว:

jQuery.fn.serializeJSON=function() {
  var json = {};
  jQuery.map(jQuery(this).serializeArray(), function(n, i) {
    var _ = n.name.indexOf('[');
    if (_ > -1) {
      var o = json;
      _name = n.name.replace(/\]/gi, '').split('[');
      for (var i=0, len=_name.length; i<len; i++) {
        if (i == len-1) {
          if (o[_name[i]]) {
            if (typeof o[_name[i]] == 'string') {
              o[_name[i]] = [o[_name[i]]];
            }
            o[_name[i]].push(n.value);
          }
          else o[_name[i]] = n.value || '';
        }
        else o = o[_name[i]] = o[_name[i]] || {};
      }
    }
    else {
      if (json[n.name] !== undefined) {
        if (!json[n.name].push) {
          json[n.name] = [json[n.name]];
        }
        json[n.name].push(n.value || '');
      }
      else json[n.name] = n.value || '';      
    }
  });
  return json;
};


14

หนึ่งซับ (ไม่มีการพึ่งพานอกเหนือจาก jQuery) ใช้การเชื่อมวัตถุคงที่สำหรับฟังก์ชั่นที่ส่งผ่านไปยังmapวิธีการ

$('form').serializeArray().map(function(x){this[x.name] = x.value; return this;}.bind({}))[0]

มันทำอะไร

"id=2&value=1&comment=ok" => Object { id: "2", value: "1", comment: "ok" }

เหมาะสำหรับแอปเว็บโปรเกรสซีฟ (แอปหนึ่งสามารถรองรับทั้งการส่งแบบฟอร์มปกติและการร้องขอ ajax)


12

ใช้:

function form_to_json (selector) {
  var ary = $(selector).serializeArray();
  var obj = {};
  for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
  return obj;
}

เอาท์พุท:

{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}

7

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

var values = $(this).serialize(),
attributes = {};

values.replace(/([^&]+)=([^&]*)/g, function (match, name, value) {
    attributes[name] = value;
});

7

จากคำตอบที่เก่ากว่า :

$('form input, form select').toArray().reduce(function(m,e){m[e.name] = $(e).val(); return m;},{})

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

ข้อแตกต่างเพียงเล็กน้อยกับคำตอบที่เชื่อมโยงคือไม่มีข้อมูลที่จำเป็นในการสร้างอินสแตนซ์และreduceส่งคืนออบเจกต์ สิ่งนี้ไม่ได้เป็นอิสระเนื่องจากมาtoArrayจาก jQuery
ไซต์

6

ฉันพบปัญหาเกี่ยวกับรหัสของ Tobias Cohen (ฉันไม่มีคะแนนมากพอที่จะแสดงความคิดเห็นโดยตรง) ซึ่งวิธีนี้เหมาะกับฉัน หากคุณมีตัวเลือกสองตัวเลือกที่มีชื่อเหมือนกันทั้งคู่มีค่า = "" รหัสเดิมจะสร้าง "ชื่อ": "" แทน "ชื่อ": ["", ""]

ฉันคิดว่าสิ่งนี้สามารถแก้ไขได้โดยการเพิ่ม "|| o [this.name] == ''" หากเงื่อนไขแรก:

$.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name] || o[this.name] == '') {
            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;
};

6

ด้วยการใช้โซลูชันของmačekฉันได้ปรับเปลี่ยนให้ทำงานกับวิธีที่ ASP.NET MVC จัดการกับวัตถุที่ซ้อนกัน / ซับซ้อนในรูปแบบเดียวกัน สิ่งที่คุณต้องทำคือแก้ไขชิ้นส่วนที่ตรวจสอบได้เป็น:

"validate": /^[a-zA-Z][a-zA-Z0-9_]*((?:\[(?:\d*|[a-zA-Z0-9_]+)\])*(?:\.)[a-zA-Z][a-zA-Z0-9_]*)*$/,

สิ่งนี้จะจับคู่แล้วจับคู่องค์ประกอบที่มีชื่ออย่างถูกต้อง:

<input type="text" name="zooName" />

และ

<input type="text" name="zooAnimals[0].name" />

5

วิธีที่ง่ายที่สุดและถูกต้องที่สุดที่ฉันพบสำหรับปัญหานี้คือการใช้ปลั๊กอินบาร์บีคิวหรือนี้หนึ่ง (ซึ่งเป็นเรื่องเกี่ยวกับ 0.5K ไบต์ขนาด)

มันยังทำงานร่วมกับอาร์เรย์หลายมิติ

$.fn.serializeObject = function()
{
	return $.deparam(this.serialize());
};


ดูเหมือนว่าจะทำงานได้ดี มีพื้นที่เก็บข้อมูลทางเลือกสำหรับ jquery-deparamที่มีไฟล์คำอธิบายสำหรับ bower และ npm
Alf Eaton

4

มีปลั๊กอินจะทำแค่นั้นสำหรับ jQuery, jquery.serializeJSON ตอนนี้ฉันใช้มันสำเร็จแล้ว มันทำงานเหมือนจับใจ



3

ฉันชอบวิธีนี้เพราะ: คุณไม่ต้องวนซ้ำคอลเลคชั่น 2 ตัวคุณสามารถทำสิ่งอื่นนอกเหนือจาก "ชื่อ" และ "ค่า" หากคุณต้องการและคุณสามารถชำระค่าของคุณให้สะอาดก่อนที่จะเก็บไว้ในวัตถุ หากคุณมีค่าเริ่มต้นที่คุณไม่ต้องการจัดเก็บเช่น)

$.formObject = function($o) {
    var o = {},
        real_value = function($field) {
            var val = $field.val() || "";

            // additional cleaning here, if needed

            return val;
        };

    if (typeof o != "object") {
        $o = $(o);
    }

    $(":input[name]", $o).each(function(i, field) {
        var $field = $(field),
            name = $field.attr("name"),
            value = real_value($field);

        if (o[name]) {
            if (!$.isArray(o[name])) {
                o[name] = [o[name]];
            }

            o[name].push(value);
        }

        else {
            o[name] = value;
        }
    });

    return o;
}

ใช้อย่างนั้น:

var obj = $.formObject($("#someForm"));

ผ่านการทดสอบใน Firefox เท่านั้น


3

เปลี่ยนทุกอย่างให้เป็นวัตถุ (ไม่ผ่านการทดสอบหน่วย)

<script type="text/javascript">
string = {};

string.repeat = function(string, count)
{
    return new Array(count+1).join(string);
}

string.count = function(string)
{
    var count = 0;

    for (var i=1; i<arguments.length; i++)
    {
        var results = string.match(new RegExp(arguments[i], 'g'));
        count += results ? results.length : 0;
    }

    return count;
}

array = {};

array.merge = function(arr1, arr2)
{
    for (var i in arr2)
    {
        if (arr1[i] && typeof arr1[i] == 'object' && typeof arr2[i] == 'object')
            arr1[i] = array.merge(arr1[i], arr2[i]);
        else
            arr1[i] = arr2[i]
    }

    return arr1;
}

array.print = function(obj)
{
    var arr = [];
    $.each(obj, function(key, val) {
        var next = key + ": ";
        next += $.isPlainObject(val) ? array.print(val) : val;
        arr.push( next );
      });

    return "{ " +  arr.join(", ") + " }";
}

node = {};

node.objectify = function(node, params)
{
    if (!params)
        params = {};

    if (!params.selector)
        params.selector = "*";

    if (!params.key)
        params.key = "name";

    if (!params.value)
        params.value = "value";

    var o = {};
    var indexes = {};

    $(node).find(params.selector+"["+params.key+"]").each(function()
    {
        var name = $(this).attr(params.key),
            value = $(this).attr(params.value);

        var obj = $.parseJSON("{"+name.replace(/([^\[]*)/, function()
        {
            return '"'+arguments[1]+'"';
        }).replace(/\[(.*?)\]/gi, function()
        {
            if (arguments[1].length == 0)
            {
                var index = arguments[3].substring(0, arguments[2]);
                indexes[index] = indexes[index] !== undefined ? indexes[index]+1 : 0;

                return ':{"'+indexes[index]+'"';
            }
            else
                return ':{"'+escape(arguments[1])+'"';
        })+':"'+value.replace(/[\\"]/gi, function()
        {
            return "\\"+arguments[0]; 
        })+'"'+string.repeat('}', string.count(name, ']'))+"}");

        o = array.merge(o, obj);
    });

    return o;
}
</script>

ผลลัพธ์ของการทดสอบ:

$(document).ready(function()
{
    console.log(array.print(node.objectify($("form"), {})));
    console.log(array.print(node.objectify($("form"), {selector: "select"})));
});

บน

<form>
    <input name='input[a]' type='text' value='text'/>
    <select name='input[b]'>
        <option>select</option>
    </select>

    <input name='otherinput[c][a]' value='a'/>
    <input name='otherinput[c][]' value='b'/>
    <input name='otherinput[d][b]' value='c'/>
    <input name='otherinput[c][]' value='d'/>

    <input type='hidden' name='anotherinput' value='hidden'/>
    <input type='hidden' name='anotherinput' value='1'/>

    <input type='submit' value='submit'/>
</form>

จะให้ผลผลิต:

{ input: { a: text, b: select }, otherinput: { c: { a: a, 0: b, 1: d }, d: { b: c } }, anotherinput: 1 }
{ input: { b: select } }

3

ฉันพบปัญหากับโซลูชันที่เลือก

เมื่อใช้รูปแบบที่มีชื่อตามอาร์เรย์ฟังก์ชั่น jQuery serializeArray () จริงตาย

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

เนื่องจากฉันต้องการทำให้ฟอร์มเป็นด่างโดยไม่ต้องใช้ฟังก์ชันฐานสัมบูรณ์นี้ฉันจึงตัดสินใจเขียน seralizeArray ของฉันเอง:

        var $vals = {};

        $("#video_edit_form input").each(function(i){
            var name = $(this).attr("name").replace(/editSingleForm\[/i, '');

            name = name.replace(/\]/i, '');

            switch($(this).attr("type")){
                case "text":
                    $vals[name] = $(this).val();
                    break;
                case "checkbox":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                case "radio":
                    if($(this).attr("checked")){
                        $vals[name] = $(this).val();
                    }
                    break;
                default:
                    break;
            }
        });

โปรดทราบ: วิธีนี้ใช้ได้กับการส่งแบบฟอร์มนอก () ดังนั้นหากเกิดข้อผิดพลาดในส่วนที่เหลือของรหัสของคุณแบบฟอร์มจะไม่ส่งหากคุณใส่ที่ปุ่มลิงค์ว่า "บันทึกการเปลี่ยนแปลง"

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


3

ฉันมีปัญหาเดียวกันเมื่อเร็ว ๆ นี้และออกมาพร้อมกับปลั๊กอิน. toJSON jQuery นี้ซึ่งแปลงฟอร์มเป็นวัตถุ JSON ที่มีโครงสร้างเดียวกัน นอกจากนี้ยังมีประโยชน์อย่างยิ่งสำหรับรูปแบบที่สร้างขึ้นแบบไดนามิกที่คุณต้องการให้ผู้ใช้ของคุณเพิ่มเขตข้อมูลเพิ่มเติมในสถานที่เฉพาะ

ประเด็นก็คือคุณอาจต้องการสร้างฟอร์มเพื่อให้มีโครงสร้างเองดังนั้นสมมติว่าคุณต้องการสร้างฟอร์มที่ผู้ใช้แทรกสถานที่โปรดของเขาในเมือง: คุณสามารถนึกภาพฟอร์มนี้เพื่อแสดง<places>...</places>องค์ประกอบ XML ที่มี รายการสถานที่ที่ผู้ใช้ชอบดังนั้นจึงเป็นรายการ<place>...</place>องค์ประกอบที่มีตัวอย่างเช่น<name>...</name>องค์ประกอบ<type>...</type>องค์ประกอบจากนั้นรายการ<activity>...</activity>องค์ประกอบเพื่อแสดงกิจกรรมที่คุณสามารถดำเนินการในสถานที่ดังกล่าว ดังนั้นโครงสร้าง XML ของคุณจะเป็นดังนี้:

<places>

    <place>

        <name>Home</name>
        <type>dwelling</type>

        <activity>sleep</activity>
        <activity>eat</activity>
        <activity>watch TV</activity>

    </place>

    <place>...</place>

    <place>...</place>

</places>

มันจะเจ๋งขนาดไหนที่จะมีวัตถุ JSON ออกมาจากสิ่งนี้ซึ่งจะแสดงโครงสร้างที่แน่นอนนี้ดังนั้นคุณจะสามารถ:

  • เก็บวัตถุนี้ไว้ในฐานข้อมูลใด ๆ ที่เหมือนCouchDB
  • อ่านจากฝั่งเซิร์ฟเวอร์ $ _POST [] ของคุณและเรียกคืนอาร์เรย์ที่ซ้อนกันอย่างถูกต้องแล้วคุณสามารถจัดการความหมาย
  • ใช้สคริปต์ฝั่งเซิร์ฟเวอร์เพื่อแปลงเป็นไฟล์ XML ที่มีการจัดรูปแบบที่ดี (แม้ว่าคุณจะไม่ทราบโครงสร้างที่แน่นอนก่อนหน้า)
  • ใช้อย่างใดอย่างหนึ่งตามที่อยู่ในสคริปต์เซิร์ฟเวอร์ใด ๆ ของNode.js

ตกลงดังนั้นตอนนี้เราต้องคิดว่าแบบฟอร์มสามารถแสดงไฟล์ XML ได้อย่างไร

แน่นอนว่า<form>แท็กคือrootแต่แล้วเราก็มี<place>องค์ประกอบนั้นซึ่งเป็นคอนเทนเนอร์และไม่ใช่องค์ประกอบข้อมูลดังนั้นเราจึงไม่สามารถใช้แท็กอินพุตได้

นี่คือสิ่งที่<fieldset>แท็กมีประโยชน์! เราจะใช้<fieldset>แท็กเพื่อแสดงองค์ประกอบภาชนะทั้งหมดในรูปแบบ / XML ของเราเพื่อให้ได้ผลลัพธ์เช่นนี้:

<form name="places">

    <fieldset name="place">

        <input type="text" name="name"/>
        <select name="type">
            <option value="dwelling">Dwelling</option>
            <option value="restoration">Restoration</option>
            <option value="sport">Sport</option>
            <option value="administrative">Administrative</option>
        </select>

        <input type="text" name="activity"/>
        <input type="text" name="activity"/>
        <input type="text" name="activity"/>

    </fieldset>

</form>

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

ณ จุดนี้คุณจะเห็นว่าไม่มีname="array[]"ชื่อเหมือนในรูปแบบและทุกอย่างสวยเรียบง่ายและมีความหมาย

ตอนนี้เราต้องการให้แบบฟอร์มนี้ถูกแปลงเป็นวัตถุ JSON ซึ่งจะมีลักษณะดังนี้:

{'places':{

    'place':[

        {

            'name': 'Home',
            'type': 'dwelling',

            'activity':[

                 'sleep',
                 'eat',
                 'watch TV'

            ]

        },

        {...},

        {...}

    ]

}}

เมื่อต้องการทำสิ่งนี้ฉันได้พัฒนาปลั๊กอิน jQuery ที่นี่ซึ่งมีคนช่วยเพิ่มประสิทธิภาพในเธรดการทบทวนรหัสนี้และมีลักษณะดังนี้:

$.fn.toJSO = function () {
    var obj = {},
        $kids = $(this).children('[name]');
    if (!$kids.length) {
        return $(this).val();
    }
    $kids.each(function () {
        var $el = $(this),
            name = $el.attr('name');
        if ($el.siblings("[name=" + name + "]").length) {
            if (!/radio|checkbox/i.test($el.attr('type')) || $el.prop('checked')) {
                obj[name] = obj[name] || [];
                obj[name].push($el.toJSO());
            }
        } else {
            obj[name] = $el.toJSO();
        }
    });
    return obj;
};

ฉันทำโพสต์บล็อกนี้เพื่ออธิบายเพิ่มเติม

สิ่งนี้จะแปลงทุกอย่างในรูปแบบให้เป็น JSON (แม้แต่วิทยุและช่องทำเครื่องหมาย) และสิ่งที่คุณต้องทำก็แค่โทรออก

$.post('script.php',('form').toJSO(), ...);

ฉันรู้ว่ามีวิธีมากมายในการแปลงแบบฟอร์มเป็นวัตถุ JSON และตรวจสอบ.serialize()และ.serializeArray()ทำงานได้ดีในกรณีส่วนใหญ่และส่วนใหญ่จะใช้ แต่ฉันคิดว่าความคิดทั้งหมดนี้ของการเขียนแบบฟอร์มเป็นโครงสร้าง XML ที่มีชื่อที่มีความหมายและแปลงเป็น วัตถุ JSON ที่มีรูปแบบที่ดีนั้นควรค่าแก่การลองและความจริงที่ว่าคุณสามารถเพิ่มแท็กอินพุตชื่อเดียวกันโดยไม่ต้องกังวลมีประโยชน์มากหากคุณต้องการดึงข้อมูลฟอร์มที่สร้างขึ้นแบบไดนามิก

ฉันหวังว่านี่จะช่วยให้ใครบางคน!


คุณพยายามจะทำอะไร?
Onheiron

3

ฉันเขียนรหัสลงในวัตถุ JavaScript หลายมิติด้วยตนเองเพื่อใช้ในการผลิต ผลที่ได้คือhttps://github.com/serbanghita/formToObject.js


ฉันใช้ความหลากหลายของสิ่งนี้เพื่อการใช้งานที่เฉพาะเจาะจงขอบคุณมาก!
Chris Baker

ขอบคุณที่ให้ฉันรู้ว่ามันมีประโยชน์ ฉันมีฟีเจอร์ขาเข้าที่จะม้วนและสิ่งนี้เป็นแรงจูงใจให้ฉัน
Șerban Ghiță

3

คำตอบอื่น

document.addEventListener("DOMContentLoaded", function() {
  setInterval(function() {
    var form = document.getElementById('form') || document.querySelector('form[name="userprofile"]');
    var json = Array.from(new FormData(form)).map(function(e,i) {this[e[0]]=e[1]; return this;}.bind({}))[0];
    
    console.log(json)
    document.querySelector('#asJSON').value = JSON.stringify(json);
  }, 1000);
})
<form name="userprofile" id="form">
  <p>Name <input type="text" name="firstname" value="John"/></p>
  <p>Family name <input name="lastname" value="Smith"/></p>
  <p>Work <input name="employment[name]" value="inc, Inc."/></p>
  <p>Works since <input name="employment[since]" value="2017" /></p>
  <p>Photo <input type="file" /></p>
  <p>Send <input type="submit" /></p>
</form>

JSON: <textarea id="asJSON"></textarea>

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



2

ฉันชอบเวอร์ชันของ samuels แต่ฉันเชื่อว่ามันมีข้อผิดพลาดเล็กน้อย โดยปกติแล้ว JSON จะถูกส่งเป็น

{ "coreSKU": "PCGUYJS", "name_de": "สิ่งที่" ...

ไม่เป็น

[{ "coreSKU": "PCGUYJS"}, { "name_de": "สิ่งที่"}, ...

ดังนั้นฟังก์ชัน IMO ควรอ่าน:

App.toJson = function( selector ) {
    var o = {};
    $.map( $( selector ), function( n,i )
    {
        o[n.name] = $(n).val();
    });     
    return o;
}

และเพื่อห่อในอาร์เรย์ข้อมูล (ตามที่คาดไว้เช่นกัน) และในที่สุดก็ส่งเป็น App.stringify ที่น่าประหลาดใจ ({data: App.toJson ('#cropform: input')})

สำหรับการดูแบบสตริงที่คำถาม 3593046สำหรับเวอร์ชันลีนที่json2.jsสำหรับเวอร์ชันที่ครอบคลุมทุกเหตุการณ์ ที่ควรจะครอบคลุมทั้งหมด :)


ขอบคุณ .. สิ่งนี้ทำให้ความแตกต่างเล็ก ๆ แต่สำคัญมาก
Adarsha

2

สำหรับวิธีแก้ปัญหาที่รวดเร็วและทันสมัยให้ใช้ปลั๊กอินJSONify jQuery ตัวอย่างด้านล่างใช้คำต่อคำจาก GitHub README ให้เครดิตกับ Kushal Pandya ผู้เขียนปลั๊กอินทั้งหมด

ได้รับ:

<form id="myform">
    <label>Name:</label>
    <input type="text" name="name"/>
    <label>Email</label>
    <input type="text" name="email"/>
    <label>Password</label>
    <input type="password" name="password"/>
</form>

วิ่ง:

$('#myform').jsonify();

ผลิต:

{"name":"Joe User","email":"joe@example.com","password":"mypass"}

หากคุณต้องการทำ jQuery POST กับวัตถุ JSON นี้:

$('#mybutton').click(function() {
    $.post('/api/user', JSON.stringify($('#myform').jsonify()));
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.