本文翻译自:https://github.com/maxatwork/form2js/
一种将结构化的表单数据转换为JavaScript对象的简化方法。
这不是一个序列化库。 用于JSON序列化的库是http://www.json.org/js.html。
本插件所做的是将form的name属性转换成结果结构化的对象。这个插件所做的就是收集表单数据并将其放在一个javascript对象中。 显然你可以通过序列化得到一个JSON / XML / 或者其它字符串,但这不是它的唯一目的。
form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName)
将根节点下的所有input元素都收集到一个对象中。如果skipEmpty=true的话,将会跳过value为空的input元素。
结果对象中的属性字段和form中input元素的name一一对应。
如果设置useIdIfEmptyName=true的话,在name为空的情况下,将使用input元素的id值作为结果对象的属性字段。
对于嵌套对象,name默认使用“.”作为分隔符,但是你也可以修改默认分隔符。
<input type="text" name="person.name.first" value="John" />
<input type="text" name="person.name.last" value="Doe" />
结果:
{
"person": {
"name": {
"first": "John",
"last": "Doe"
}
}
}
具有相同的name值,并且name使用了括号([]),的多个input元素来定义数组的具体值。
<label><input type="checkbox" name="person.favFood[]" value="steak" checked="checked" /> Steak</label>
<label><input type="checkbox" name="person.favFood[]" value="pizza"/> Pizza</label>
<label><input type="checkbox" name="person.favFood[]" value="chicken" checked="checked" /> Chicken</label>
结果:
{
"person": {
"favFood": [ "steak", "chicken" ]
}
}
相同的index表示是在是同一个数组元素。
index并不会指明改元素在数组的位置,数组元素的位置由input元素在HTML文档中出现的前后决定的。
<dl>
<dt>Give us your five friends' names and emails</dt>
<dd>
<label>Email <input type="text" name="person.friends[0].email" value="agent.smith@example.com" /></label>
<label>Name <input type="text" name="person.friends[0].name" value="Smith Agent"/></label>
</dd>
<dd>
<label>Email <input type="text" name="person.friends[1].email" value="n3o@example.com" /></label>
<label>Name <input type="text" name="person.friends[1].name" value="Thomas A. Anderson" /></label>
</dd>
</dl>
结果:
{
"person" :
{
"friends" : [
{ "email" : "agent.smith@example.com", "name" : "Smith Agent" },
{ "email" : "n3o@example.com", "name" : "Thomas A. Anderson" }
]
}
}
如果数组的下标以[a-zA-Z_]开始,那么下标将会作为结果对象的字段
<dl>
<dt>Rails-style test</dt>
<dd>
<label>rails[field1][foo]<input type="text" name="rails[field1][foo]" value="baz" /></label>
<label>rails[field1][bar]<input type="text" name="rails[field1][bar]" value="qux" /></label>
</dd>
<dd>
<label>rails[field2][foo]<input type="text" name="rails[field2][foo]" value="baz" /></label>
<label>rails[field2][bar]<input type="text" name="rails[field2][bar]" value="qux" /></label>
</dd>
</dl>
结果:
{
"rails": {
"field1": {
"foo": "baz",
"bar": "qux"
},
"field2": {
"foo": "baz",
"bar": "qux"
}
}
}
你可以通过实现自己的nodeCallback方法(form2object()
中的第四个参数)来自定义转换逻辑。
<dl id="dateTest">
<dt>Date of birth:</dt>
<dd data-name="person.dateOfBirth" class="datefield">
<select name="person.dateOfBirth.month">
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<input type="text" name="person.dateOfBirth.day" value="1" />
<input type="text" name="person.dateOfBirth.year" value="2011" />
</dd>
</dl>
<script type="text/javascript">
function processDate(node)
{
var dataName = node.getAttribute ? node.getAttribute('data-name') : '',
dayNode,
monthNode,
yearNode,
day,
year,
month;
if (dataName && dataName != '' && node.className == 'datefield')
{
dayNode = node.querySelector('input[name="'+dataName + '.day"]');
monthNode = node.querySelector('select[name="'+dataName + '.month"]');
yearNode = node.querySelector('input[name="'+dataName + '.year"]');
day = dayNode.value;
year = yearNode.value;
month = monthNode.value;
return { name: dataName, value: year + '-' + month + '-' + day};
}
return false;
}
var formData = form2object('dateTest', '.', true, processDate);
</script>
结果:
{
"person": {
"dateOfBirth": "2011-01-12"
}
}
.serializeArray()
?JQuery的.serializeArray()
无法转换结构化的对象/嵌套对象:
[
{ "person.friends[0].email" : "agent.smith@example.com" },
{ "person.friends[0].name" : "Smith Agent" },
{ "person.friends[1].email" : "n3o@example.com" },
{ "person.friends[1].name" : "Thomas A. Anderson" }
]