Search code examples
extjscomboboxgridextjs3

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


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
});

Solution

  • 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
            });