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

本文翻译自: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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值