使用渲染器来处理ExtJS表单字段

3
我想创建一个PercentField组件,它扩展了textfield用于在ExtJS表单上使用。我希望这个字段能够显示百分数值,例如 25%400% ,但是当用户编辑字段或表单被提交时,底层的值应该是小数,例如 0.254
我已经成功地通过在网格列中使用渲染器( 这里是一个 fiddle ) 来实现这一点,但是看起来textfield没有用于基本表单的渲染器属性。我已经查看了rawToValuevalueToRaw 方法,但它们似乎不完全符合我的需求。有什么建议吗?
1个回答

5
据我所知,表单字段的模板化是不可能的。这需要在焦点和失焦时翻转输入元素并显示一个 div 或其他内容。尽管可行,但这需要一些精细调整的 CSS。
更简单的方法是实现自定义的 valueToRawrawToValue 方法,并让 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;
        }
    }
});

谢谢,这看起来运行得非常好。我还添加了一个getSubmitValue的覆盖来处理提交。 - Cavyn VonDeylen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接