我正在尝试创建一个扩展textfield
的PercentField组件,以便在ExtJS表单上使用。我正在寻找的行为是字段显示百分比值,例如25%
或400%
,但在用户编辑字段或提交表单时具有基础值,例如小数,例如.25
或4
。
我已成功通过在网格列中使用渲染器(Here's a fiddle)来实现此功能,但看起来textfield
具有渲染器属性,以便在基本表单中使用该字段。我查看了rawToValue
和valueToRaw
方法,但它们似乎并不是我想要的。有什么建议吗?
答案 0 :(得分:5)
据我所知,表单字段没有模板的可能性。这将需要翻转输入元素并在焦点和模糊时显示div或其他内容。这是可行的,但这意味着一些精心调整的CSS。
更简单的选择是实现自定义valueToRaw
和rawToValue
方法,并让Ext处理值生命周期(这实际上是复杂的部分)。您仍然需要更改焦点和模糊的原始值,但这仍然非常简单。
以下是您可以构建的示例(请参阅fiddle):
Ext.define('My.PercentTextField', {
extend: 'Ext.form.field.Text',
onFocus: function() {
this.callParent(arguments);
var v = this.getValue();
if (Ext.isNumeric(v)) {
this.setRawValue(this.rawToValue(v));
}
},
onBlur: function() {
this.callParent(arguments);
var v = this.getValue();
if (Ext.isNumeric(v)) {
this.setRawValue(this.valueToRaw(v));
}
},
valueToRaw: function(v) {
return Ext.isEmpty(v)
? ''
: v * 100 + ' %';
},
rawToValue: function(v) {
// cast to float
if (!Ext.isEmpty(v)) {
var pcRe = /^(\d*(?:\.\d*)?)\s*%$/,
dcRe = /^\d*(?:\.\d*)?$/,
precision = 2,
floatValue,
match;
if (match = dcRe.test(v)) { // decimal input, eg. .33
floatValue = v * 1;
} else if (match = pcRe.exec(v)) { // % input, eg. 33 %
floatValue = match[1] / 100;
} else {
// invalid input
return undefined;
}
floatValue = Number.parseFloat(floatValue);
if (isNaN(floatValue)) {
return undefined;
} else {
return floatValue.toFixed(precision);
}
} else {
return undefined;
}
}
});