Results 1 to 9 of 9

Thread: CellEditing Plugin bug - Reconfigured Editorgrid with Grouped Header fails

  1. #1
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default CellEditing Plugin bug - Reconfigured Editorgrid with Grouped Header fails

    The grid renders perfectly, with the locked columns also. However, when I double-click on a cell to edit it, I get an error "columnHeader.getEditor is not a function".

    This is generated in the 'startEdit' function in the 'Ext.grid.plugin.CellEditing' plugin.


    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
    <head>
    <title>Test Locked EditorGrid</title>
    <meta http-equiv="Content-Type"       content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Language"   content="de" />
    
    <link rel="stylesheet" href="../../resources/css/ext-all.css" />
    <script type="text/javascript" src="../../ext-all-debug.js"></script>
    <script type="text/javascript">
      Ext.onReady(function() {
        var lockedPanel =  Ext.create('Ext.grid.Panel', {
          title: 'Locked Grid with reconfigure',
           
          autoScroll: true,
          
          renderTo: Ext.getBody(),
          
          enableLocking: true,
          
          columns: [],
          
          updateGrid: function(definition) {
            var me = this;
    
            var store = Ext.create('Ext.data.Store', {
              fields: definition.get('fields')
            });
            store.loadData(definition.get('data'));
            me.reconfigure(store, definition.get('columns'));
          },
          
          columnLines: true,
          plugins: [
            {
              ptype: 'cellediting'
            }
          ]
        });
    
        var dynamicDefinitionStore = Ext.create('Ext.data.Store', {
          fields: [
            'fields',
            'data',
            'columns'
          ],
          data: {
             fields: [
              'group',
              'type',
              'value'
            ],
            columns: [
              {
                header: 'Main Group',
                locked: true,
                columns: [
                  {
                    header: 'Group',
                    locked: true,
                    dataIndex: 'group',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  }
                ]
              },
              {
                header: 'Second Group',
                columns: [
                  {
                    header: 'Type',
                    dataIndex: 'type',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  },
                  {
                    header: 'Value',
                    dataIndex: 'value',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  }
                ]
              }
            ],
            data: [
              ['Group1', 'Type1', 'Value1'],
              ['Group1', 'Type2', 'Value2'],
              ['Group1', 'Type3', 'Value3']
            ]
          },
          listeners: {
            load: {
              fn: function(store, records, success) {
                //console.log('records', records);
                lockedPanel.updateGrid(records[0]);
              }
            }
          }
        });
      });
    </script>
    </head>
    <body></body>
    </html>

  2. #2
    Sencha - Support Team
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,410

    Default

    Move your columns to the grid

    Code:
      Ext.onReady(function() {
        var lockedPanel =  Ext.create('Ext.grid.Panel', {
          title: 'Locked Grid with reconfigure',
           
          autoScroll: true,
          
          renderTo: Ext.getBody(),
          
          enableLocking: true,
          
            columns: [
              {
                header: 'Main Group',
                locked: true,
                columns: [
                  {
                    header: 'Group',
                    locked: true,
                    dataIndex: 'group',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  }
                ]
              },
              {
                header: 'Second Group',
                columns: [
                  {
                    header: 'Type',
                    dataIndex: 'type',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  },
                  {
                    header: 'Value',
                    dataIndex: 'value',
                    editor  : {
                      xtype  : 'textfield'
                    }
                  }
                ]
              }
            ],
          
          updateGrid: function(definition) {
            var me = this;
    
            var store = Ext.create('Ext.data.Store', {
              fields: definition.get('fields')
            });
            store.loadData(definition.get('data'));
            me.reconfigure(store, definition.get('columns'));
          },
          
          columnLines: true,
          plugins: [
            {
              ptype: 'cellediting'
            }
          ]
        });
    
        var dynamicDefinitionStore = Ext.create('Ext.data.Store', {
          fields: [
            'fields',
            'data',
            'columns'
          ],
          data: {
             fields: [
              'group',
              'type',
              'value'
            ],
            data: [
              ['Group1', 'Type1', 'Value1'],
              ['Group1', 'Type2', 'Value2'],
              ['Group1', 'Type3', 'Value3']
            ]
          },
          listeners: {
            load: {
              fn: function(store, records, success) {
                //console.log('records', records);
                lockedPanel.updateGrid(records[0]);
              }
            }
          }
        });
      });?
    Scott.

  3. #3
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default

    In our scenario, the column configurations is not known in the client and is received from the server.

    Is there any other solution? Even if you can suggest me some other alternative ways to approach this it'll be a great help.

    We have been using grid reconfigure for over a year now and only now have we faced this problem because the requirement for locking columns has come in.

    Hopefully, you (or anyone else) can give some pointers!

    Thanks in advance!

  4. #4
    Sencha - Support Team
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,410

    Default

    You could send the metadata in the response:

    Example post today:
    http://www.sencha.com/forum/showthread.php?239890

    Scott.

  5. #5
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default

    Scott,

    I did what you suggested - the gird is now being reconfigured by the store's 'metachange' event.

    However, the problem still persists - I still get the following error when I try to edit a cell -
    'columnHeader.getEditor is not a function'

    My javascript is now like this -

    Code:
    Ext.define('Contact', {
      extend    : 'Ext.data.Model',
      fields    : [],
      proxy    : {
        type    : 'ajax',
        reader: {
          root             : 'value',
          successProperty  : 'success'
        }
      }
    });
    
    Ext.define('Contacts', {
      extend    : 'Ext.data.Store',
      model     : 'Contact',
      listeners  : {
        metachange: function(store, meta){
          var  grid = Ext.getCmp('maingridid');
          var model = store.getProxy().getModel();
          model.field = meta.fields;
          grid.reconfigure(store, meta.columns);
        }
      }
    }); 
    
    
    Ext.define('ContactsGrid', {
      extend      : 'Ext.grid.Panel',
      alias       : 'widget.contactsgrid',
      title      : 'Reconfigured Grid',
      width      : 700,
      height      : 500,
      store      : Ext.create('Contacts'),
      forceFit    : true,
      enableLocking  : true,
      autoScroll    : true,
      columns      : [],
      initComponent  : function(){
        this.plugins = [
          Ext.create('Ext.grid.plugin.CellEditing')
        ]
        this.callParent();
      }
    });
    
    Ext.onReady(function(){  
      var g = Ext.create('ContactsGrid', {
        id      : 'maingridid',
        renderTo  : Ext.getBody()
      });
      g.store.proxy.url = '/contacts';
      g.store.load();
    });
    The response from the server is like this -
    Code:
    {
      "value": [{
        "company": "Boeing",
        "name": "lvYsDhK6bmR",
        "id": 1
      },
      {
        "company": "IBM",
        "name": "pO0jlpyYU6A",
        "id": 100
      }],
      "metaData": {
        "fields": ["id", "name", "company"],
        "columns": [{
          "header": "Group 1",
          "columns": [{
            "header": "Id",
            "dataIndex": "id",
            "locked": true
          }],
          "locked": true
        },
        {
          "header": "Group 2",
          "columns": [{
            "editor": {
              "xtype": "textfield"
            },
            "header": "Name",
            "dataIndex": "name",
            "width": 200
          },
          {
            "editor": {
              "xtype": "textfield"
            },
            "header": "Company",
            "dataIndex": "company",
            "width": 200
          }]
        }]
      },
      "success": true
    }

  6. #6
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default My Solution

    I overrode the 'Ext.grid.plugin.CellEditing' plugin's two methods - 'startEdit' and 'getEditor'

    However, I see that the plugin had 'getEditor()' in a number of places. As of now, those lines don't seem to be getting executed.

    If there is a better solution, please advise.

    Code:
    Ext.override(Ext.grid.plugin.CellEditing, {
      startEdit: function(record, columnHeader) {
        .
        .
        .
          // if (columnHeader && !columnHeader.getEditor(record)) {
          if (columnHeader && !columnHeader.editor) {
              return false;
          }
        .
        .
      },
      getEditor: function(record, column) {
          var me = this,
              editors = me.editors,
              editorId = column.getItemId(),
              editor = editors.getByKey(editorId);
    
          if (editor) {
              return editor;
          } else {
              // editor = column.getEditor(record);
              editor = column.editor;
              if (!editor) {
                  return false;
              }
          .
          .
          .
          }
      }
    });

  7. #7
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default A Better Solution

    After some more head banging and going through 'Editing' plugin a little more in detail, I understood how the 'getEditor' and 'setEditor' functions are getting added.

    So, this override seems better than the one I posted earlier, as it adds those methods to the lowest level columns.

    Any advise, suggestions are welcome. Thanks in advance.

    Update: I notice that 'beforeedit' event doesn't fire any more.

    Any suggestions will be helpful.

    Thanks.

    Code:
    Ext.override(Ext.grid.plugin.Editing, {
      initFieldAccessors: function(columns) {
        columns = [].concat(columns);
    
        var me   = this,
          c,
          cLen = columns.length,
          column,
          childColumns,
          childcLen;
    
        for (c = 0; c < cLen; c++) {
          column = columns[c];
          
          if (column.isGroupHeader){
            childColumns = column.query('gridcolumn');
            me.initFieldAccessors(childColumns);
          }
          else{
            Ext.applyIf(column, {
              getEditor: function(record, defaultField) {
                return me.getColumnField(this, defaultField);
              },
    
              setEditor: function(field) {
                me.setColumnField(this, field);
              }
            });
          }
        }
      }
    });

  8. #8
    Sencha User
    Join Date
    Apr 2007
    Posts
    39

    Default Passing events on to Grid Panel

    After going through ExtJs code some more, especially the 'Ext.grid.Lockable' mixin, this is my understanding -
    When you set 'enableLocking: true' on a Grid Panel, the 'Ext.grid.Lockable' mixin steps in and creates two grids, one for the locked section and another for the unlocked section. Besides creating these, it also takes the plugins and features from the main grid, attaches them to each of these grids and deletes them from the original grid. It then substitutes the 'view' of the original grid with these two views in an 'hbox' layout.

    The result of this is - whenever the plugins access the grid, they are not accessing the main grid anymore. Instead they are accessing the individual grids within the main grid's 'view'.

    This is fine for most things except for the 'relayEvents' functionality. In case the plugins were set to relay events from the plugins to the main grid, now they relay those events to the individual grids only. Hence, listeners set on the main grid don't fire.

    To overcome this, I overrode the 'injectLockable' function in 'Ext.grid.Lockable' as there doesn't seem to be any other way to achieve this. Here, once the plugins for the 'locked' and 'normal' section are created, I set the relayEvents for the editing events. I'm assuming here that whatever other events need to be passed can be added here.

    Although this works, I would have preferred to put this functionality in the 'CellEditing' plugin such that the events get relayed correctly depending upon whether the grid is part of a 'LockingView' or not. I couldn't find any way to distinguish that there.

    Scott, does this seem like a right approach?

    Any suggestions are welcome.

    Code:
    Ext.override(Ext.grid.Lockable, {
      injectLockable: function() {
        .
        .
        .
        .
        lockedPlugins = me.constructPlugins();
        for (i = 0, len = lockedPlugins.length; i < len; i++){
          me.relayEvents(lockedPlugins[i], [
            'beforeedit', 'edit', 'validateedit', 'canceledit'
          ]);
        }
        
        me.clonePlugins();
        normalPlugins = me.constructPlugins();
        for (i = 0, len = normalPlugins.length; i < len; i++){
          me.relayEvents(normalPlugins[i], [
            'beforeedit', 'edit', 'validateedit', 'canceledit'
          ]);
        }
        .
        .
        .
        .
        
      }
    });

  9. #9
    Sencha User
    Join Date
    Apr 2013
    Posts
    13

    Default Need the code

    Hi,

    I am trying to reapply the editor and plugin when the Grid is reconfigured.

    Can you provide me the overrides I need to apply.

    When I say clonePlugins it shows me an error.

    Thank You
    Manish Pandit

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •