Search code examples
extjsextjs6

How to set length of a combo box to only allow one of two values


I have the combobox minLength set to 5. I want the combobox to require the length to be 5. If it is longer than 5, I want the minLength to be set to 10. So the outcome should be: the min length can be either 5 or 10, nothing else. (The ComboBox will not accept an input with a length of less than 5 or greater than 10, it also will not accept a length equal to 6, 7, 8, or 9).

Here is my code for example:

  xtype: 'combobox', 
  minLength: 5,
  maxLength: 10,
  maskRe: /[0-9.-]/,
  validator: function(v) {
    //this only allows numbers and a hyphen to be entered into the combo box,
    //while also requiring 4 digits to be entered after the hyphen 
    //(only if a hyphen is present)
    return /^[0-9]*(-?[0-9]{4})?$/.test(v)? true : 'A Postal Code should only include a hyphen if there are four digits after the hyphen!';
  },

Solution

  • As far as I know there is no built-in solution for that, but you can do it. Check the code below and this fiddle, this is for ExtJS 7.5 Classic Material, but it can likely be adopted to other version / toolkit.

    Some notes:

    • You have to set a store, even if it's empty, otherwise the change listener will not be called. (I don't know if it is a bug or a feature.)
    • The solution uses a ViewModel and binds the minLength to this. The reason you need setMinLength and setMaxLength is that ExtJS doesn't provide it and getter / setter is required for binding.
    • Important: since this is not an 'official' solution there is no guarantee it will always work.
    Ext.application({
        name: 'MyApp',
        launch: function () {
            Ext.create('Ext.form.Panel', {
                renderTo: Ext.getBody(),
                items: [{
                    xtype: 'combo',
                    minLength: 5,
                    maxLength: 10,
                    maskRe: /[0-9.-]/,
                    viewModel: {
                        data: {
                            minLength: 5
                        }
                    },
                    store: [],
                    bind: {
                        minLength: '{minLength}'
                    },
                    setMinLength: function (v) {
                        this.minLength = v;
                    },
                    getMinLength: function () {
                        return this.minLength;
                    },
                    validator: function (v) {
                        return /^[0-9]*(-?[0-9]{4})?$/.test(v) ? true : 'A Postal Code should only include a hyphen if there are four digits after the hyphen!';
                    },
                    listeners: {
                        change: function (combo, newValue, oldValue, eOpts) {
                            const newMinLength = newValue == null ? 5 : newValue.length >= 5 ? 10 : 5;
                            console.log('New min length will be: ' + newMinLength);
                            combo.getViewModel().set('minLength', newMinLength);
                        }
                    }
                }]
            });
        }
    });