Use Renderer for ExtJS Form Field

I am trying to create a PercentField component that extends textfield

for use in ExtJS forms. The behavior I'm looking for is a field to display percentage values, eg. 25%

or 400%

, but have a basic meaning when the user is editing the field or the form is represented as decimal, for example. .25

or 4

.

I managed to get this working using a renderer on a grid column, ( fiddle here) , but it doesn't look like it textfield

has a renderer property for using a field in basic forms. I've looked at the methods rawToValue

and valueToRaw

, but they don't seem to be exactly what I'm looking for. Any advice?

+3


source to share


1 answer


As far as I know, there is no template option for form fields. This would require flipping the input element and displaying a div or whatever, focusing and blurring. It would be doable, but it does involve some finely tuned CSS.

An easier option is to implement custom methods valueToRaw

and rawToValue

, while Ext handles the value lifecycle (this is the really tricky part). You will still have to change the original value to focus and blur, but it remains pretty simple.



Here's an example you can build on (see 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;
        }
    }
});

      

+5


source







All Articles