jQuery Form - 序列化为多维数组?
Posted
技术标签:
【中文标题】jQuery Form - 序列化为多维数组?【英文标题】:jQuery Form - Serialize into multi dimensional array? 【发布时间】:2016-12-29 18:32:01 【问题描述】:我需要从form
获取值,将其格式化为 JSON 并通过 AJAX 发布。这是我想要实现的格式:
items: [
id: 7, name: 'Book', price: 5.7 ,
id: 5, name: 'Pencil', price: 2.5
]
这是 html:
(function($)
var $form = $('form');
// serializeArray format is way off from what I need
var rawData = $form.serializeArray();
console.log(rawData)
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
我应该循环并使用正则表达式来解析name
吗?还是有内置方式?
如果需要,我可以更改<form>
格式。
【问题讨论】:
不,我的意思是我想从输入中获取所有数据以形成该 JSON。我需要通过 Ajax 发布它。我将编辑问题以使其更清晰 序列化在这里不起作用,需要手动进行 【参考方案1】:这里不能使用默认的序列化,而是可以像这样手动进行序列化
(function($)
var $fieldsets = $('form fieldset');
var items = $fieldsets.map(function(i, fs)
var obj = ;
$(fs).find('input').each(function()
obj[this.name.match(/\[([^\[]*)\]$/)[1]] = this.value;
);
return obj;
).get();
var rawData =
items: items
;
console.log(rawData)
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
【讨论】:
【参考方案2】:请看看这种方法。我们不能只使用$.serializeArray()
,还需要一些自定义代码,如下所示。实际上,我们需要遍历所有 <fieldset>
来获取我们需要的 JSON:
(function($)
var $form = $('form');
var fieldSets = $form.find("fieldset");
var result =
items: []
;
fieldSets.each(function()
var fields = ;
$.each($(this).serializeArray(), function()
fields[this.name] = this.value;
);
result.items.push(fields);
);
console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="id" value="7">
<input type="text" name="name" value="Book">
<input type="number" name="price" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="id" value="5">
<input type="text" name="name" value="Pencil">
<input type="number" name="price" value="2.5">
</fieldset>
</form>
注意:稍微修改了 HTML,而不是 name="items[0][id]"
我给出的 name="id"
【讨论】:
谢谢,这似乎是更简单的解决方案。【参考方案3】:是的,您需要自己解析name
字段。没有解析自定义字段的自动化方法。当然,有多种方法可以做到这一点。
注意:我假设您的 name="items[0][id]"
字段指定这必须是结果数组中的第 0 项,并且此类 <input>
字段集不一定按项目 # 升序排列DOM。换句话说,item[N]
应该控制它成为<form>
中的第 Q 个<fieldset>
。
您可以使用 serializeArray()
然后处理该数据:
(function($)
var $form = $('form');
var data = $form.serializeArray();
var result = items:[];
data.forEach(function(input)
nameArray = input.name.split(/[[\]]/);
item = nameArray[1];
prop = nameArray[3];
if(typeof result.items[item] !== 'object')
result.items[item]=;
if(typeof result.items[item][prop] !== 'undefined')
//Consistency check the name attribute
console.log('Warning duplicate "name" property =' + input.name);
result.items[item][prop]=input.value;
);
console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
或者,您可以直接从 DOM 处理它:
(function($)
var result = items:[];
$('form fieldset input').each(function()
nameArray = this.name.split(/[[\]]/);
item = nameArray[1];
prop = nameArray[3];
if(typeof result.items[item] !== 'object')
result.items[item]=;
if(typeof result.items[item][prop] !== 'undefined')
//Consistency check the name attribute
console.log('Warning duplicate "name" property =' + this.name);
result.items[item][prop]=this.value;
);
console.log(result);
)(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
<fieldset>
<h2>Product 1</h2>
<input type="hidden" name="items[0][id]" value="7">
<input type="text" name="items[0][name]" value="Book">
<input type="number" name="items[0][price]" value="5.7">
</fieldset>
<fieldset>
<h2>Product 2</h2>
<input type="hidden" name="items[1][id]" value="5">
<input type="text" name="items[1][name]" value="Pencil">
<input type="number" name="items[1][price]" value="2.5">
</fieldset>
</form>
【讨论】:
为什么你认为这个解决方案会帮助 OP? 感谢您的回答。items[0]
只是避免重复名称的示例。我想可以使用重复的名称,例如 id
或 name
,就像 vijayP 的回答一样
@DarcCode,谢谢。复制name
属性通常很方便(它可用于对元素进行分组)(例如getElementsByName()
)。还有一次,请在问题中提到 HTML 可以更改。当我阅读这个问题时,我假设您正在尝试使用 javascript 来获取您想要的基于 HTML 的 JSON,该 HTML 具有该精确格式。考虑到它的编写方式,该假设和 vijayP 的假设(可以方便地更改 HTML)都是有效的。在问题中指出具体情况将有助于人们为您提供更好的答案。
@Makyen 感谢您的建议,下次我提出问题时会提供更多详细信息。以上是关于jQuery Form - 序列化为多维数组?的主要内容,如果未能解决你的问题,请参考以下文章