2010-09-09 48 views
19

我一直在爲此尋找小時,並且沒有找到答案。 在燃燒之前請仔細閱讀整個問題! :)使用jQuery將複雜形式序列化爲JSON對象

我有一個類似的形式:

<form id="sample"> 
<input name="name" type="text" value="name value" /> 

<input name="phone[0][type]" type="text" value="cell" /> 
<input name="phone[0][number]" type="text" value="000" /> 

<input name="phone[1][type]" type="text" value="home" /> 
<input name="phone[1][number]" type="text" value="111" /> 
</form> 

而且需要能夠將其序列化到這一點:

{ 
name: 'name value', 

phone: [ 
    { 
    type: 'cell', 
    number: '000' 
    }, 
    { 
    type: 'home', 
    number: '111' 
    } 
] 
} 

我曾嘗試在SO包括jQuery的JSON最答案庫和大多數人返回這樣的事情:

{ 
'name': 'name value', 
'phone[0][type]': 'cell', 
'phone[0][number]': '000', 
'phone[1][type]': 'home', 
'phone[1][number]': '111', 
} 

這是東西我不能使用! :P

謝謝大家提前。

回答

18

試試這段代碼我爲你寫的...對我來說工作得很好,只是使用你的數據結果。你可以使用它來製作一個簡單的jQuery插件...

該示例需要JSON.stringify才能完全工作。

var d = { 
    'name': 'name value', 
    'phone[0][type]': 'cell', 
    'phone[0][number]': '000', 
    'phone[1][type]': 'home', 
    'phone[1][number]': '111', 
}; 

$(document).ready(function(){ 

    arrangeJson(d); 
    alert(JSON.stringify(d)); 
}); 

function arrangeJson(data){ 
    var initMatch = /^([a-z0-9]+?)\[/i; 
    var first = /^\[[a-z0-9]+?\]/i; 
    var isNumber = /^[0-9]$/; 
    var bracers = /[\[\]]/g; 
    var splitter = /\]\[|\[|\]/g; 

    for(var key in data) { 
     if(initMatch.test(key)){ 
      data[key.replace(initMatch,'[$1][')] = data[key]; 
     } 
     else{ 
      data[key.replace(/^(.+)$/,'[$1]')] = data[key]; 
     } 
     delete data[key]; 
    } 


    for (var key in data) { 
     processExpression(data, key, data[key]); 
     delete data[key]; 
    } 

    function processExpression(dataNode, key, value){ 
     var e = key.split(splitter); 
     if(e){ 
      var e2 =[]; 
      for (var i = 0; i < e.length; i++) { 
        if(e[i]!==''){e2.push(e[i]);} 
      } 
      e = e2; 
      if(e.length > 1){ 
       var x = e[0]; 
       var target = dataNode[x]; 
       if(!target){ 
        if(isNumber.test(e[1])){ 
         dataNode[x] = []; 
        } 
        else{ 
         dataNode[x] ={} 
        } 
       } 
       processExpression(dataNode[x], key.replace(first,''), value); 
      } 
      else if(e.length == 1){ 
       dataNode[e[0]] = value; 
      } 
      else{ 
       alert('This should not happen...'); 
      } 
     } 
    } 
} 
+1

非常感謝Juliano! 這是完美的解決方案! :D – 2010-09-09 15:29:09

+0

工程像魔術。對其進行一些修改,以處理您的列表形式爲 var d = {name':'name value', 'phone [0] .type':'cell', 'phone [0] .number':'000', 'phone [1] .type':'home', 'phone [1] .number':'111', }; 結果在內部列表Key中有(。)in from,所以我在processExpression的第一個for循環後面添加了 )功能。 – 2016-02-05 16:13:02

+0

_key_在函數中被聲明瞭兩次。 – robsch 2016-05-14 14:16:42

1

有了這個結構,我不認爲任何JSON庫可以完成所有的工作。 所以,我認爲編寫自己的轉換循環更容易。

下面是代碼到您的序列:http://jsfiddle.net/7MAUv/1/

的邏輯很簡單,祕訣是eval跑般的動感命令字符串。 我試圖讓它儘可能地簡單,幾乎所有的行都被評論了。

順便說一句,隨時提出問題。

+0

你的代碼完美工作Erick。 非常感謝您發佈它。 我會嘗試看看是否可以完成沒有eval部分,但現在應該是真棒。 – 2010-09-09 14:04:56

2

這個工作對我非常好。這並不需要form2js庫。

$.fn.serializeObject = function serializeObject() { 
     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; 
    }; 

要序列化表單數據,我使用了這段代碼。

JSON.stringify($(this).serializeObject());//'this' points to the form 

如果您有任何疑問,請隨時添加評論。

+0

爲了實現這個目標,你的表單是什麼樣的? – trebor 2016-01-12 14:27:00

0

它不是你問什麼了,但如果你正在使用jQuery庫,需要你的連載在AJAX發送它的目的複雜的形式,你可以使用某事像這樣

ajaxRunning = $.ajax(
    "?"+$('#yourForm').serialize(), 
    { 
     data: { 
      anotherData: 'worksFine', 
      etc: 'still works' 
     }, 
     success: function(result) { 
      doSth(); 
     }, 
     dataType: "json" 
}); 

可以使用in $ .post and $ .get以及

nJoy!