复杂表单转换JS对象 form2js插件介绍

来源:互联网 发布:指南针炒股软件诈骗 编辑:程序博客网 时间:2024/05/22 01:58

本文翻译自:https://github.com/maxatwork/form2js/

一种将结构化的表单数据转换为JavaScript对象的简化方法。

1 详细

这不是一个序列化库。 用于JSON序列化的库是http://www.json.org/js.html。
本插件所做的是将form的name属性转换成结果结构化的对象。这个插件所做的就是收集表单数据并将其放在一个javascript对象中。 显然你可以通过序列化得到一个JSON / XML / 或者其它字符串,但这不是它的唯一目的。

2 用法

form2js(rootNode, delimiter, skipEmpty, nodeCallback, useIdIfEmptyName)

根节点下的所有input元素都收集到一个对象中。如果skipEmpty=true的话,将会跳过value为空的input元素。

2.1 对象 / 嵌套对象

结果对象中的属性字段和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"    }  }}

2.2 数组

具有相同的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" ]    }}

2.3 对象数组 / 嵌套对象数组

相同的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" }        ]    }}

2.4 Rails-style 表示法

如果数组的下标以[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"        }    }}

2.5 自定义字段

你可以通过实现自己的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"    }}

3 为什么不使用.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" }]
0 0