我必须将价格一分为二。因此,我得到了方程price_1 + price_2 = total_price
。因为我很好,我会允许用户更改3个参数中的任何一个。我必须在我的前端轨道视图中反映这一点。
当然,在数据库方面,我只存储其中两个值:)price_1和total_price
所以在我看来:
<%= f.number_field :price_1, :step => 0.1, class: "form-control" %>
<%= f.number_field :total_price, :step => 0.1, class: "form-control" %>
我认为我可以为第三个做什么:
<input id="price_2" type:"number" step="0.1">
并与javascript同步。当然,问题是这3个输入是可编辑的。因此,假设编辑price_1应该只更改price_2,反之亦然,而更改total_price应该只更改price_one(如果某个聪明的用户将price_1设置为0并降低total_price,则可能会对price_2采取措施…)
我很少看到关于这个的问题(或者可能我找不到好的答案,因为关键字不好)。这是一个快速的解决方案,但肯定会失败:
var global_lock = true
$("#price_1").on("change"){
global_lock = !global_lock
if(!global_lock){
$("#price_2").attr("value", (Integer.parse($("total_price").attr("value")) - Integer.parse($("price_1").attr("value")))
}
}
有更好的吗?也许我可以使用rails助手轻松集成?
编辑:
让我们抽象一下:p。相反,我有一个随机方程f(price_1, price_2, total_price) = 0
。因此,我的代码变成
var global_lock = 2
$("#price_1").on("change"){
global_lock = (global_lock++) % 3;
if(global_lock == 0){
//Jquery stuff that always modifies both price_2 and total_price
}
}
//Similar for price_2 and total_price
我在rails应用程序中实现了类似的功能。
如果您想在视图中保留所有ruby,可以使用number_field标记。
<%= number_field_tag(:price_2,nil,:step => 0.1) %>
我对你正在努力实现的目标的理解是:
- 您目前有3个字段可供用户编辑,分别命名为
price_1
、price_2
和total_price
total_price
是price_1
和price_2
的和- 当3个字段中的任何一个发生更改时,您希望根据其他2个字段各自的方程式更新它们
方程式如下:
价格_1已更改:
price_2 = total_price - price_1
价格_2已更改:
price_1 = total_price - price_2
总计价格已更改:
如果total_price
的变化大于原始总价格,则
price_1 = price_1 + (total_price - old_total_price)
如果变化小于原始总价格,则
if price_1 < (old_total_price - total_price) then
price_1 = 0 and price_2 = price_2 - ( (old_total_price - total_price) - price_1)
else
price_1 = price_1 - (old_total_price - total_price)
很明显,如果total_price
被设置为0,那么一切都是0
如果我是对的,那么我会写这样的函数:
Javascript
我对你使用global_lock
有点困惑,所以如果我偏离了轨道,请告诉我。我已经编写了3个与任何更改绑定的函数,每个字段一个。希望这就是你想要的
var price_1 = $("#price_1");
var price_2 = $("#price_2");
var total_price = $("#total_price");
price_1.bind("change", function () {
var p1 = Number(price_1.val());
var total = Number(total_price.val());
switch (true){
case (p1 > total ):
price_1.val(total);
price_2.val(0);
break;
case (p1 < 0 ):
price_1.val(0);
price_2.val(total);
break;
default:
price_2.val(Math.round((total - p1)*100)/100);
break;
}
});
price_2.bind("change", function () {
var p2 = Number(price_2.val());
var total = Number(total_price.val());
switch (true){
case (p2 > total ):
price_1.val(0);
price_2.val(total);
break;
case (p2 < 0 ):
price_2.val(0);
price_1.val(total);
break;
default:
price_1.val(Math.round((total - p2)*100)/100);
break;
}
});
total_price.bind("change", function () {
var total = Number(total_price.val());
if (total < 0) {total = 0}
var old_total = Number(price_1.val()) + Number(price_2.val());
var total_difference = old_total - total;
var p1 = Number(price_1.val());
var p2 = Number(price_2.val());
switch (true){
case (p1 < total_difference):
price_1.val(0);
price_2.val(p2 - (total_difference - p1));
break;
default:
price_1.val(p1 - total_difference);
break;
}
});