如何在vanilla JS表单序列化中处理多个同名表单元素?
解决原生JS表单序列化中同名字段的处理问题
在实现原生JS的form_to_json表单序列化函数时,动态添加的同名字段(比如每行包含三个同名输入框的“条件”行)只能保留最后一组值,核心问题出在同名字段的重复赋值逻辑上。
问题根源
原代码中,首次存储字段值时是字符串类型,当再次遇到同名字段时直接调用push方法会报错——因为字符串没有push方法。需要先将单个值转为数组,再添加后续的同名字段值。
修改后的完整代码
// gather form elements and serialize inputs function form_to_json(form_id) { console.log(`Getting form with ID ${form_id}`); let obj_form = document.getElementById(form_id); // Create an object var obj = {}; // Loop through each field in the form Array.prototype.slice.call(obj_form.elements).forEach(function(field) { // Skip some fields we don't need if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return; // Handle multi-select fields if (field.type === 'select-multiple') { // Create an array of selected values var options = []; // Loop through the options and add selected ones Array.prototype.slice.call(field.options).forEach(function(option) { if (!option.selected) return; options.push(option.value); }); // If there are any selection options, add them to the object if (options.length) { obj[field.name] = options; } return; } // If it's a checkbox or radio button and it's not checked, skip it if (['checkbox', 'radio'].indexOf(field.type) > -1 && !field.checked) return; console.log(`${field.name}: ${field.value}`); // Add the value to the object if (field.name in obj) { // 处理同名字段:先判断当前值是否为数组,不是则转为数组 if (!Array.isArray(obj[field.name])) { obj[field.name] = [obj[field.name]]; } obj[field.name].push(field.value); } else { obj[field.name] = field.value; } }); // Return the object return obj; }
关键修改说明
- 当检测到
field.name已存在于obj中时,先通过Array.isArray判断当前存储的值是否为数组 - 如果不是数组(即首次存储的单个值),将其转换为包含该值的数组
- 之后再调用
push方法添加新的同名字段值,这样所有同名字段的value都会被收集到数组中
内容的提问来源于stack exchange,提问作者Source Matters
相关产品推荐
相关产品推荐

