将HTML表单字段转换为具有内部对象的JSON对象
给出以下HTML表单:
将此表单在javascript中序列化为JSON对象的最佳方式是什么:
{ Company:"ACME, INC.", Contact:{FirstName:"Daffy", LastName:"Duck"} }
另请注意,可能会有超过1个“。” 登录字段名称。
我认为你要做的是:对于每个输入,首先在分隔符处分割名称(’。’字符)。 现在,您有一系列名称。 然后,您可以遍历该数组,确保每次遇到新的名称段时,目标“程序集”对象(和子对象)都有容器。 当数组中包含1个元素时,只需添加该值即可。
$.fn.extractObject = function() { var accum = {}; function add(accum, namev, value) { if (namev.length == 1) accum[namev[0]] = value; else { if (accum[namev[0]] == null) accum[namev[0]] = {}; add(accum[namev[0]], namev.slice(1), value); } }; this.find('input, textarea, select').each(function() { add(accum, $(this).attr('name').split('.'), $(this).val()); }); return accum; }); // ... var object = $('#myform').extractObject();
我只是做了这样的事情,所以可能会有一两个错误; 我不记得所有浏览器是否都有“切片”,但我认为它们确实存在。
(编辑:我忘记了对split()
最重要的调用)
您可以按名称遍历表单字段,使用String#split
在点上拆分名称,并构建结果结构。 概念代码:
function serializeDeep(form) { var rv, obj, elements, element, index, names, nameIndex, value; rv = {}; elements = form.elements; for (index = 0; index < elements.length; ++index) { element = elements[index]; name = element.name; if (name) { value = $(element).val(); names = name.split("."); obj = rv; for (nameIndex = 0; nameIndex < names.length; ++nameIndex) { name = names[nameIndex]; if (nameIndex == names.length - 1) { obj[name] = value; } else { obj = obj[name] = obj[name] || {}; } } } } return rv; }
请注意,这不允许具有重复名称的字段(应该创建数组),也不能优雅地处理使用名称“foo”和“foo.bar”的情况。 但它应该让你开始。
我用这种方式管理它:
$('#Myform').attr('onsubmit', 'test()'); function test() { var obj = {}; obj.title =$('#title').prop('value'); console.log('title: '+obj.title); obj.website =$('#website').prop('value'); console.log('website: '+obj.website); obj.tags =$('#tags').prop('value').split(','); console.log('tags: '+obj.tags); do_something(JSON.stringify(obj)); }
当然,如果您知道名称是什么,这可以完成,而我实际上是使用Formation插件生成表本身。
我使用普通的js为这个问题创建了一个例子,请检查开发人员工具控制台以查看数据对象!
jsfiddle的例子
var data = {}; var array = 'person.name.first'.split('.'); var value = 'myFirstName'; generateObj(data, array, value); console.log(data); function generateObj(obj, arr, val) { if (arr.length === 1) { obj[arr[0]] = val return; } var restArr = arr.splice(1); if (!obj[arr[0]]) { obj[arr[0]] = {}; } generateObj(obj[arr[0]], restArr, val); }
解:
- 将每个名称字符串转换为数组。
- 遍历每个数组。
- 递归调用一个创建obj的方法,并将此obj设置为属性的值,并将此obj传递给下一个递归。
创建该形状的对象,然后使用JSON编码器将其写出。