PDA

View Full Version : Multiple Group Grids in Accordion Doesn't Work



jkyoutsey
20 Nov 2012, 10:25 AM
I am dynamically creating grouping Ext.grid.Panel objects and adding them to an accordion layout. Each has a local array as the store. However, ExtJS is rendering these incorrectly. Both grids show the same groups and expanding the SECOND grid's groups does nothing except change the expand icon on the FIRST grid's corresponding group! Looking at the HTML output, I believe this is a bug in ExtJS.
Here is the first grid in the accordion. Note that it has id 1015 but its group headers have 1020:
40212

Here is the second grid. It has id 1020 and its headers do too. Now that the id's are being re-used, the grouping grids are totally broken.
40214

I have no problems if I do not group the grids. I have no problem if there is only one grouped grid.
I execute this in my accordion view's initComponent:


var store = Ext.data.StoreManager.lookup('MyStore');
store.load({
params : {
resourceId : 'bogus'
},
callback : function(records, operation, success) {
this.suspendLayout = true;
for (var i = 0; i < records.length; i++) {
var rec = store.getAt(i);
var details = rec.raw.details;
var criticals = details.filter(filterToCritical);
var warnings = details.filter(filterToWarning);
var goods = details.filter(filterToGood);
var title = "...";
var panel = new My.view.GroupedGridPanel({
title : title,
criticals : criticals,
warnings : warnings,
goods : goods,
instanceId : i
});
this.add(panel);
}
this.suspendLayout = false;
this.doLayout();
},
scope : this
});


My GroupedGridPanel is a bit more complex. It takes a combination of the "criticals", "warnings", and/or "goods" array and builds a new concatenated array and then binds that array as the store for the grid:


filterData : function() {
var state = this.getToggleState();
var data = new Array();
if (state & 1) {
data = data.concat(this.criticals);
}
if (state & 2) {
data = data.concat(this.warnings);
}
if (state & 4) {
data = data.concat(this.goods);
}


var theStore = Ext.create('Ext.data.Store', {
storeId : 'gridStore' + this.instanceId,
model : 'My.model.ScoreModel',
groupField : 'profileName',
data : data,
sorters : ['profileName', 'score']
});
theStore.sort(['profileName', 'score']);
this.store = theStore;
this.reconfigure(theStore);
}

jkyoutsey
20 Nov 2012, 3:35 PM
Ok, I've been able to duplicate this in a nice simple bit of code...


<html>
<head>
<link rel="stylesheet" type="text/css" href="/extjs-4.1/resources/css/ext-all.css">
<script type="text/javascript" src="/extjs-4.1/ext-all-debug-w-comments.js"></script>
<script type="text/javascript">
Ext.define('MyDetailsModel', {
extend : 'Ext.data.Model',
fields : [{
name : 'resourceType',
type : 'string'
}, {
name : 'resourceId',
type : 'string'
}, {
name : 'resourceName',
type : 'string'
}, {
name : 'profileId',
type : 'string'
}, {
name : 'profileName',
type : 'string'
}, {
name : 'score',
type : 'int'
}, {
name : 'resourceTypeCount',
type : 'int'
}]
});


