将复杂表单输入对象序列化为JSON以生成API请求

时间:2015-04-09 17:10:03

标签: jquery json forms serialization stringify

我有一个表单,其输入我想提交给API以获得可解析的响应。到目前为止,我已设法使用预格式化的对象执行请求。但是,我很难获得发出请求所需的格式。

请求的结构需要如下所示:

{ "request": { "slice": [ { "origin": "LAX", "destination": "BOS", "date": "2015-09-09" } ], "passengers": { "adultCount": 1 }, "solutions": 1 } };

我尝试创建嵌套密钥时更改了表单的名称,但我得到的是:

{"request[slice][origin]":"LAX","request[slice][destination]":"BOS","request[slice][date]":"2015-09-09","request[passengers][adultcount]":"1","request[solutions]":"1"}

表格如下:

<form id="request" action="" onsubmit="request" method="post">
<input type="text" name="request[slice][origin]" placeholder="From">
<br>
<input type="text" name="request[slice][destination]" placeholder="Destination">
<br>
<input type="text" name="request[slice][date]" placeholder="Outbound Date">
<br>
<input type="text" name="request[passengers][adultcount]" placeholder="Passengers">
<br>
<input type="text" name="request[solutions]" placeholder="Results">
<br>
<p><input type="submit" /></p>
</form>

序列化对象的脚本是:

<script>
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
    if (o[this.name] !== undefined) {
        if (!o[this.name].push) {
            o[this.name] = [o[this.name]];
        }
        o[this.name].push(this.value || '');
    } else {
        o[this.name] = this.value || '';
    }
});
return o;
};

$(function request() {
$('form').submit(function() {
    $('#result').text(JSON.stringify($('form').serializeObject()));
    return false;
});
});
</script>

1 个答案:

答案 0 :(得分:0)

serializeObject方法仅适用于具有正常输入的元素。但在您的情况下,输入具有不同类型的名称,因此必须稍微更改serializeObject。

$.fn.serializeObject = function () {
    var o = {};
    var outputCopy = o;
    var a = this.serializeArray();
    var regex = /(\w+)+/g; 
    $.each(a, function (index, item) {
        var keys = item.name.match(regex);
        keys.forEach(function (key, localIndex) {
            if (!outputCopy.hasOwnProperty(key)) {
                outputCopy[key] = {};
            }
            if(localIndex == keys.length - 1) { 
                outputCopy[key] = isNaN(item.value) ? item.value : +item.value;
            }
            outputCopy = outputCopy[key];
        });
        outputCopy = o;
    });
    return o;
});

我使用正则表达式将字符串request[slice][destination]分解为请求,切片和目标,从而创建一个对象。

最深的对象的键将具有值。条件localIndex == keys.length - 1用于计算最后一次迭代,从而插入一个值。

希望这有帮助。

更新

检查值是字符串还是数字isNaN,然后相应地进行转换。 字符串之前的+会将其转换为数字(如果是数字)。

这是一个很好的reference

$.fn.serializeObject = function () {
    var o = {};
    var outputCopy = o;
    var a = this.serializeArray();
    var regex = /(\w+)+/g;
    $.each(a, function (index, item) {
        var keys = item.name.match(regex);
        keys.forEach(function (key, localIndex) {
            if (!outputCopy.hasOwnProperty(key)) {
                outputCopy[key] = {};
            }
            if(localIndex == keys.length - 1) { 
                outputCopy[key] = isNaN(item.value) ? item.value : +item.value; 
            }
            outputCopy = outputCopy[key];
        });
        outputCopy = o;
    });
    return o;
};


$(function request() {
    $('form').submit(function (e) {
        e.preventDefault();
        alert(JSON.stringify($(this).serializeObject()));
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form id="request" action="" onsubmit="request" method="post">
    <input type="text" name="request[slice][origin]" placeholder="From">
    <br>
    <input type="text" name="request[slice][destination]" placeholder="Destination">
    <br>
    <input type="text" name="request[slice][date]" placeholder="Outbound Date">
    <br>
    <input type="text" name="request[passengers][adultcount]" placeholder="Passengers">
    <br>
    <input type="text" name="request[solutions]" placeholder="Results">
    <br>
    <p>
    <input type="submit" />
    </p>
</form>