In ExtJs 3.3.1, how can I show a ComboBox drop down without click in EditorGrid?

Justin picture Justin · Sep 15, 2011 · Viewed 10.5k times · Source

I am using ExtJs 3.3.1.

Within an EditorGrid, my "editable" column has a ComboBox as its editor. How can I have the ComboBox always showing for each row? Meaning, the user would not have to click on a cell to know there is a ComboBox there. Currently, I have clicksToEdit set to 1, but I wish I could set this to 0 (I tried that).

See some of my code below to see my current configuration.

var combo = new Ext.form.ComboBox({
    typeAhead: true,
    triggerAction: 'all',
    lazyRender: true,
    mode: 'local',
    store: new Ext.data.ArrayStore({
        id: 0,
        fields: [
            'statusId',
            'displayText'],
        data: data
    }),
    valueField: 'statusId',
    displayField: 'displayText'
});

var cm = new Ext.grid.ColumnModel({
    columns: [{
        id: 'orderId',
        header: 'ID',
        dataIndex: 'id',
        width: 50
    }, {
        header: 'Status',
        dataIndex: 'status',
        width: 130,
        editor: (data.length == 1) ? null : combo,
        renderer: Ext.util.Format.comboRenderer(combo)
    }, {
        id: 'orderSummary',
        header: 'Summary',
        dataIndex: 'summary',
        renderer: this.renderSummary
    }]
});

var orderGrid = new Ext.grid.EditorGridPanel({
    store: this.getOrderStore(),
    cm: cm,
    autoExpandColumn: 'orderSummary',
    clicksToEdit: 1
});

Answer

Justin picture Justin · Sep 15, 2011

Here is the solution I came up with.

  1. In my column model, I made sure that the column I am making "editable" has an id. Each cell in that column will now have a CSS class associated with it named "x-grid-col-{id}". My column id is "status" so the class was "x-grid-col-status".

  2. I created the CSS for class "x-grid-col-status" which sets the dropdown arrow image as the background, aligned right. It also sets the cursor to pointer, so the user knows they can click on the cell.

    .x-grid3-col-status
    {
        background-image: url(Image/trigger-single.gif);
        background-position: right;
        background-repeat: no-repeat;
        cursor: pointer;
    }
    
  3. Next, I set up a listener for my ComboBox that listens for the 'focus' event. On focus, I expand the drop down. It is important that I had to add lazyInit: false to my ComboBox config, or else an empty list will appear when you expand. lazyInit - true to not initialize the list for this combo until the field is focused (defaults to true)

The code:

    Ext.util.Format.comboRenderer = function (combo) {
            return function (value, metaData, record, rowIndex, colIndex, store) {
                var record = combo.findRecord(combo.valueField, value);
                return record ? record.get(combo.displayField) : combo.valueNotFoundText;
            }
        }        

    var combo = new Ext.form.ComboBox({
            typeAhead: true,
            triggerAction: 'all',
            lazyInit: false,
            lazyRender: true,
            mode: 'local',
            editable: false,
            store: new Ext.data.ArrayStore({
                id: 0,
                fields: [
                    'statusId',
                    'displayText'
                ],
                data: data
            }),
            valueField: 'statusId',
            displayField: 'displayText',
            listeners: {
                'focus': {
                    fn: function (comboField) {
                        comboField.doQuery(comboField.allQuery, true);
                        comboField.expand();
                    }
                    , scope: this
                }
                , 'select': {
                    fn: function (comboField, record, index) {
                        comboField.fireEvent('blur');
                    }
                    , scope: this
                }
            }
        });

        var cm = new Ext.grid.ColumnModel({
            defaults: {
                sortable: true
            },
            columns: [
                {
                    id: 'orderId',
                    header: 'ID',
                    dataIndex: 'id',
                    width: 50
                }, {
                    header: 'Status',
                    id: 'status',
                    dataIndex: 'status',
                    width: comboColumnWidth,
                    editor: combo,
                    renderer: Ext.util.Format.comboRenderer(combo)
                }, {
                    id: 'orderSummary',
                    header: 'Summary',
                    dataIndex: 'summary',
                    renderer: this.renderSummary
                }
            ]
        });

        var orderGrid = new Ext.grid.EditorGridPanel({
            store: this.getOrderStore(),
            cm: cm,
            autoExpandColumn: 'orderSummary',
            title: title,
            clicksToEdit: 1
        });