Search code examples
extjscomboboxextjs6-classic

Access underlaying data row on Ext.grid.Panel's column ComboBox Selection


I have an Ext.grid.Panel which shows several columns. One is a combo box with a static predefined set of selectable values.

On some data entries (columns) I want to disable the combo box. The disabling depends on another column value.

How do I do that?

More background:

After rendering column's cell data in a combo box I am not able to back reference the column's data model within the afterrender-listener.

If I am able to re-reference the data object then I can make a decision on allowing to make a selection from the combo box. Some columns (data tuples) allow selecting a different value from the combo box, others will not.

Background:

Panel's cell editing is turned on. I have one column which is a dropdown with determined values taken from the data received.

The store I am able to reference withing the afterrender method is not the store holding all the table data. It just holds the static Big-Medium-Low data of the column. But I need the store of the row; or better the correct row of data which ist stored in that more global store.

Ext.define( 'MyTable',{

  extend: 'Ext.grid.Panel',

  xtype:'myXtypeName',

  mixins: {
    field: 'Ext.form.field.Field'
  },

  plugins: [
    Ext.create('Ext.grid.plugin.CellEditing', { clicksToEdit: 1} )
  ],

  store: Ext.create( 'Ext.data.Store', {
    data: [],
    autoLoad: false,
  } ),


  columns: [
    {
        header: '#',
        dataIndex: 'id',
    },
    {
        header: 'Severity',
        dataIndex:'correctionSeverity',
        sortable: false,
        renderer: function(value, metaData, record, rowIndex, colIndex, store, view) {
            var myTable = Ext.ComponentQuery.query('myXtypeName');
            myTable[0].severityChangeable[ record.id ] = record.data.correctionType == 'Changed';
            return value;
        },

        editor: Ext.create( 'Ext.form.field.ComboBox', {

            queryMode: 'remote',

            store: Ext.create( 'Ext.data.Store', {
                fields: ['id', 'text'],
                data: [ { id:'entry0', text:'Big' },
                    { id:'entry1', text:'Medium' },
                    { id:'entry2', text:'Low' } ],
            } ),

            valueField: 'id',
            displayField: 'text',

            editable: false,
            forceSelection: true,

            listeners: {

                afterrender: function(combo, eOpts) {

                    // how to access the underlaying entry (row data) instead of just the column?
                    // by another value of the
                    var rowData = ???;

                    if ( rowData['preventColumnDropdown'] == true ) {
                        combo.disable();
                    }

                },

                change: function(combo, newValue, oldValue, eOpts) {
                    // do something
                },
            }
        }),

    }
  ],

  initComponent: function() {
    this.callParent(arguments);
    this.initField();
  },

  setValue: function(value) {
    this.store.loadData( value );
  },

});

I hope my point and problem is understandable. Please let me know if not so...

I am running ExtJS 6.0.0 classic.


Solution

  • The afterrender event is the wrong event to use, because the same combobox instance is reused for all rows. Therefore, at combobox instantiation time, the row data is not available.

    You may want to use the beforeedit event on your CellEditing plugin to modify the editor before the start of a cell edit:

    Ext.create('Ext.grid.plugin.CellEditing', { 
        clicksToEdit: 1,
        listeners: {
            beforeedit: function(editor, context, eOpts) {
                // Only if the combo column is being edited:
                if(context.column.dataIndex == "myComboDataIndex") {
                    // Disable combobox depending on:
                    editor.setDisabled(!context.record.get("AllowComboDataEdit"));
                    // or just return false to stop edit altogether:
                    // return context.record.get("AllowComboDataEdit");
                }
            }
        } 
    });