使用JavaScript复制下拉列表值后,提交时Qty/Price/Sum存为0的问题
问题排查:表单提交时Qty/Price/Sum始终保存为0
1. 场景说明
- 通过下拉列表将产品的数量(quantity)、单价(price)复制到对应输入框,第三个输入框展示「数量×单价」的总价(sum)
- 数量或单价变更时,总价能正常更新显示
- 当前代码是默认的Create页面,仅修改了下拉列表以获取qty和price值
2. 问题现象
提交表单时,输入框中的Qty、Price、Sum值始终被保存为0
3. 诉求
排查代码存在的问题
4. 原始前端+JavaScript代码
HTML表单部分
<form method="post"> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <div class="form-group"> <label asp-for="InvRows.ProdId" class="control-label">Produkti</label> <select asp-for="InvRows.ProdId" class="form-control" style="width:100%;font-size:80%;" id="xprod"> <option value="">--- Product name ---</option> @foreach (var item in Model.PL) { <option value="@item.ProdId" qty="1" price="@Convert.ToInt32(item.Price)"> @item.Prodname </option> } </select> </div> <div class="form-group"> <label asp-for="InvRows.Qty" class="control-label"></label> <input asp-for="InvRows.Qty" class="form-control" name="Qty" id="xqty" /> <span asp-validation-for="InvRows.Qty" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="InvRows.Price" class="control-label"></label> <input asp-for="InvRows.Price" class="form-control" name="Price" id="xPrice" /> <span asp-validation-for="InvRows.Price" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="InvRows.Sum" class="control-label">Shuma</label> <input asp-for="InvRows.Sum" class="form-control" name="Sum" id="xSum" /> <span asp-validation-for="InvRows.Sum" class="text-danger"></span> </div> <div class="form-group"> <input type="submit" value="Create" class="btn btn-primary" /> </div> </form> @section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
重复的JavaScript事件处理
// 下拉列表onchange方法1 <script> $("#xprod").change(function () { $("#xPrice").val($("#xprod").find("option:selected").text()); getSum(); }) function getSum() { var sum = parseInt($("#xPrice").val() * $("#xQty").val()); $("#xSum").val(sum); }; </script> // 数量/单价onchange方法 <script> $("#xQty").keyup(function () { getSum(); }) $("#xPrice").keyup(function () { getSum(); }) function getSum() { var sum = parseInt($("#xPrice").val() * $("#xQty").val()); $("#xSum").val(sum); }; </script> // 将下拉列表值复制到输入框的函数 <script> $("#xprod").change(function () { var qty = $(this).children('option:selected').attr("qty"); var price = $(this).children('option:selected').attr("price"); document.getElementsByName("Qty")[0].value = parseInt(qty); document.getElementsByName("Price")[0].value = parseInt(price); document.getElementsByName("Sum")[0].value = parseInt(price); }); </script> }
问题根源分析
模型绑定字段名称不匹配:
输入框手动指定了name="Qty"/Price/Sum,但后端模型绑定的目标是InvRows.Qty/Price/Sum。ASP.NET Core会根据name属性匹配模型属性,手动修改name后,后端无法正确映射到InvRows对象,导致默认值0被保存。重复的事件绑定与函数定义:
对#xprod绑定了3个不同的change事件,执行顺序不确定,会导致输入框值被错误覆盖;同时重复定义getSum函数,后定义的会覆盖前一个,引发逻辑混乱。DOM选择器大小写错误:
输入框ID为xqty(小写q),但getSum中使用$("#xQty")(大写Q),无法正确获取数量值,导致总价计算错误。初始Sum值设置错误:
最后一个change事件中,直接将Sum值设为price而非qty×price,不符合需求逻辑。
修复方案
1. 修正表单字段的name属性
移除手动指定的name属性,让asp-for自动生成符合模型绑定的name(InvRows.Qty/Price/Sum):
<div class="form-group"> <label asp-for="InvRows.Qty" class="control-label"></label> <input asp-for="InvRows.Qty" class="form-control" id="xqty" /> <span asp-validation-for="InvRows.Qty" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="InvRows.Price" class="control-label"></label> <input asp-for="InvRows.Price" class="form-control" id="xPrice" /> <span asp-validation-for="InvRows.Price" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="InvRows.Sum" class="control-label">Shuma</label> <input asp-for="InvRows.Sum" class="form-control" id="xSum" /> <span asp-validation-for="InvRows.Sum" class="text-danger"></span> </div>
2. 合并并修正JavaScript逻辑
删除重复代码,统一处理事件,修正选择器错误:
<script> // 下拉列表变更事件 $("#xprod").change(function () { var selectedOption = $(this).children('option:selected'); var qty = parseInt(selectedOption.attr("qty")) || 0; var price = parseInt(selectedOption.attr("price")) || 0; $("#xqty").val(qty); $("#xPrice").val(price); calculateSum(); }); // 数量、单价输入框键盘事件 $("#xqty").keyup(calculateSum); $("#xPrice").keyup(calculateSum); // 统一总价计算函数 function calculateSum() { var qty = parseInt($("#xqty").val()) || 0; var price = parseInt($("#xPrice").val()) || 0; $("#xSum").val(qty * price); } </script>
3. 脚本放置位置
将修正后的JS代码放入@section Scripts块内,确保DOM加载完成后执行:
@section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} <!-- 上述修正后的JS代码 --> }
内容的提问来源于stack exchange,提问作者Fillo
相关产品推荐
相关产品推荐

