如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
如何将表单的所有元素转换为JavaScript对象?
我希望有某种方法从表单自动构建JavaScript对象,而不必遍历每个元素。我不希望使用$('#formid').serialize();返回的字符串;,我也不希望$('#formid').serializeArray()返回映射;
当前回答
我的库phery中的代码有一个序列化例程,可以处理非常复杂的表单(如演示中所示https://github.com/pocesar/phery/blob/master/demo.php#L1664),而且不是一刀切。它实际上检查每个字段的类型。例如,单选框与范围不同,与keygen不同,与select multiple不同。我的功能涵盖了这一切,你可以看到它在https://github.com/pocesar/phery/blob/master/phery.js#L1851.
serializeForm:function (opt) {
opt = $.extend({}, opt);
if (typeof opt['disabled'] === 'undefined' || opt['disabled'] === null) {
opt['disabled'] = false;
}
if (typeof opt['all'] === 'undefined' || opt['all'] === null) {
opt['all'] = false;
}
if (typeof opt['empty'] === 'undefined' || opt['empty'] === null) {
opt['empty'] = true;
}
var
$form = $(this),
result = {},
formValues =
$form
.find('input,textarea,select,keygen')
.filter(function () {
var ret = true;
if (!opt['disabled']) {
ret = !this.disabled;
}
return ret && $.trim(this.name);
})
.map(function () {
var
$this = $(this),
radios,
options,
value = null;
if ($this.is('[type="radio"]') || $this.is('[type="checkbox"]')) {
if ($this.is('[type="radio"]')) {
radios = $form.find('[type="radio"][name="' + this.name + '"]');
if (radios.filter('[checked]').size()) {
value = radios.filter('[checked]').val();
}
} else if ($this.prop('checked')) {
value = $this.is('[value]') ? $this.val() : 1;
}
} else if ($this.is('select')) {
options = $this.find('option').filter(':selected');
if ($this.prop('multiple')) {
value = options.map(function () {
return this.value || this.innerHTML;
}).get();
} else {
value = options.val();
}
} else {
value = $this.val();
}
return {
'name':this.name || null,
'value':value
};
}).get();
if (formValues) {
var
i,
value,
name,
$matches,
len,
offset,
j,
fields;
for (i = 0; i < formValues.length; i++) {
name = formValues[i].name;
value = formValues[i].value;
if (!opt['all']) {
if (value === null) {
continue;
}
} else {
if (value === null) {
value = '';
}
}
if (value === '' && !opt['empty']) {
continue;
}
if (!name) {
continue;
}
$matches = name.split(/\[/);
len = $matches.length;
for (j = 1; j < len; j++) {
$matches[j] = $matches[j].replace(/\]/g, '');
}
fields = [];
for (j = 0; j < len; j++) {
if ($matches[j] || j < len - 1) {
fields.push($matches[j].replace("'", ''));
}
}
if ($matches[len - 1] === '') {
offset = assign_object(result, fields, [], true, false, false);
if (value.constructor === Array) {
offset[0][offset[1]].concat(value);
} else {
offset[0][offset[1]].push(value);
}
} else {
assign_object(result, fields, value);
}
}
}
return result;
}
它是我的库phery的一部分,但可以移植到您自己的项目中。它在应该有数组的地方创建数组,从select、normalize复选框等选项中获取正确的选择选项。如果要将其转换为JSON(真正的JSON字符串),只需执行JSON.stringify($('form').serializeForm());
其他回答
Use:
function form_to_json (selector) {
var ary = $(selector).serializeArray();
var obj = {};
for (var a = 0; a < ary.length; a++) obj[ary[a].name] = ary[a].value;
return obj;
}
输出:
{"myfield": "myfield value", "passwordfield": "mypasswordvalue"}
我编写了一个jQuery模块jsForm,即使对于非常复杂的表单(也允许集合和其他更复杂的结构),它也可以实现这种双向。
它使用字段的名称(加上一些用于集合的特殊类)并匹配JSON对象。它允许自动复制用于收集和数据处理的DOM元素:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://raw.github.com/corinis/jsForm/master/src/jquery.jsForm.js"></script>
<script>
$(function(){
// Some JSON data
var jsonData = {
name: "TestName", // Standard inputs
description: "long Description\nMultiline", // Textarea
links: [{href:'http://stackoverflow.com',description:'StackOverflow'}, {href:'http://www.github.com', description:'GitHub'}], // Lists
active: true, // Checkbox
state: "VISIBLE" // Selects (enums)
};
// Initialize the form, prefix is optional and defaults to data
$("#details").jsForm({
data:jsonData
});
$("#show").click(function() {
// Show the JSON data
alert(JSON.stringify($("#details").jsForm("get"), null, " "));
});
});
</script>
</head>
<body>
<h1>Simpel Form Test</h1>
<div id="details">
Name: <input name="data.name"/><br/>
<input type="checkbox" name="data.active"/> active<br/>
<textarea name="data.description"></textarea><br/>
<select name="data.state">
<option value="VISIBLE">visible</option>
<option value="IMPORTANT">important</option>
<option value="HIDDEN">hidden</option>
</select>
<fieldset>
<legend>Links</legend>
<ul class="collection" data-field="data.links">
<li><span class="field">links.description</span> Link: <input name="links.href"/> <button class="delete">x</button></li>
</ul>
</fieldset>
<button class="add" data-field="data.links">add a link</button><br/>
Additional field: <input name="data.addedField"/>
</div>
<button id="show">Show Object</button>
</body>
</html>
使用此项:
var sf = $('#mainForm').serialize(); // URL encoded string
sf = sf.replace(/"/g, '\"'); // Be sure all "s are escaped
sf = '{"' + sf.replace(/&/g, '","'); // Start "object", replace tupel delimiter &
sf = sf.replace(/=/g, '":"') + '"}'; // Replace equal sign, add closing "object"
// Test the "object"
var formdata = eval("(" + sf + ")");
console.log(formdata);
即使在非常复杂的形式上,它也像一种魅力。
由于XSS攻击和可能存在的其他问题,我不会在现场网站上使用此功能,但下面是一个快速示例:
$("#myform").submit(function(){
var arr = $(this).serializeArray();
var json = "";
jQuery.each(arr, function(){
jQuery.each(this, function(i, val){
if (i=="name") {
json += '"' + val + '":';
} else if (i=="value") {
json += '"' + val.replace(/"/g, '\\"') + '",';
}
});
});
json = "{" + json.substring(0, json.length - 1) + "}";
// do something with json
return false;
});
此函数返回转换为正确类型的所有值;
bool/string/(integer/floats)可能
虽然您需要jQuery来实现这一点,但由于serializeArray也是jQuery,所以没什么大不了的。
/**
* serialized a form to a json object
*
* @usage: $("#myform").jsonSerialize();
*
*/
(function($) {
"use strict";
$.fn.jsonSerialize = function() {
var json = {};
var array = $(this).serializeArray();
$.each(array, function(key, obj) {
var value = (obj.value == "") ? false : obj.value;
if(value) {
// check if we have a number
var isNum = /^\d+$/.test(value);
if(isNum) value = parseFloat(value);
// check if we have a boolean
var isBool = /^(false|true)+$/.test(value);
if(isBool) value = (value!=="false");
}
json[obj.name] = value;
});
return json;
}
})(jQuery);