Combobox that automatically adjusts the value

I have a combobox in which you can select a specific period of time, for example:

5 minutes 15 minutes 1 hour 2 hours 1 day 2 days 1 week 2 weeks 

It always passes the number of minutes to the server, but the user does not understand what β€œ10080” means (before you try to calculate: this is a week).

The new requirement is that the user should be able to enter arbitrary values ​​in this field. For instance. β€œ20 minutes”, β€œ1 hour 5 minutes”, β€œ2h 5m” or β€œ1d 6h 120m”; and that if the field is set to a certain value (for example, 75) programmatically, the field should display the correct line (1 hour 15 minutes)

So, I wrote a parser and a formatting function (see below), but how can I use its combobox?

I already tried to override a couple of rawToValue / valueToRaw functions, similar to what I found in the datefield code:

 rawToValue:function(rawValue) { console.log('rawToValue'); console.log(rawValue); return this.parse(rawValue) || rawValue || null; }, valueToRaw:function(value) { console.log('valueToRaw'); console.log(value); return this.format(value); }, 

but they are not called, I do not get output to the console log.

These are the parser / formatting functions:

 Ext.define('AlarmTimeField',{ extend:'Ext.form.field.ComboBox', format:function(minutes) { var a = []; Ext.each(this.units, function(unit) { if(minutes >= unit.minutes) { var unitCount = Math.floor(minutes/unit.minutes); console.log(unitCount); minutes = minutes-unitCount*unit.minutes; a.push("" + unitCount + " " + (unitCount==1?unit.singular:unit.plural)); } }); return a.join(' '); }, parse:function(input) { if(!input) return 0; var me=this, inputSplit = input.split(' '), value = 0, lastNum = 0; Ext.each(inputSplit,function(input) { if(!input) return; else if(Ext.isNumeric(input)) lastNum = input; else if(Ext.isNumeric(input[0])) { var inputUnit = input.slice(-1), inputValue = input.slice(0,-1); Ext.each(me.units,function(unit) { if(inputUnit==unit.abbr) { value+=unit.minutes*inputValue; } }); } else { Ext.each(me.units,function(unit) { if(input==unit.singular || input==unit.plural || input==unit.abbr) { value+=unit.minutes*lastNum; } }); } }); return value; }, units:[{ minutes:10080, abbr:'w', singular:'week', plural:'weeks' },{ minutes:1440, abbr:'d', singular:'day', plural:'days' },{ minutes:60, abbr:'h', singular:'hour', plural:'hours' },{ minutes:1, abbr:'m', singular:'minute', plural:'minutes' }] }); 
+5
source share
1 answer

The basic idea is that the value of Ext.form.field.ComboBox is actually an instance of Ext.data.Model , so your value and displayed value are only model attribute values, and every time you change the value / displayed value, you need to update the instance instance with binding (its my vision, correct me if I am wrong).

I think Ext.form.field.ComboBox.validator is a good place to parse manually entered values (and you can instantly display an error message if the entered value is incorrect), so you can override it like this:

  validator: function (value) { // TODO: Add regexp value format validator var minutes = me.parse(value); // Add check for zero / empty values if needed if (minutes === 0) // Add meaningful error message return 'Incorrect input'; else { me.setValue(Ext.create('Ext.data.Model', { value: minutes, text: value })); return true; } } 

Its a rather crude example, but I think the idea is clear.

To format values ​​set programmatically using the setValue() method, you can override this method, for example:

  setValue: function (value) { // TODO: Add array of values support if (Ext.isNumber(value)) value = Ext.create('Ext.data.Model', { value: value, text: this.format(value) }); this.callParent([value]); } 

Check out your plug . Hope I helped a bit.

+1
source

Source: https://habr.com/ru/post/1264943/


All Articles