使用Jquery序列化表单时动态计算字段未赋值及序列化失败问题
解决动态表单计算与序列化问题
让我们一步步拆解并解决你遇到的两个核心问题:
问题1:新增条目后cgst_val不显示计算值
你的代码里有两处关键错误导致了这个问题:
- 事件绑定的语法不对:jQuery的
.on()方法中,多个触发选择器应该放在事件类型后面,用逗号分隔,而不是作为单独的参数传入; - 设置输入框值的方式错误:用
.attr('value', ...)只会修改DOM的属性值,不会同步到表单的实际value中,也不会实时显示在输入框里,应该用.val()方法。
问题2:计算值无法被JSON序列化
这个问题也有两个核心原因:
- 禁用的表单元素会被序列化忽略:你的
cgst_val设置了disabled属性,表单序列化时会自动跳过这类元素,建议改成readonly(只读状态但仍会被序列化捕获); - 重复的name属性导致数据覆盖:新增多个条目后,所有相同name的输入框值会被最后一个条目覆盖,应该用数组形式的name(比如
tax_val[])来存储多组数据。
修改后的完整代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form> <input type="button" id="add" value="ADD" /> <div id="container"> <div class="group"> <input type="text" name="tax_val[]" class="P_tax_val" /> <select name="tax_per[]" class="P_tax_per"> <option disabled selected value>GST %</option> <option value="5">5</option> <option value="12">12</option> </select> <input type="text" name="cgst_val[]" class="P_cgst_val" size="3" placeholder="cs" value="" readonly /> </div> </div> <input type="submit" name="SUBMIT" /> </form> <script> $(document).ready(function() { $("#add").click(function() { var $clone = $('#container .group:first').clone(); $clone.find('input').val(''); $clone.find('select').val('2'); $clone.append('<a href="#" class="remove">X</a>'); $clone.appendTo('#container'); }); $("#container").on('click', '.remove', function() { $(this).parent('.group').remove(); }); // 修正事件绑定的语法,同时监听tax_val和tax_per的变化 $('#container').on('input change', ".P_tax_per, .P_tax_val", function() { var $group = $(this).closest('.group'); var num1 = parseInt($group.find(".P_tax_val").val(), 10) || 0; var num2 = parseInt($group.find(".P_tax_per").val(), 10) || 0; // 增加除以0的防护,避免出现NaN var num3 = num2 !== 0 ? (num1 / num2 * 100) : 0; // 用val()设置值并保留两位小数,提升用户体验 $group.find(".P_cgst_val").val(num3.toFixed(2)); }); }); $("form").submit(function(e) { e.preventDefault(); // 阻止表单默认提交,方便测试序列化结果 var resultArray = $('form').serializeArray(); // 将序列化的数组转换为按条目分组的对象数组 var taxEntries = []; var entryCount = $('#container .group').length; for(let i=0; i<entryCount; i++){ taxEntries.push({ tax_val: resultArray.find(item => item.name === 'tax_val[]' && item.index === i)?.value || '', tax_per: resultArray.find(item => item.name === 'tax_per[]' && item.index === i)?.value || '', cgst_val: resultArray.find(item => item.name === 'cgst_val[]' && item.index === i)?.value || '' }); } var myJSON = JSON.stringify(taxEntries); alert(myJSON); }); </script>
关键修改点说明
- 事件绑定修正:把错误的
.on('input, change', ".P_tax_per", ".P_state")改成.on('input change', ".P_tax_per, .P_tax_val"),确保税值和税率的变化都能触发计算; - 输入框值更新:用
.val(num3.toFixed(2))替代.attr('value', num3),实时同步输入框显示值,同时保留两位小数更符合财务数据的展示习惯; - 序列化问题解决:
- 将
disabled改为readonly,让计算后的字段能被表单序列化捕获; - 把name属性改为数组形式(
tax_val[]、tax_per[]、cgst_val[]),避免多组数据互相覆盖,同时方便按条目分组处理;
- 将
- 异常防护:增加
num2 !== 0的判断,避免用户未选择税率时出现除以0的NaN错误。
内容的提问来源于stack exchange,提问作者V. Monisha
相关产品推荐
相关产品推荐

