有时候需要将表单Form的input、select、textarea等标签的数据,转化成json格式的数据,以便操作,Jquery的serializeArray 方法已经可以实现将Form的数据序列化为一个数组,但是有时候我们需要转换为后端使用的Bean对象,某些属性是嵌套结构的,网上找了半天相关的转换方法,都只是转了一层,嵌套的比较少。当然资源还是有的,比如国外同学写的 jquery-serialize-object。不过使用起来层级是用[]中括号来分隔的,反填的时候就不太方便了, 所以逼的一名后端只能摸索着写点前端代码了!
可以在jquery中添加下面方法,来实现嵌套form的转换。
//form表单转json
$.fn.serializeObject = function () {
const o = {};
const a = this.serializeArray();
$.each(a, function () {
//增加嵌套属性支持
const names = this.name.split(".")
let temp = o;
const end = (names.length - 1);
//为了支持强制指定单值也可以为json array类型
const jsonType = $('[name="' + this.name + '"]').data("json-type");
const jsonArray = jsonType && (jsonType === 'array');
names.forEach((item, index, array) => {
if (temp[item]) {
if (index == end) {
if (!temp[item].push) {
temp[item] = [temp[item]];
}
temp[item].push(this.value || '');
}
} else {
if (index == end) {
temp[item] = jsonArray ? [this.value || ''] : (this.value || '');
} else {
temp[item] = jsonArray ? [] : {};
}
}
temp = temp[item];
})
});
return o;
};
使用时,将嵌套属性定义为“属性1.子属性1.xx”的格式,嵌套层级用点分隔即可。
例如:
<div class="left">checkbox:</div>
<div class="right">
<label for="checkbox-0"><input value="0" type="checkbox" name="checkbox.a" data-json-type="array" id="checkbox-0" />0 </label>
<label for="checkbox-1"><input value="1" type="checkbox" name="checkbox.a" id="checkbox-1" />1 </label>
</div>
<div class="right">
<label for="checkbox-0"><input value="0" type="checkbox" name="checkbox.b" data-json-type="array" id="checkbox-0" />0 </label>
<label for="checkbox-1"><input value="1" type="checkbox" name="checkbox.b" id="checkbox-1" />1 </label>
</div>
</div>
转换后:
{"checkbox":{"a":["0","1"],"b":["0","1"]}}
注意,data-json-type:这个属性是为了强制指定该属性只有一个值时也转换为数组,方便跟后台bean做转换。