Ext.create('Ext.data.Store', {
storeId : 'MyDetailsStore',
model : 'MyDetailsModel',
groupField : 'profileName',
proxy : {
type : 'memory',
reader : {
type : 'json',
root : 'details'
}
},
data : {
details : [{
resourceType : "TypeA",
resourceId : "0",
resourceName : "typeA-0",
profileId : "profile1",
profileName : "Profile 1",
score : 41
}, {
resourceType : "TypeA",
resourceId : "1",
resourceName : "typeA-1",
profileId : "profile1",
profileName : "Profile 1",
score : 31
}, {
resourceType : "TypeA",
resourceId : "2",
resourceName : "typeA-2",
profileId : "profile1",
profileName : "Profile 1",
score : 2
}, {
resourceType : "TypeA",
resourceId : "3",
resourceName : "typeA-3",
profileId : "profile1",
profileName : "Profile 1",
score : 32
}, {
resourceType : "TypeA",
resourceId : "4",
resourceName : "typeA-4",
profileId : "profile1",
profileName : "Profile 1",
score : 29
}, {
resourceType : "TypeA",
resourceId : "5",
resourceName : "typeA-5",
profileId : "profile1",
profileName : "Profile 1",
score : 16
}, {
resourceType : "TypeA",
resourceId : "6",
resourceName : "typeA-6",
profileId : "profile1",
profileName : "Profile 1",
score : 76
}, {
resourceType : "TypeA",
resourceId : "7",
resourceName : "typeA-7",
profileId : "profile1",
profileName : "Profile 1",
score : 24
}, {
resourceType : "TypeA",
resourceId : "8",
resourceName : "typeA-8",
profileId : "profile1",
profileName : "Profile 1",
score : 5
}, {
resourceType : "TypeA",
resourceId : "9",
resourceName : "typeA-9",
profileId : "profile1",
profileName : "Profile 1",
score : 44
}, {
resourceType : "TypeA",
resourceId : "10",
resourceName : "typeA-10",
profileId : "profile2",
profileName : "Profile 2",
score : 14
}, {
resourceType : "TypeA",
resourceId : "11",
resourceName : "typeA-11",
profileId : "profile2",
profileName : "Profile 2",
score : 41
}, {
resourceType : "TypeA",
resourceId : "12",
resourceName : "typeA-12",
profileId : "profile2",
profileName : "Profile 2",
score : 54
}, {
resourceType : "TypeA",
resourceId : "13",
resourceName : "typeA-13",
profileId : "profile2",
profileName : "Profile 2",
score : 78
}, {
resourceType : "TypeA",
resourceId : "14",
resourceName : "typeA-14",
profileId : "profile2",
profileName : "Profile 2",
score : 2
}, {
resourceType : "TypeA",
resourceId : "15",
resourceName : "typeA-15",
profileId : "profile2",
profileName : "Profile 2",
score : 73
}, {
resourceType : "TypeA",
resourceId : "16",
resourceName : "typeA-16",
profileId : "profile2",
profileName : "Profile 2",
score : 57
}, {
resourceType : "TypeA",
resourceId : "17",
resourceName : "typeA-17",
profileId : "profile2",
profileName : "Profile 2",
score : 40
}, {
resourceType : "TypeA",
resourceId : "18",
resourceName : "typeA-18",
profileId : "profile2",
profileName : "Profile 2",
score : 58
}, {
resourceType : "TypeA",
resourceId : "19",
resourceName : "typeA-19",
profileId : "profile2",
profileName : "Profile 2",
score : 48
}, {
resourceType : "TypeA",
resourceId : "20",
resourceName : "typeA-20",
profileId : "profile3",
profileName : "Profile 3",
score : 7
}, {
resourceType : "TypeA",
resourceId : "21",
resourceName : "typeA-21",
profileId : "profile3",
profileName : "Profile 3",
score : 2
}, {
resourceType : "TypeA",
resourceId : "22",
resourceName : "typeA-22",
profileId : "profile3",
profileName : "Profile 3",
score : 27
}, {
resourceType : "TypeA",
resourceId : "23",
resourceName : "typeA-23",
profileId : "profile3",
profileName : "Profile 3",
score : 69
}, {
resourceType : "TypeA",
resourceId : "24",
resourceName : "typeA-24",
profileId : "profile3",
profileName : "Profile 3",
score : 64
}, {
resourceType : "TypeA",
resourceId : "25",
resourceName : "typeA-25",
profileId : "profile3",
profileName : "Profile 3",
score : 7
}, {
resourceType : "TypeA",
resourceId : "26",
resourceName : "typeA-26",
profileId : "profile3",
profileName : "Profile 3",
score : 48
}, {
resourceType : "TypeA",
resourceId : "27",
resourceName : "typeA-27",
profileId : "profile3",
profileName : "Profile 3",
score : 99
}, {
resourceType : "TypeA",
resourceId : "28",
resourceName : "typeA-28",
profileId : "profile3",
profileName : "Profile 3",
score : 84
}, {
resourceType : "TypeA",
resourceId : "29",
resourceName : "typeA-29",
profileId : "profile3",
profileName : "Profile 3",
score : 87
}, {
resourceType : "TypeA",
resourceId : "30",
resourceName : "typeA-30",
profileId : "profile4",
profileName : "Profile 4",
score : 84
}, {
resourceType : "TypeA",
resourceId : "31",
resourceName : "typeA-31",
profileId : "profile4",
profileName : "Profile 4",
score : 47
}, {
resourceType : "TypeA",
resourceId : "32",
resourceName : "typeA-32",
profileId : "profile4",
profileName : "Profile 4",
score : 85
}, {
resourceType : "TypeA",
resourceId : "33",
resourceName : "typeA-33",
profileId : "profile4",
profileName : "Profile 4",
score : 91
}, {
resourceType : "TypeA",
resourceId : "34",
resourceName : "typeA-34",
profileId : "profile4",
profileName : "Profile 4",
score : 46
}, {
resourceType : "TypeA",
resourceId : "35",
resourceName : "typeA-35",
profileId : "profile4",
profileName : "Profile 4",
score : 79
}, {
resourceType : "TypeA",
resourceId : "36",
resourceName : "typeA-36",
profileId : "profile4",
profileName : "Profile 4",
score : 5
}, {
resourceType : "TypeA",
resourceId : "37",
resourceName : "typeA-37",
profileId : "profile4",
profileName : "Profile 4",
score : 42
}, {
resourceType : "TypeA",
resourceId : "38",
resourceName : "typeA-38",
profileId : "profile4",
profileName : "Profile 4",
score : 59
}, {
resourceType : "TypeA",
resourceId : "39",
resourceName : "typeA-39",
profileId : "profile4",
profileName : "Profile 4",
score : 13
}, {
resourceType : "TypeA",
resourceId : "40",
resourceName : "typeA-40",
profileId : "profile5",
profileName : "Profile 5",
score : 73
}, {
resourceType : "TypeA",
resourceId : "41",
resourceName : "typeA-41",
profileId : "profile5",
profileName : "Profile 5",
score : 25
}, {
resourceType : "TypeA",
resourceId : "42",
resourceName : "typeA-42",
profileId : "profile5",
profileName : "Profile 5",
score : 2
}, {
resourceType : "TypeA",
resourceId : "43",
resourceName : "typeA-43",
profileId : "profile5",
profileName : "Profile 5",
score : 94
}, {
resourceType : "TypeA",
resourceId : "44",
resourceName : "typeA-44",
profileId : "profile5",
profileName : "Profile 5",
score : 66
}, {
resourceType : "TypeA",
resourceId : "45",
resourceName : "typeA-45",
profileId : "profile5",
profileName : "Profile 5",
score : 17
}, {
resourceType : "TypeA",
resourceId : "46",
resourceName : "typeA-46",
profileId : "profile5",
profileName : "Profile 5",
score : 48
}, {
resourceType : "TypeA",
resourceId : "47",
resourceName : "typeA-47",
profileId : "profile5",
profileName : "Profile 5",
score : 79
}, {
resourceType : "TypeA",
resourceId : "48",
resourceName : "typeA-48",
profileId : "profile5",
profileName : "Profile 5",
score : 8
}, {
resourceType : "TypeA",
resourceId : "49",
resourceName : "typeA-49",
profileId : "profile5",
profileName : "Profile 5",
score : 50
}, {
resourceType : "TypeB",
resourceId : "0",
resourceName : "typeB-0",
profileId : "profile1",
profileName : "Profile 1",
score : 37
}, {
resourceType : "TypeB",
resourceId : "5000",
resourceName : "typeB-1",
profileId : "profile1",
profileName : "Profile 1",
score : 42
}, {
resourceType : "TypeB",
resourceId : "10000",
resourceName : "typeB-2",
profileId : "profile2",
profileName : "Profile 2",
score : 97
}, {
resourceType : "TypeB",
resourceId : "15000",
resourceName : "typeB-3",
profileId : "profile2",
profileName : "Profile 2",
score : 43
}, {
resourceType : "TypeB",
resourceId : "20000",
resourceName : "typeB-4",
profileId : "profile3",
profileName : "Profile 3",
score : 95
}]
}
});


