mialkin
mialkin

Reputation: 2791

ExtJs - Column Editor with different xtype based on record value

I have a gridpanel with rowediting plugin enabled. I was wondering if it is possible to display in the same cell either checkbox control or numberfield based on data that's being returned from server. I have not seen anything like that before and googling has not yield any results so it may be impossible at all. It looks like I have to specify different editor types not per each column but per each cell.

How can I achieve that?

P.S. I must have a chance to edit that cell, i.e. change number value or check/uncheck checkbox.

Upvotes: 0

Views: 7477

Answers (3)

Guilherme Lopes
Guilherme Lopes

Reputation: 4760

That is very easy to achieve, you will need to use the getEditor method of your grid column and get it to return the form field you want:

Example:

{
    xtype: 'gridcolumn',
    getEditor: function(record) {
        var grid = this.up('grid'),
            cellediting = grid.findPlugin('cellediting'),
            editors = cellediting.editors,
            editor = editors.getByKey(this.id),
            fieldType;

        if (editor) {
        // Do this to avoid memory leaks
            editors.remove(editor);
        }
        fieldType = isNaN(parseFloat(record.get('salary'))) ? 'textfield' : 'numberfield';

        return {
            xtype: fieldType,
            allowBlank: false
        };
    },
    dataIndex: 'salary',
    text: 'Salary',
    flex: 1
}

I have created a fiddle demonstrating the use of this method, if the column Salary holds a string it will edit with a textfield, if it holds a number, it will edit with a Numberfield.

Hope it helps

Fiddle: https://fiddle.sencha.com/#fiddle/c2m

  • My fiddle is working with the CellEditor plugin, you will have to make the adjustments to make it work with your RowEditor plugin, for further reference, check the documentation for Grid Column and the getEditor method.

Upvotes: 3

mialkin
mialkin

Reputation: 2791

Many thanks to Guilherme Lopes for the nice code to begin with. Here is the sample of what I finally got:

 var data = [{
                name: 'Richard Wallace',
                age: 24,
                hired: '9/21/2013',
                active: true,
                salary: 1,
                checkbox: true
            }, {
                name: 'Phyllis Diaz',
                age: 29,
                hired: '1/27/2009',
                active: false,
                salary: 41244,
                checkbox: false
            }, {
                name: 'Kathryn Kelley',
                age: 23,
                hired: '9/14/2011',
                active: false,
                salary: 98599.9,
                checkbox: false
            }, {
                name: 'Annie Willis',
                age: 36,
                hired: '4/11/2011',
                active: true,
                salary: 0,
                checkbox: true
            }];

            var store = Ext.create('Ext.data.Store', {
                data: data,
                fields: [{
                    name: 'name'
                }, {
                    type: 'float',
                    name: 'age'
                }, {
                    type: 'date',
                    name: 'hired'
                }, {
                    type: 'boolean',
                    name: 'active'
                }, {
                    name: 'salary'
                }]
            });

            Ext.define('MyApp.view.MyGridPanel', {
                extend: 'Ext.grid.Panel',
                alias: 'widget.mygridpanel',
                height: 315,
                width: 784,
                title: 'Employees',
                store: store,
                viewConfig: {
                    listeners: {
                        beforecellclick: function (view, cell, cellIndex, record, row, rowIndex, e) {
                            if (cellIndex == 4 && record.get('checkbox')) {
                                if (record.get('salary')) {
                                    record.set('salary', 0);
                                } else {
                                    record.set('salary', 1);
                                }
                                return false;
                            }
                            return true;
                        }
                    }
                },

                columns: [{
                    xtype: 'gridcolumn',
                    dataIndex: 'name',
                    text: 'Name',
                    flex: 1,
                    editor: {
                        xtype: 'textfield'
                    }
                }, {
                    xtype: 'gridcolumn',
                    dataIndex: 'age',
                    text: 'Age'
                }, {
                    xtype: 'datecolumn',
                    dataIndex: 'hired',
                    text: 'Hired',
                    flex: 1
                }, {
                    xtype: 'checkcolumn',
                    dataIndex: 'active',
                    text: 'Active'
                }, {
                    xtype: 'gridcolumn',
                    getEditor: function (record) {
                        var fieldType = record.get('checkbox') ? 'checkboxfield' : 'textfield';
                        return Ext.create('Ext.grid.CellEditor', {
                            field: {
                                xtype: fieldType,
                                allowBlank: false
                            }
                        });
                    },
                    renderer: function (value, metaData) {
                        if (metaData.record.get('checkbox')) {
                            if (metaData.record.get('salary')) {
                                return '<div style="text-align: center"><img class="x-grid-checkcolumn x-grid-checkcolumn-checked" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div>';

                            } else {
                                return '<div style="text-align: center"><img class="x-grid-checkcolumn" src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=="></div>';
                            }
                        }
                        return value;
                    },
                    dataIndex: 'salary',
                    text: 'Salary',
                    flex: 1
                }],
                plugins: [{
                    ptype: 'cellediting',
                    autoCancel: false,
                    clicksToEdit: 1
                }]
            });
        Ext.create('MyApp.view.MyGridPanel', {
            renderTo: Ext.getBody()
        });

Working example on Sencha's fiddle https://fiddle.sencha.com/#fiddle/c3p

Upvotes: 1

Alexander
Alexander

Reputation: 20244

Editor contains one field, and this editor is used for the whole column. You can't specify two xtypes or multiple editors for one column.

That said, it is not completely impossible, but it will require some work. You will have to define a new custom field with custom xtype. Tell this field to either render a checkboxfield or a numberfield, depending on the value.

This will require you to override/implement most if not all functions that a Ext.form.field.Base has...

Upvotes: 0

Related Questions