我有下表与可编辑字段(列)。
我对sellprice或casecost列字段所做的任何更改,我希望GP列字段在用户输入或更改值时更新。我的代码如下。
function calculate() {
$('tr #item_q_sellprice').change(function calculate() {
//$('.productTable tr').on('change','#item_q_sellprice,#item_q_casecost',function calculate() {
// $("input[type=text]").change(function () {
//fields used for calculations
var newPrice = parseFloat($('tr #item_q_sellprice').val());
var casecost = parseFloat($('tr #item_q_casecost').val());
var casesize = parseFloat($('tr #item_q_casesize').val());
var vatrate = parseFloat($('tr #item_productVat').val());
//formulae
var netprice = newPrice / (1 + vatrate / 100);
var unitcost = casecost / casesize;
var profit = (newPrice / (vatrate / 100 + 1)) - unitcost;
var grossprofit = (profit / netprice) * 100
//alert("change price: " + price);
//Update GP field
$('#item_grossProfit').val(grossprofit.toFixed(1));
});
}
我的行的Html如下
@foreach (var item in Model)
{
<tr>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.DisplayFor(modelItem => item.q_description)
</td>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.DisplayFor(modelItem => item.q_barcode)
</td>
<td>
€ @Html.TextBoxFor(modelItem => item.q_sellprice, "{0:0.00}", new { @class = "calc-list" })
</td>
<td>
€ @Html.TextBoxFor(modelItem => item.q_casecost, "{0:0.00}", new { @class = "calc-list" })
</td>
<td>
@Html.TextBoxFor(modelItem => item.grossProfit, new { @class = "calc-list" })
</td>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.DisplayFor(modelItem => item.productDepartment)
</td>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.TextBoxFor(modelItem => item.productVat, "{0:0.0}",new { @class = "calc-list", @readonly = "readonly" })
</td>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.DisplayFor(modelItem => item.q_stocklevel)
</td>
<td onclick="location.href = '@(Url.Action("Index", "Product", new { id = item.q_guid }))'">
@Html.TextBoxFor(modelItem => item.q_casesize, new { @class = "calc-list", @readonly = "readonly" })
</td>
</tr>
}
现在,这当前仅适用于顶行,而不适用于表行的其余部分。我猜错误将出现在我的变量行上
var newPrice = parseFloat($('tr #item_q_sellprice').val());
如何更改/更新这些字段(sellprice / casecost)的任何行还会更新相应的GP列?
您使用foreach
循环生成重复的id
属性,这是无效的html,以及您的脚本失败的原因。例如,使用$('tr #item_q_sellprice').val()
只返回第一个元素的值,使用id
。
更重要的是,使用foreach
循环意味着您的视图永远不会正确绑定。相反,你需要使用for
循环或EditorTemplate
- 更多细节参考Post an HTML Table to ADO.NET DataTable)。
在计算中为类名提供您需要的元素,然后使用相对选择器在同一容器中查找关联元素(您的<tr>
)。
视图应该是(使用for
循环)
@for(int i = 0; i < Model.Count; i++)
{
<tr>
....
@Html.TextBoxFor(m => m[i].q_sellprice, "{0:0.00}", new { @class = "sell-price calc-list" })
@Html.TextBoxFor(m => m[i].q_casecost, "{0:0.00}", new { @class = "case-cost calc-list" })
....
</tr>
}
然后你的脚本变成了
$('.sell-price, .case-cost').change(function calculate() {
// Get the containing table row
var row = $(this).closest('tr');
var newPrice = Number(row.find('.sell-price').val());
var casecost = Number(row.find('.case-cost').val());
....
// calculate results
row.find('.gross-profit').val(grossprofit.toFixed(1))
});
作为旁注,您应该检查值是否有效(如果在文本框中输入的值无效,则parseFloat
和Number()
将返回NAN
),例如
if (isNaN(newPrice) || isNaN(casecost) {
// its invalid and the calculation would fail
此外,由于grossProfit
是计算值,因此不应将其生成为文本框。而是在<span>
中使用(比方说)<td>
来显示计算值(并且应该在POST方法中在服务器上重新计算该值以防止恶意用户更改请求)