Hi Forum,

I am using the MaximGB treegrid for a 2 level list of records, with rowexpander. The grid data and column configuration is fed through the Metagrid Json plugin. The code for moving the record works, and i had it made for another grid type and I'm trying to use it here. Obviously the guy who made it, can't help me any further or I wouldn't be here. I've hit a wall on moving the record visually from one place to another in 'OnSetRelation':
Code:
_this.rootGrid.detailGrids is undefined
When moved into a, not yet loaded 'leaf node' there's no problem. But when the leaf Node is loaded i'd like to show in that collection.
This is my grid:
Code:
Ext.ux.ClustersGrid = Ext.extend(Ext.ux.maximgb.tg.GridPanel, {
  initComponent: function() {
    var filters = new Ext.ux.grid.GridFilters({
      //autoReload: false,
      local: false,
      autoReload: true
    });
    var store = new Ext.ux.maximgb.tg.AdjacencyListStore({
      url: extVar['gridUri'],
      remoteSort: true,
      reader: new Ext.data.JsonReader()
    });    
    //var expander = config.getExpander();
    var gridPlugins = [
    {
      ptype: 'ux-grid-metagrid',
      maskEmpty: false,
      paging: {
        perPage: 100000
      }
    } ,
    filters,
    new Ext.ux.AjaxRowExpander({
      ptype: 'ajax-row-expander',
      //it is used as a marker now
      previewUrl: extVar['gridRowDetail'],
      idProperty: 'idea_key'
    }),
    {
      ptype:'idea-relation-popup',
      rootGrid: this,
      uncategorized: true
    }]
    Ext.apply(this, {
      store: store,
      stripeRows: true,
      height: 500, //document.body.clientHeight - 172,
      plugins: gridPlugins,
      loadMask: true,
      maskEmpty: false,
      viewConfig: {
        emptyText: L('gridEmptyText')
      },
      bbar: new Ext.Toolbar()
    });
    Ext.ux.ClustersGrid.superclass.initComponent.apply(this, arguments);
    this.addEvents('dataloaded');
    this.store.proxy.on('load', function(proxy, options) {
      this.fireEvent('dataloaded', options.reader.jsonData);
    }, this);
    var grid = this;
    this.on('reconfigure', function() {
      delete store.lastOptions.params.reconfigure;
      //notifying about hidden columns
      grid.getColumnModel().on('hiddenchange', function() {
        var cm = grid.getColumnModel();
        var hidden = cm.columns.filter(function(x) {
          return x.hidden;
        }).map(function(x) {
          return x.id;
        });
        Ext.Ajax.request({
          url: extVar['columnUri'],
          method: 'POST',
          params: {
            names: Ext.encode(hidden)
          }
        });
      });
    });
    
    var gridColumnMenu = new Ext.menu.Menu({
      id: grid.id + '-hcols-menu',
      enableScrolling: false,
      items: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
    });
    var gridView = grid.getView();
    var beforeColMenuShow = function() {
      var colModel = gridView.cm,
      colCount = colModel.getColumnCount(),
      colMenu = gridColumnMenu,
      i;
      colMenu.removeAll();
      for (i = 0; i < colCount; i++) {
        if (colModel.config[i].hideable !== false) {
          colMenu.add(new Ext.menu.CheckItem({
            text: colModel.getColumnHeader(i),
            itemId: 'col-' + colModel.getColumnId(i),
            checked: !colModel.isHidden(i),
            disabled: colModel.config[i].hideable === false,
            hideOnClick: false
          }));
        }
      }
    };
    var handleHdMenuClick = function(item) {
      var colModel = gridView.cm,
      itemId = item.getItemId(),
      index = colModel.getIndexById(itemId.substr(4));
      if (index != -1) {
        if (item.checked && colModel.getColumnsBy(gridView.isHideableColumn, this).length <= 1) {
          gridView.onDenyColumnHide();
          return;
        }
        colModel.setHidden(index, item.checked);
      }
    };
    gridColumnMenu.on({
      beforeshow: beforeColMenuShow,
      itemclick: handleHdMenuClick
    });
    //this.store.on('load', this.autoSizeColumns, this);
    grid.on('afterrender', function() {
      grid.getBottomToolbar().add(['->',
      {
        itemId: 'columns',
        hideOnClick: false,
        text: gridView.columnsText,
        menu: gridColumnMenu,
        showMenu: function() {
          if (this.menuHackApplied) Ext.Button.prototype.showMenu.apply(this, arguments);
          else {
            this.menuHackApplied = true;
            Ext.Button.prototype.showMenu.apply(this, arguments);
            Ext.Button.prototype.hideMenu.apply(this, arguments);
            Ext.Button.prototype.showMenu.apply(this, arguments);
          }
        },
        iconCls: 'x-cols-icon'
      },
      {
        iconCls: 'excelIcon',
        text: L('excelExport'),
        tip: L('excelExportTip'),
        handler: function() {
          var params = grid.store.baseParams;
          location.replace(Ext.urlAppend(extVar['gridExcelUri'], Ext.urlEncode(params)));
        }
      },
      {
        text: L('removeFilters'),
        iconCls: 'removeFilters',
        handler: function() {
          grid.filters.clearFilters();
        }
      }
      ]);
    });
  },
  setFilterParam: function(key, value) {
    this.store.baseParams[key] = value;
    //switch to the first page
    var store = this.store;
    var start = store.paramNames.start;
    if (store.lastOptions && store.lastOptions.params && store.lastOptions.params[start]) {
      store.lastOptions.params[start] = 0;
    }
    this.store.reload();
  }
}); //grid class definition
And this is the plugin that does the moving. It creates a relation to another record, thus moving it into it's children.
Code:
Ext.ux.IdeaRelationPopupPlugin = function(config) {
  Ext.apply(this, config);
};
Ext.extend(Ext.ux.IdeaRelationPopupPlugin, Ext.util.Observable, {
  init: function(grid) {
    this.grid = grid;
    grid.on('rowcontextmenu', this.onRowContextMenu, this);
  },
  onRowContextMenu: function(grid, rowNumber, e) {
    var _this = this;
    e.preventDefault();
    e.stopEvent();
    var record = grid.store.getAt(rowNumber);
    if (record.get('is_cluster') == 'Cluster') {
      return;
    }
    Ext.Ajax.request({
      url: extVar['getClusterRelations'] + '/' + record.get('idea_key'),
      success: function(response) {
        result = Ext.decode(response.responseText);
        var menu = new Ext.menu.Menu({
          enableScrolling: false,
          items: result.map(function(x) {
            return new Ext.menu.CheckItem({
              text: x.title,
              idea_key: x.idea_key,
              checked: x.checked,
              hideOnClick: false,
              listeners: {
                beforecheckchange: function(x, state) {
                  return state;
                },
                checkchange: function() {
                  _this.onSetRelation(record,record.get('idea_key'), x.idea_key);
                }
              }
            });
          })
        });
        menu.showAt(e.getXY());
      }
    });
  },
  onSetRelation: function(record,idea, cluster) {
		var _this = this;
    Ext.Ajax.request({
      url: extVar['createClusterRelation'] + '/key/' + idea + '/target/' + cluster,
      success: function() {
				if (_this.uncategorized){
					_this.rootGrid.store.remove(record);
				}
				var detailGrid = _this.rootGrid.detailGrids[cluster];
				if (detailGrid){
					detailGrid.store.loadData([record.json], true);
				}
			}
    });
  }
});
Ext.preg('idea-relation-popup', Ext.ux.IdeaRelationPopupPlugin);