Vlad
Vlad

Reputation: 2773

How to disable items in a combobox in Ext JS?

How can I disable specific items in a combobox in Ext JS?

For example I have these records

row_1_type_1
row_2_type_2
row_3_type_3

and I want to disable the third row i.e it should stay in the combo as label but it will be greyed out and not clickable.

Upvotes: 5

Views: 9872

Answers (4)

A1rPun
A1rPun

Reputation: 16837

You can try something like this with the listConfig:

myItems: [
    { name: 'row_1_type_1',  disabled: false},
    { name: 'row_2_type_2',  disabled: false},
    { name: 'row_3_type_3',  disabled: true }
]

listConfig: {
    getInnerTpl: function(displayField) {
        return Ext.create('Ext.XTemplate',
            '<ul><li role="option"',
            '<tpl for=".">',
            '<tpl if="disabled == true">',
                'class="x-disabled-item"',
            '<tpl else>',
                'class="x-custom-item"',
            '</tpl>',
            '>{#} - {name}</li></ul>'
        );
    }
}

//CSS
.x-disabled-item
{
}

.x-custom-item
{
}

You can find more about templates in the docs

Upvotes: 3

Sergey Bogdanov
Sergey Bogdanov

Reputation: 673

Very tricky example by ordman and a bit complicated by Christiaan. You can use my simpler example as an alternative.

It is supposed usually that disabled param comes from backend in boolean value, so you need to make some calculations on it.

By the way adding x-item-disabled class makes an item unchoosable. If you need just point out disabled item with the ability to choose, I use small part of inline style, so you dont need touch css classes.

Also you can use conditions and operate with all record data by adding function to Ext.XTemplate.

Here is working example for 7.6 and 6.6:

   Ext.create('Ext.form.ComboBox', {
        fieldLabel: 'Choose State',
        store: states,
        queryMode: 'local',
        valueField: 'abbr',
        displayField: 'name',
        renderTo: Ext.getBody(),
        tpl: Ext.create('Ext.XTemplate',
            '<ul class="x-list-plain"><tpl for=".">',
                '{[this.getItemTpl(values)]}',
            '</tpl></ul>',
            {
                getItemTpl: function(itm) {
                    const colorStyle = (itm.isActive) ? '' : 'style="color:grey"';
                    // uncomment disabledCls to make item unchoosable
                    //const disabledCls = (itm.isActive) ? '' : 'x-item-disabled';
                    return `<li role="option" class="x-boundlist-item ${disabledCls}" ${colorStyle}> ${itm.abbr} - ${itm.name}</li>`;
                }
            }
        )
    });

Upvotes: 2

ordman
ordman

Reputation: 225

Solution for Ext6

Ext.application({
    name: 'Fiddle',

    launch: function () {

        var states = Ext.create('Ext.data.Store', {
            fields: ['abbr', 'name', 'disabled'],
            data: [{
                "abbr": "AL",
                "name": "Alabama",
                "disabled": '',
            }, {
                "abbr": "AK",
                "name": "Alaska",
                "disabled": 'x-item-disabled',
            }, {
                "abbr": "AZ",
                "name": "Arizona",
                "disabled": '',
            }]
        });

        Ext.create('Ext.form.ComboBox', {
            fieldLabel: 'Choose State',
            store: states,
            queryMode: 'local',
            valueField: 'abbr',
            renderTo: Ext.getBody(),
            // Template for the dropdown menu.
            // Note the use of the "x-list-plain" and "x-boundlist-item" class,
            // this is required to make the items selectable.
            tpl: Ext.create('Ext.XTemplate',
                '<ul class="x-list-plain"><tpl for=".">',
                '<li role="option" class="x-boundlist-item {disabled}">{abbr} - {name}</li>',
                '</tpl></ul>'
            ),
            // template for the content inside text field
            displayTpl: Ext.create('Ext.XTemplate',
                '<tpl for=".">',
                '{abbr} - {name}',
                '</tpl>'
            )
        });

    }
});

Try code here https://fiddle.sencha.com/#view/editor

Upvotes: 1

Christiaan Westerbeek
Christiaan Westerbeek

Reputation: 11137

Here's a solutions that you can use at least for Ext JS 4.2.1. It's a plugin that disables some items in the boundlist based on the value of each record. The name of the field to check if the listitem should be disabled can be configured.

Let's start with how to use the plugin.

{
    xtype: 'combo',
    fieldLabel: 'My combo with disabled items',
    valueField: 'value',
    displayField: 'display',
    queryMode: 'local',
    store: {
        fields: ['value', 'display', 'disabled'],
        data: [{
            value: 1, display: 'an enabled item', disabled: false
        },{
            value: 2, display: 'a disabled item', disabled: true
        }]
    },
    plugins: [{
        ptype: 'comboitemsdisableable',
        disabledField: 'disabled'
    }]
}

And here's the plugin.

Ext.define('Ext.ux.plugin.ComboItemsDisableable', {
    extend: 'Ext.AbstractPlugin',
    alias: 'plugin.comboitemsdisableable',

    init: function (cmp) {
        var me = this; // the plugin
        me.disabledField = me.disabledField || 'disabled';

        cmp.tpl = Ext.create('Ext.XTemplate',
            '<tpl for=".">',
            '  <tpl if="this.isDisabled(' + me.disabledField + ')">',
            '    <div class="x-boundlist-item x-item-disabled"><em>{' + cmp.displayField + '}</em></div>',
            '  <tpl else>',
            '    <div class="x-boundlist-item">{' + cmp.displayField + '}</div>',
            '  </tpl>',
            '</tpl>', {
                isDisabled: function(disabled) {
                    return disabled;
                }
            }
        );

        // make sure disabled items are not selectable
        cmp.on('beforeselect', function(combo, record, index) {
            return !record.get(me.disabledField);
        });
    }
});

And here's some css to go with the plugin. It greys out the disabled items and makes sure that the disabled items when hovered don't get its background changed as to suggest that it would be selectable.

.x-item-disabled.x-boundlist-item {
    color: #8c8c8c;
    cursor: default;
}

.x-item-disabled.x-boundlist-item-over {
    background: inherit;
    border-color: white;
}

Upvotes: 8

Related Questions