根据其他两个字段更改一个数字字段中的值
Change value in one numberfield based on two other fields
我在一个表单中创建了 3 个数字字段:
{
xtype: 'numberfield',
fieldLabel: 'Inhuur',
name: 'inhuurPrijs',
inputId: 'inhuurPrijs',
emptyText: '0'
},
{
xtype: 'numberfield',
fieldLabel: 'Marge %',
inputId: 'inhuurMarge',
emptyText: '0',
maxValue: 100,
minValue: -100
},
{
xtype: 'numberfield',
fieldLabel: 'Verhuur',
inputId: 'verhuurPrijs',
emptyText: '0'
},
在字段 'inhuurPrijs' 中,我填写了一个数字。例如 100。基于字段 'inhuurMarge',我想将价格设为 'verhuurPrijs'。 inhuurMarge 是一个百分比字段。因此,当用户选择值“10”时,'verhuurPrijs' 应该是 110。
我尝试了监听器,但它们不起作用。并使其更加复杂.....如果我填写 'inhuurPrijs' & 'verhuurPrijs' 我想计算它们之间的百分比并将其放入 'inhuurMarge'
这可能是一种形式吗?
您可以使用侦听器,将它们附加到字段以检测何时进行更改以及运行您的计算和更新总数。
如果上述 link 中断,这里是代码:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
bodyPadding: 5,
width: 350,
defaults: {
xtype: 'numberfield',
listeners: {
change: function(field, newVal, oldVal) {
console.log("Calculating");
var amount = Ext.getCmp('fieldAmount').getValue();
var markup = Ext.getCmp('feildMarkup').getValue();
var total = Ext.getCmp('fieldTotal');
if (amount > 0 && markup > 0) {
total.setValue(
amount + ((markup/amount) * 100)
);
}
}
}
},
items: [{
fieldLabel: 'amount',
name: 'amount',
id: 'fieldAmount'
}, {
fieldLabel: 'markup',
name: 'markup',
id: 'feildMarkup'
}, {
fieldLabel: 'total',
name: 'total',
id: 'fieldTotal'
}]
});
}
});
注意:您可能应该禁用总计/计算字段,以便无法对其进行手动编辑。
我实施的另一个解决方案是在商店的 update/datachanged 事件上添加监听器,而不是在表单字段上,这样即使您在其他地方更改数据,即使从console,不仅仅是那个特定的形式。
myStore.on('update', function(store, rec, op, fields, details, eOpts){
// run this only if desired fields have changed
if (fields && fields.some(function(item){
return /^amount/.test(item); // if field name starts with 'amount'
//return ['field_1', 'or_field_2', 'percentage_3'].indexOf(item) >= 0; // validation based on custom names, of course that still can be done using RegEx
})
) {
// custom number round function, see bellow why
var total = Ext.Number.round(rec.get('amount_one') * rec.get('amount_two') / 100);
rec.set('total', total);
}
});
我的模型中有总计字段,并从服务器检索它的默认值(如果需要),但我在其上设置了 persist: false
,以免将其发送回服务器。
关于自定义数字舍入方法,我很难发现 JavaScript 舍入方法不太精确,意思是:
Number((1.005).toFixed(2)); // 1 instead of 1.01
Math.round(1.005*100)/100; // 1 instead of 1.01
Jack Moore 构建了一个自定义函数,它似乎纠正了我在 Ext.Number
class 中实现的这个问题,所以所有功劳都归于他:http://www.jacklmoore.com/notes/rounding-in-javascript/
function round(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
另一个改进是它使用直接记录访问(如果需要,甚至可以使用关联数据),而不是性能不佳的 ComponentQuery。
最近我尽可能避免使用 Ext.getCmp()
,但如果我需要在视图(或事件父视图)中处理组件,我会使用 this.getView().lookupReference()
或 .up()
或 .down()
代替。
我在一个表单中创建了 3 个数字字段:
{
xtype: 'numberfield',
fieldLabel: 'Inhuur',
name: 'inhuurPrijs',
inputId: 'inhuurPrijs',
emptyText: '0'
},
{
xtype: 'numberfield',
fieldLabel: 'Marge %',
inputId: 'inhuurMarge',
emptyText: '0',
maxValue: 100,
minValue: -100
},
{
xtype: 'numberfield',
fieldLabel: 'Verhuur',
inputId: 'verhuurPrijs',
emptyText: '0'
},
在字段 'inhuurPrijs' 中,我填写了一个数字。例如 100。基于字段 'inhuurMarge',我想将价格设为 'verhuurPrijs'。 inhuurMarge 是一个百分比字段。因此,当用户选择值“10”时,'verhuurPrijs' 应该是 110。
我尝试了监听器,但它们不起作用。并使其更加复杂.....如果我填写 'inhuurPrijs' & 'verhuurPrijs' 我想计算它们之间的百分比并将其放入 'inhuurMarge'
这可能是一种形式吗?
您可以使用侦听器,将它们附加到字段以检测何时进行更改以及运行您的计算和更新总数。
如果上述 link 中断,这里是代码:
Ext.application({
name: 'Fiddle',
launch: function() {
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
bodyPadding: 5,
width: 350,
defaults: {
xtype: 'numberfield',
listeners: {
change: function(field, newVal, oldVal) {
console.log("Calculating");
var amount = Ext.getCmp('fieldAmount').getValue();
var markup = Ext.getCmp('feildMarkup').getValue();
var total = Ext.getCmp('fieldTotal');
if (amount > 0 && markup > 0) {
total.setValue(
amount + ((markup/amount) * 100)
);
}
}
}
},
items: [{
fieldLabel: 'amount',
name: 'amount',
id: 'fieldAmount'
}, {
fieldLabel: 'markup',
name: 'markup',
id: 'feildMarkup'
}, {
fieldLabel: 'total',
name: 'total',
id: 'fieldTotal'
}]
});
}
});
注意:您可能应该禁用总计/计算字段,以便无法对其进行手动编辑。
我实施的另一个解决方案是在商店的 update/datachanged 事件上添加监听器,而不是在表单字段上,这样即使您在其他地方更改数据,即使从console,不仅仅是那个特定的形式。
myStore.on('update', function(store, rec, op, fields, details, eOpts){
// run this only if desired fields have changed
if (fields && fields.some(function(item){
return /^amount/.test(item); // if field name starts with 'amount'
//return ['field_1', 'or_field_2', 'percentage_3'].indexOf(item) >= 0; // validation based on custom names, of course that still can be done using RegEx
})
) {
// custom number round function, see bellow why
var total = Ext.Number.round(rec.get('amount_one') * rec.get('amount_two') / 100);
rec.set('total', total);
}
});
我的模型中有总计字段,并从服务器检索它的默认值(如果需要),但我在其上设置了 persist: false
,以免将其发送回服务器。
关于自定义数字舍入方法,我很难发现 JavaScript 舍入方法不太精确,意思是:
Number((1.005).toFixed(2)); // 1 instead of 1.01
Math.round(1.005*100)/100; // 1 instead of 1.01
Jack Moore 构建了一个自定义函数,它似乎纠正了我在 Ext.Number
class 中实现的这个问题,所以所有功劳都归于他:http://www.jacklmoore.com/notes/rounding-in-javascript/
function round(value, decimals) {
return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}
另一个改进是它使用直接记录访问(如果需要,甚至可以使用关联数据),而不是性能不佳的 ComponentQuery。
最近我尽可能避免使用 Ext.getCmp()
,但如果我需要在视图(或事件父视图)中处理组件,我会使用 this.getView().lookupReference()
或 .up()
或 .down()
代替。