Ext.define('GridPanel', {
extend : 'Ext.grid.Panel',
alias : 'widget.GridPanel',
features : Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl : Ext.create('Ext.XTemplate', '{name} ({children.length})'),
startCollapsed : true
}),
columns : [{
header : 'Object Name',
dataIndex : 'resourceName',
flex : 1
}, {
header : 'Score',
dataIndex : 'score',
width : 125
}]
});


function deepCloneStore(source) {
var target = Ext.create('Ext.data.Store', {
model : source.model
});


Ext.each(source.getRange(), function(record) {
var newRecordData = Ext.clone(record.copy().data);
var model = new source.model(newRecordData, newRecordData.id);
target.add(model);
});


return target;
}


function getDistinctTypes(store) {
var types = new Array();
for (var i = 0; i < store.data.length; i++) {
var type = store.getAt(i).get('resourceType');
var exists = false;
for (var j = 0; j < types.length; j++) {
if (types[j] == type) {
exists = true;
break;
}
}


if (!exists) {
types.push(type);
}
}
return types;
}


function getPanelsForTypes(store, types) {
var panels = new Array();
for (var i = 0; i < types.length; i++) {
store.clearFilter();
store.filterBy(function(record, id, scope) {
return record.get('resourceType') == types[i];
});
var newStore = deepCloneStore(store);
console.log(types[i] + "(" + newStore.data.length + ")");
newStore.group('profileName');
panels.push(new GridPanel({
title : types[i],
store : newStore
}));
}
return panels;
}


Ext.onReady(function() {
var store = Ext.data.StoreManager.lookup('MyDetailsStore');
var types = getDistinctTypes(store);
var panels = getPanelsForTypes(store, types);


Ext.create('Ext.panel.Panel', {
layout : {
type : 'accordion',
multi : true
},
items : panels,
renderTo : Ext.getBody()
});
});
</script>
</head>
<body>
</body>
</html>

kevin.chen
20 Nov 2012, 4:25 PM
You should not use the same store for multiple grid. that cause the problem

jkyoutsey
20 Nov 2012, 4:32 PM
If you look at my code sample, I'm CLONING the records, not using the same store.
And if you comment out the group() command everything works fine.
The problem is with grouping in an accordian layout.

kevin.chen
20 Nov 2012, 6:38 PM
Sorry, I saw you call deepCloneStore, I did not look into the method,

Can you please try following configuration for your grid definition




features: [{
ftype: 'grouping',
groupHeaderTpl : Ext.create('Ext.XTemplate', '{name} ({children.length})'),
startCollapsed : true
}],

jkyoutsey
21 Nov 2012, 6:56 AM
Thanks, Kevin! That fixed it!