如果我有以下表格:
<form>
<input name="foo" value="bar">
<input name="hello" value="world">
<input name="animals[]" value="panda">
<input name="animals[]" value="koala">
<input name="car[make]" value="Honda">
<input name="car[origin]" value="Japan">
</form>
我不想要使用$("form").serialize()
:
foo=bar&hello=world&animals%5B%5D=panda&animals%5B%5D=koalacar&%5Bmake%5D=Honda&car%5Borigin%5D=Japan
相反,我想要这个:
{"foo":"bar", "hello":"world", "animals":["panda", "koala"], "car":{"make":"Honda", "origin":"Japan"}}
据我了解,jQuery曾经这样做过,但是他们切换了serialize
方法来返回GET风格的查询字符串。有没有简单的方法来获得我想要的结果?
我已将原始问题更新为包含car[make]
和car[origin]
示例。应该假设foo[bar][baz]
或foo[bar][baz][bof]
输入也可以出现在表单上。
此外,应保留指定的数字索引键,例如foo[0]=a
,foo[1]=b
,foo[4]=c
,例如,
{ ... "foo":["a", "b", undefined, undefined, "c"] ... }
答案 0 :(得分:9)
Github: Follow along on Github
以下代码可以使用各种输入名称;并按照您的预期处理它们。
如,
<!-- 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();
(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);
答案 1 :(得分:6)
您可以使用“.serializeArray()”,然后修复结果:
var json = {};
$.each($('form').serializeArray(), function() {
json[this.name] = this.value;
});
当然,您可能需要担心多值字段:
var json = {};
$.each($('form').serializeArray(), function() {
var cur = json[this.name];
if (cur !== undefined) {
if ($.isArray(cur))
cur.push(this.value);
else
json[ this.name.replace(/\[[^\]]*\]$/, '') ] = [ cur, this.value ];
}
else
json[this.name] = this.value;
});
(编辑 - 现在我想起来了,“序列化”和“serializeArray”已经为你处理了多值参数,给你的名字就像“无论[2]”以序列化的形式。无论如何它都可以工作,但除了简单的事情之外,它可能没有必要做任何事情。)
答案 2 :(得分:1)
这是将查询字符串转换为JSON的一个非常好的答案。我来自以下SO link
knovel.util = {
queryParamsToJson : function (theURL) {
href = theURL;
qStr = href.replace(/(.*?\?)/, '');
qArr = qStr.split('&');
stack = {};
for (var i in qArr) {
var a = qArr[i].split('=');
var name = a[0],
value = isNaN(a[1]) ? a[1] : parseFloat(a[1]);
if (name.match(/(.*?)\[(.*?)]/)) {
name = RegExp.$1;
name2 = RegExp.$2;
//alert(RegExp.$2)
if (name2) {
if (!(name in stack)) {
stack[name] = {};
}
stack[name][name2] = value;
} else {
if (!(name in stack)) {
stack[name] = [];
}
stack[name].push(value);
}
} else {
stack[name] = value;
}
}
return stack;
}
}
希望这对某人有所帮助..
答案 3 :(得分:0)
我总是这样做,也许有点长啰嗦,但我很容易维持。
function FormContent(foo, hello, animals)
{
this.Foo = foo;
this.Hello = hello;
this.Animals = animals;
}
var animals = [];
$("[name='animals[]']").each(function(){
animals.push($(this).val());
});
var foo = $("[name='foo']").val();
var hello = $("[name='hello']").val();
var formContent = new FormContent(foo, hello, animals);
var jsonContent = json.stringify(formContent); // from json.org
我刚才意识到你特意问过“使用jQuery”抱歉。我从未有过使用jQuery序列化json的运气。希望无论如何都有帮助。
答案 4 :(得分:0)
就我而言,我必须采用以前使用jQuery序列化的形式,并将其转换为对象,将所有特殊字符的编码等替换为其文字值。在这里使用Dilip的示例,这就是我所使用的。
Form1 = $('#MyForm').serialize(); // Name=Mr.+John+Mark+Jr.&Email=john%40example.com
Form1 = Form1.replace(/\+/g, '%20'); // Name=Mr.%20John%20Mark%20Jr.&Email=john%40example.com
var Decoded = decodeURIComponent(Form1); // Name=Mr. John Mark Jr.&Email=john@example.com
var Values = queryParamsToJson(Decoded); // { Name : "Mr. John Mark Jr.", Email : "john@example.com" }
function queryParamsToJson(theURL)
{
href = theURL;
qStr = href.replace(/(.*?\?)/, '');
qArr = qStr.split('&');
stack = {};
for (var i in qArr)
{
var a = qArr[i].split('=');
var name = a[0],
value = isNaN(a[1]) ? a[1] : parseFloat(a[1]);
if (name.match(/(.*?)\[(.*?)]/))
{
name = RegExp.$1;
name2 = RegExp.$2;
//alert(RegExp.$2)
if (name2)
{
if (!(name in stack))
{
stack[name] = {};
}
stack[name][name2] = value;
}
else
{
if (!(name in stack))
{
stack[name] = [];
}
stack[name].push(value);
}
}
else
{
stack[name] = value;
}
}
return stack;
}
现在我可以访问“ Values.variable”中的任何值