4
votes

I have a grid with some columns to be edited. One of the columns should be edited through a combobox. The combobox store is remote and is of a key value pair type:

['id', 'title']

The combobox valueField is id and the displayValue is title. When editing a cell my combobox loads the store, the displayValue is selected and the valueField is returned to the grid editor. So the cell is then filled with the valueField.

My question is: how do I get the cell to render the displayValue? Just selecting it from the store is not good enough since the render happens before the store is loaded. My code for now (that works with local stores only):

{
    header: 'Column title',
    dataIndex: 'id',
    displayField: 'title',
    editor: {
        xtype: 'combo',
        valueField: 'id',
        store: 'myStore',
        displayField: 'title'
    },
    renderer: function(value) {
        //How do I find the editors combobox store?
        store = new myStore();
        index = store.findExact('id', value);
        if (index != -1) {
            rs = store.getAt(index).data;
            return rs.title;
        }
        return value;
    }
}
4

4 Answers

3
votes

This is how I did it:

I have 2 stores, storeA for the grid and storeB for the value to be selected (as described above). Both stores have an ID from storeB.

I ended up adding a field to storeA - the title for storeB ID. And in the grid i have this title as a hidden column. And in the combobox editor column i use this renderer:

  renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
       //Title is the title for the storeB ID
       return store.data.items[rowIndex].data.title;
  }

On the grid I have a listener for the edit event to update the column containing the title with the title from the combobox:

  grid.on('edit', function(editor, e, eOpts ) {
       grid.store.data.items[e.rowIdx].set('title', editor.editors.items[0].field.rawValue)
  })

Hope this helps someone else!

2
votes

In your model definitions, what is the type of 'id'. If you define as 'int', you have to:

index = store.findExact('id', parseInt(value));
0
votes

Value is not the only parameter passed in to the renderer see docs: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.column.Column-cfg-renderer

value : Object

The data value for the current cell
**metaData** : Object

A collection of metadata about the current cell; 

can be used or modified by the renderer. Recognized properties are: tdCls, tdAttr, and style.

**record** : Ext.data.Model

The record for the current row
**rowIndex** : Number

The index of the current row
**colIndex** : Number

The index of the current column
**store** : Ext.data.Store

The data store
**view** : Ext.view.View

The current view
0
votes

Here's the answer, bring the combo store into the scope of your renderer:

http://jsfiddle.net/WRXcw/3/

Ext.define('GridModel', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'id',
        type: 'int'
    },{
        name: 'type_id',
        type: 'int'
    }]
});

Ext.define('ComboModel', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'id',
        type: 'int'
    },{
        name: 'label',
        type: 'string'
    }],
    statics: {
        TYPE_OPTION_ONE:   1,
        TYPE_OPTION_TWO:   2,
        TYPE_OPTION_THREE: 3,
        TYPE_OPTION_FOUR:  4
    }
});

var comboStore = Ext.create('Ext.data.Store', {
    model: 'ComboModel',
    data: [{
        id: 1,
        label: '1st Option'
    },{
        id: 2,
        label: '2nd Option'
    },{
        id: 3,
        label: '3rd Option'
    }]
});

var gridStore = Ext.create('Ext.data.Store', {
    model: 'GridModel',
    data: [{
        id: 1,
        type_id: ComboModel.TYPE_OPTION_ONE
    },{
        id: 2,
        type_id: ComboModel.TYPE_OPTION_TWO
    },{
        id: 3,
        type_id: ComboModel.TYPE_OPTION_THREE
    },{
        id: 4,
        type_id: ComboModel.TYPE_OPTION_TWO
    }]
});

Ext.widget('grid', {
    title: 'Rendering Combos',
    width: 650,
    height: 500,
    renderTo: 'ct',
    plugins: [
        Ext.create('Ext.grid.plugin.CellEditing', {
            clicksToEdit: 1
        })
    ],
    store: gridStore,
    forceFit: true,
    columns: [{
        dataIndex: 'id',
        header: 'ID'
    },{
        dataIndex: 'type_id',
        header: 'Type',
        editor: {
            xtype: 'combobox',
            displayField: 'label',
            valueField: 'id',
            queryMode: 'local',
            store: comboStore,
            allowBlank: true
        },
        renderer: function(value) {
            var rec = comboStore.getById(value);

            if (rec)
            {
                return rec.get('label');
            }

            return '—';
        }
    }]
});