To meet the functional requirements, we will create an extension class by extending the Ext JS's Ext.form.field.Spinner
class from which we will get most of the facilities that we need to provide. We need to implement the onSpinUp
and onSpinDown
functions of the Ext.form.field.Spinner
class to handle the spinner button click event to provide our logic to increase or decrease the values. By default, pressing the up and down arrow keys will also trigger the onSpinUp
and onSpinDown
methods. Now, let us start coding:
Ext.define('Examples.ux.LabeledSpinner', { extend : 'Ext.form.field.Spinner', alias : 'widget.labeledspinner', onSpinUp : function() { this.setValue(++this.value); }, onSpinDown : function() { this.setValue(--this.value); } });
And now we have a working extension that can increase or decrease its value. Here is the screenshot where we used this extension:
You can see that we now have a field with up/down spinner buttons with which we can increase or decrease the value by 1.
Now, we will add a functionality that this field can show the unit label text just beside the numeric value. We will define the
setValue
function from which we can set the value including the label unit. We will also add some config
properties to this class so that we can set the values as we needed:
Ext.define('Examples.ux.LabeledSpinner', { extend : 'Ext.form.field.Spinner', alias : 'widget.labeledspinner', config : { labelText : ", minValue: 0, value: 0 }, onSpinUp : function() { var value = parseFloat(this.getValue().split(' ')[0]); this.setValue(++value); }, onSpinDown : function() { var value = parseFloat(this.getValue().split(' ')[0]); this.setValue(--value); }, setValue : function(value) { value = (value ||this.minValue) + ' ' +this.getLabelText(); this.callParent(arguments); } });
In the following screenshot, we can see the label just beside the numeric value within the field:
Within the code, you can find that we have provided some config
options, added the setValue
function, and modified a little of the onSpinUp
and onSpinDown
functions.
Now, we will define the getValue
function so that we can get the numeric value from this field and define the getLabeledValue
function that will return the numeric value, including the unit label, exactly as it shows on the field. We will also define the onBlur
handler to check and fix it with a minimum value, if there is any wrong input and will do some changes on the existing code. Here is the complete code for our extension:
Ext.define('Examples.ux.LabeledSpinner', { extend : 'Ext.form.field.Spinner', alias : 'widget.labeledspinner', config : { labelText : '', minValue : 0, maxValue : Number.MAX_VALUE, step : 1, value : 0 }, onBlur : function() { if (isNaN(this.getValue())) { this.setValue(this.getLabeledValue(this.getMinValue())); } else{ this.setValue(this.getLabeledValue()); } }, onSpinUp : function() { var val = this.getValue() || this.getMinValue(); this.setChangedValue(val + this.step); }, onSpinDown : function() { var val = this.getValue() || this.getMinValue(); this.setChangedValue(val - this.step); }, getLabeledValue : function(value) { value = Ext.isDefined(value) ? value : this.getValue(); if (value.toString().indexOf(this.getLabelText()) == -1) { return value + ' ' + this.getLabelText(); } else { return value; } }, setValue : function(value) { if(!this.readOnly){ value = this.getLabeledValue(value); } this.callParent(arguments); }, getValue : function() { var me = this, val = me.rawToValue(me.processRawValue(me.getRawValue())); val = parseFloat(val.split(' ')[0]); return val; }, setChangedValue : function(value){ if(!isNaN(value)){ this.setValue(Ext.Number.constrain(value, this.getMinValue(), this.getMaxValue())); } } });
And following is the screenshot of our working LabeledSpinner extension:
In the preceding screenshot, we can find the Get value button within the window. When this button is clicked, we print the values on the window by calling both the getValue
and getLabeledValue
functions.