PDA

View Full Version : [FIXED]RowExpander bug in getting gridview



mitchellsimoens
5 Mar 2011, 2:35 PM
The RowExpander is a great plugin. However I am getting inconsistant results.

The example for it works perfectly. However, I have created a Viewport with a center region of a GridPanel. I created my own class based on the GridPanel and specify the plugin as a config option, however I get errors. This code:


Ext.define("App.views.CenterRegion", {
extend: "Ext.grid.GridPanel",
alias : "widget.centerregion",

region : "center",
frame : true,
store : Ext.grid.CompanyStore,
headers: [
new Ext.grid.RowNumberer(),
{text: "Company", flex: 1, dataIndex: "company"},
{text: "Price", renderer: Ext.util.Format.usMoney, dataIndex: "price"},
{text: "Change", dataIndex: "change"},
{text: "% Change", dataIndex: "pctChange"},
{text: "Last Updated", renderer: Ext.util.Format.dateRenderer("m/d/Y"), dataIndex: "lastChange"}
],
plugins: [{
ptype: "rowexpander",
rowBodyTpl : [
"<p><b>Company:</b> {company}</p><br>",
"<p><b>Summary:</b> {desc}</p>"
]
}]
});

results in this error:


Uncaught TypeError: Cannot call method 'getEl' of null
RowExpander.js line 103

so I made this change:


onGridAfterLayout: function() {
var view = this.getCmp(),
viewEl = view.getEl();

if (this.expandOnEnter) {
this.keyNav = new Ext.KeyNav(viewEl, {
'enter' : this.onEnter,
scope: this
});
}
if (this.expandOnDblClick) {
view.on('dblclick', this.onDblClick, this);
}
viewEl.on('click', this.onMouseDown, this, {delegate: '.x-grid-row-expander'});
this.view = view;
},
toggleRow: function(rowIdx) {
var view = this.view.down("gridview"),
rowNode = view.getNode(rowIdx),
row = Ext.get(rowNode),
nextBd = Ext.get(row).down(this.rowBodyTrSelector),
record = view.getRecord(rowNode);

if (row.hasCls(this.rowCollapsedCls)) {
row.removeCls(this.rowCollapsedCls);
nextBd.removeCls(this.rowBodyHiddenCls);
this.recordsExpanded[record.internalId] = true;
this.view.fireEvent('expandbody');
} else {
row.addCls(this.rowCollapsedCls);
nextBd.addCls(this.rowBodyHiddenCls);
this.recordsExpanded[record.internalId] = false;
this.view.fireEvent('collapsebody');
}
view.up('gridpanel').invalidateScroller();
},

And now it works without errors. But why? this.getCmp() is different if you use an extended component versus just using the GridPanel by itself.

So I tried specifying the plugin in initComponent and got this error:


Uncaught TypeError: Object #<Object> has no method 'init'

using this code:


initComponent: function() {
this.plugins = [{
ptype: "rowexpander",
rowBodyTpl : [
"<p><b>Company:</b> {company}</p><br>",
"<p><b>Summary:</b> {desc}</p>"
]
}];
this.callParent(arguments);
},

I could be using this.callParent wrong. Tried the constructor:


constructor: function() {
this.plugins = [{
ptype: "rowexpander",
rowBodyTpl : [
"<p><b>Company:</b> {company}</p><br>",
"<p><b>Summary:</b> {desc}</p>"
]
}];

this.callParent(arguments);
},

And we are back to working but with my changes to RowExpander.js

steffenk
5 Mar 2011, 2:47 PM
One big disadvantage of rowexpander is losing the info after redraw the grid, eg after sorting records.

mitchellsimoens
5 Mar 2011, 2:50 PM
It's still open but the CSS is wrong.

steffenk
5 Mar 2011, 3:02 PM
ah - didn't noticed that. Do you have ever fixed that?

mitchellsimoens
5 Mar 2011, 3:05 PM
http://24.media.tumblr.com/tumblr_lg985fHtqs1qzc2rao1_500.jpg


:D Will have to look into that one.

steffenk
5 Mar 2011, 3:08 PM
:D - reminds me to the film i just finished looking: Clear and Present Danger

mitchellsimoens
5 Mar 2011, 3:13 PM
So I think it has to do with selecting.

Steps to reproduce your bug...


Expand a row. Looks good.
Click a header to sort.
Find row. It is still expanded but back to white.
Looks like it isn't selected anymore so try to select the expanded row. Still nothing.
Select a different row, that row gets selected.
Now you can select the previously expanded row and things are back to being fine for that row.

steffenk
5 Mar 2011, 3:16 PM
thanks, will check that.

evant
6 Mar 2011, 8:37 PM
For the initial issue:

Can't confirm this, with both PR3 and the latest source build. Using this code:



Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', '../ux');

Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.ux.RowExpander',
'Ext.container.*'
]);

Ext.define("App.views.CenterRegion", {
extend: "Ext.grid.GridPanel",
alias : "widget.centerregion",
region : "center",
headers: [
{text: "Company", flex: 1, dataIndex: "company"},
{text: "Price", renderer: Ext.util.Format.usMoney, dataIndex: "price"},
{text: "Change", dataIndex: "change"},
{text: "% Change", dataIndex: "pctChange"},
{text: "Last Updated", renderer: Ext.util.Format.dateRenderer("m/d/Y"), dataIndex: "lastChange"}
],
plugins: [{
ptype: "rowexpander",
rowBodyTpl : [
"<p><b>Company:</b> {company}</p><br>",
"<p><b>Summary:</b> {desc}</p>"
]
}]
});

Ext.onReady(function(){
Ext.regModel('Company', {
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'industry'},
{name: 'desc'}
]
});
// Array data for the grids
Ext.grid.dummyData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am', 'Manufacturing'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am', 'Manufacturing'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am', 'Manufacturing'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am', 'Finance'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am', 'Services'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am', 'Services'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am', 'Manufacturing'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am', 'Services'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am', 'Finance'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am', 'Manufacturing'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am', 'Manufacturing'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am', 'Manufacturing'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am', 'Automotive'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am', 'Computer'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am', 'Manufacturing'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am', 'Computer'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am', 'Computer'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am', 'Medical'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am', 'Finance'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am', 'Food'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am', 'Medical'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am', 'Computer'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am', 'Services', 'Medical'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am', 'Food'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am', 'Retail'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am', 'Manufacturing'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am', 'Computer'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am', 'Services'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am', 'Retail'],
['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am', 'Services']
];

// add in some dummy descriptions
for(var i = 0; i < Ext.grid.dummyData.length; i++){
Ext.grid.dummyData[i].push('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. ');
}


Ext.QuickTips.init();

var getLocalStore = function() {
return new Ext.data.ArrayStore({
model: 'Company',
data: Ext.grid.dummyData
});
};

new Ext.container.Viewport({
layout: 'border',
items: {
store: getLocalStore(),
xtype: 'centerregion'
}
})
});

evant
6 Mar 2011, 8:38 PM
Can confirm the other issue, however it's independent of the RowExpander.

evant
6 Mar 2011, 9:25 PM
I've added a fix for the second issue.

steffenk
7 Mar 2011, 3:45 AM
thanks Evan!

mitchellsimoens
7 Mar 2011, 5:25 AM
Can't confirm this, with both PR3 and the latest source build.

I just tried your code and I still get the error in PR3. I uploaded to my server (http://www.simoens.org/bugs/RowExpander.html). Here is my complete index.html:


<html>
<head>
<title>Row Expander</title>
<link rel="stylesheet" type="text/css" href="/ext-4.0-pr3/resources/css/ext-all.css" />
<script type="text/javascript" src="/ext-4.0-pr3/bootstrap.js"></script>

<script type="text/javascript">

Ext.Loader.setConfig({
enabled: true
});
Ext.Loader.setPath('Ext.ux', '/ext-4.0-pr3/examples/ux');

Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.ux.RowExpander',
'Ext.container.*'
]);

Ext.define("App.views.CenterRegion", {
extend: "Ext.grid.GridPanel",
alias : "widget.centerregion",
region : "center",
headers: [
{text: "Company", flex: 1, dataIndex: "company"},
{text: "Price", renderer: Ext.util.Format.usMoney, dataIndex: "price"},
{text: "Change", dataIndex: "change"},
{text: "% Change", dataIndex: "pctChange"},
{text: "Last Updated", renderer: Ext.util.Format.dateRenderer("m/d/Y"), dataIndex: "lastChange"}
],
plugins: [{
ptype: "rowexpander",
rowBodyTpl : [
"<p><b>Company:</b> {company}</p><br>",
"<p><b>Summary:</b> {desc}</p>"
]
}]
});

Ext.onReady(function(){
Ext.regModel('Company', {
fields: [
{name: 'company'},
{name: 'price', type: 'float'},
{name: 'change', type: 'float'},
{name: 'pctChange', type: 'float'},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'},
{name: 'industry'},
{name: 'desc'}
]
});
// Array data for the grids
Ext.grid.dummyData = [
['3m Co',71.72,0.02,0.03,'9/1 12:00am', 'Manufacturing'],
['Alcoa Inc',29.01,0.42,1.47,'9/1 12:00am', 'Manufacturing'],
['Altria Group Inc',83.81,0.28,0.34,'9/1 12:00am', 'Manufacturing'],
['American Express Company',52.55,0.01,0.02,'9/1 12:00am', 'Finance'],
['American International Group, Inc.',64.13,0.31,0.49,'9/1 12:00am', 'Services'],
['AT&T Inc.',31.61,-0.48,-1.54,'9/1 12:00am', 'Services'],
['Boeing Co.',75.43,0.53,0.71,'9/1 12:00am', 'Manufacturing'],
['Caterpillar Inc.',67.27,0.92,1.39,'9/1 12:00am', 'Services'],
['Citigroup, Inc.',49.37,0.02,0.04,'9/1 12:00am', 'Finance'],
['E.I. du Pont de Nemours and Company',40.48,0.51,1.28,'9/1 12:00am', 'Manufacturing'],
['Exxon Mobil Corp',68.1,-0.43,-0.64,'9/1 12:00am', 'Manufacturing'],
['General Electric Company',34.14,-0.08,-0.23,'9/1 12:00am', 'Manufacturing'],
['General Motors Corporation',30.27,1.09,3.74,'9/1 12:00am', 'Automotive'],
['Hewlett-Packard Co.',36.53,-0.03,-0.08,'9/1 12:00am', 'Computer'],
['Honeywell Intl Inc',38.77,0.05,0.13,'9/1 12:00am', 'Manufacturing'],
['Intel Corporation',19.88,0.31,1.58,'9/1 12:00am', 'Computer'],
['International Business Machines',81.41,0.44,0.54,'9/1 12:00am', 'Computer'],
['Johnson & Johnson',64.72,0.06,0.09,'9/1 12:00am', 'Medical'],
['JP Morgan & Chase & Co',45.73,0.07,0.15,'9/1 12:00am', 'Finance'],
['McDonald\'s Corporation',36.76,0.86,2.40,'9/1 12:00am', 'Food'],
['Merck & Co., Inc.',40.96,0.41,1.01,'9/1 12:00am', 'Medical'],
['Microsoft Corporation',25.84,0.14,0.54,'9/1 12:00am', 'Computer'],
['Pfizer Inc',27.96,0.4,1.45,'9/1 12:00am', 'Services', 'Medical'],
['The Coca-Cola Company',45.07,0.26,0.58,'9/1 12:00am', 'Food'],
['The Home Depot, Inc.',34.64,0.35,1.02,'9/1 12:00am', 'Retail'],
['The Procter & Gamble Company',61.91,0.01,0.02,'9/1 12:00am', 'Manufacturing'],
['United Technologies Corporation',63.26,0.55,0.88,'9/1 12:00am', 'Computer'],
['Verizon Communications',35.57,0.39,1.11,'9/1 12:00am', 'Services'],
['Wal-Mart Stores, Inc.',45.45,0.73,1.63,'9/1 12:00am', 'Retail'],
['Walt Disney Company (The) (Holding Company)',29.89,0.24,0.81,'9/1 12:00am', 'Services']
];

// add in some dummy descriptions
for(var i = 0; i < Ext.grid.dummyData.length; i++){
Ext.grid.dummyData[i].push('Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed metus nibh, sodales a, porta at, vulputate eget, dui. Pellentesque ut nisl. ');
}


Ext.QuickTips.init();

var getLocalStore = function() {
return new Ext.data.ArrayStore({
model: 'Company',
data: Ext.grid.dummyData
});
};

new Ext.container.Viewport({
layout: 'border',
items: {
store: getLocalStore(),
xtype: 'centerregion'
}
})
});

</script>
</head>
<body>
</body>
</html>

steffenk
7 Mar 2011, 5:32 AM
in your online demo i even can't expand any row!

mitchellsimoens
7 Mar 2011, 5:38 AM
in your online demo i even can't expand any row!

Bootstrap using the debug version so it takes a while to load. Not sure if my server is just going that slow but the second time I tried to load it was working fine. That's also why I posted my entire index.html file.

steffenk
7 Mar 2011, 5:42 AM
it dosn't work even everything got loaded. With opened console i could see that. Clicking on the + it breaks here:
var rowNode = this.view.getNode(rowIdx),
where getNode is undefined.

mitchellsimoens
7 Mar 2011, 5:44 AM
Thats the bug i encounter

steffenk
7 Mar 2011, 5:57 AM
i see, so confirmed!

PV-Patrick
7 Mar 2011, 1:34 PM
I just wanted to point out that I am experiencing the same issue of the plugin.init. When testing, I did notice if I place both the headers:[{}] and plugins:[{}] inside items:[{}] it removes the .init problem. However, it then generated the following error: view is null - viewEl = view.getEl(); Line 103



//Ext JS 4.x class definition
Ext.define('MyApp.MyEmailsGridPanel', {

extend: 'Ext.grid.GridPanel',

initComponent: function() {

var store = new Ext.data.Store({
model : 'MyEmails',
autoLoad : true
});

Ext.apply(this, {
title : 'My Emails',
width : 600,
height : 300,
store : store,
renderTo: 'myemails-grid-wrap',
columnLines : true,
items : [{
headers : [{
dataIndex : 'id',
hidden : true
},{
text : 'Date Sent',
dataIndex : 'date',
width : 180,
align : 'left',
renderer : Ext.util.Format.dateRenderer('M j, Y \\a\\t g:ia \\C\\S\\T'),
},{
text : 'Email Subject',
dataIndex : 'subject',
flex : 1
}],
plugins : [{
ptype : 'rowexpander',
rowBodyTpl : [
'<p>{message}</p>'
]
}]
}]
});

this.callParent(arguments);
}
});


If I remove the encapsulating items:[{}] - the plugin.init error shows.

aconran
8 Mar 2011, 4:20 PM
This should be fixed in the next release. Please verify after the release.

DHainzl
26 May 2011, 11:27 PM
I still get the error "plugin.init is undefined" when defining the plugin in the initComponent-function ...

pwuk
1 Jun 2011, 8:26 AM
This style works for me :

var grid = Ext.create('Ext.grid.Panel', {
store: store,
columnLines: true,
collapsible: false,
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<img style=\'float:left\' src=graph.png>',
'<p style=\'padding:3px\'>{abstract}</p>',
'<a href=\'#\' class=\'timore\'>more...</a>'
]
}],


This doesn't :

Ext.define('myGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.ideaslist',

initComponent: function() {

var store = Ext.create('Ext.data.ArrayStore', {
idIndex:0,
fields: [
{name: 'id'},
{name: 'title' },
{name: 'analyst'},
{name: 'CCY'},
{name: 'cost', type: 'float'},
{name: 'PV', type: 'float'},
{name: 'PnL', type: 'float'},
{name: 'StartDate', type: 'date'},
{name: 'abastract'}

]
});

var currency = Ext.create('Ext.data.Store', {
fields: ['CCY', 'CCYName'],
data : [
{"CCY":"GBP", "CCYName":"GBP"},
{"CCY":"USD", "CCYName":"USD"},
{"CCY":"JPY", "CCYName":"JPY"},
{"CCY":"EUR", "CCYName":"EUR"}
]
});

Ext.apply(this,{
store: store,
currcency: currency,
columns: this.getColumns(),
tbar: this.getToolBar(),
columnLines: true,
collapsible: false
,plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<img style=\'float:left\' src=graph.png>',
'<p style=\'padding:3px\'>{abstract}</p>',
'<a href=\'#\' class=\'timore\'>more...</a>'
]
}]
})


},

ae.intern
12 Jan 2012, 2:30 AM
This style works for me :

var grid = Ext.create('Ext.grid.Panel', {
store: store,
columnLines: true,
collapsible: false,
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<img style=\'float:left\' src=graph.png>',
'<p style=\'padding:3px\'>{abstract}</p>',
'<a href=\'#\' class=\'timore\'>more...</a>'
]
}],


This doesn't :

Ext.define('myGrid', {
extend: 'Ext.grid.Panel',
alias: 'widget.ideaslist',

initComponent: function() {

var store = Ext.create('Ext.data.ArrayStore', {
idIndex:0,
fields: [
{name: 'id'},
{name: 'title' },
{name: 'analyst'},
{name: 'CCY'},
{name: 'cost', type: 'float'},
{name: 'PV', type: 'float'},
{name: 'PnL', type: 'float'},
{name: 'StartDate', type: 'date'},
{name: 'abastract'}

]
});

var currency = Ext.create('Ext.data.Store', {
fields: ['CCY', 'CCYName'],
data : [
{"CCY":"GBP", "CCYName":"GBP"},
{"CCY":"USD", "CCYName":"USD"},
{"CCY":"JPY", "CCYName":"JPY"},
{"CCY":"EUR", "CCYName":"EUR"}
]
});

Ext.apply(this,{
store: store,
currcency: currency,
columns: this.getColumns(),
tbar: this.getToolBar(),
columnLines: true,
collapsible: false
,plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<img style=\'float:left\' src=graph.png>',
'<p style=\'padding:3px\'>{abstract}</p>',
'<a href=\'#\' class=\'timore\'>more...</a>'
]
}]
})


},

Hi,

I have exact the same problem. Is there an bugfix for this issue?

I use version 4.0.7 from Extjs.

ae.intern
12 Jan 2012, 2:36 AM
Nervermind I've found a solution for my problem.

talha06
8 Jun 2012, 4:15 AM
By the way I'm still getting same error while using Ext JS 4.1.0 release. Bug still continues with using viewport. Hope someone can offer a certain resolve for this bug?
Thanks in advance..

Cannot call method 'addCls' of null
Cannot call method 'removeCls' of null

powellke
14 Jun 2012, 11:13 AM
Just confirmed that this issue still exists in Ext JS 4.1.1-rc2.


By the way I'm still getting same error while using Ext JS 4.1.0 release. Bug still continues with using viewport. Hope someone can offer a certain resolve for this bug?
Thanks in advance..

Cannot call method 'addCls' of null
Cannot call method 'removeCls' of null

tr1x
26 Jul 2013, 7:53 AM
problem still not fixed in 4.2.1.883. when using this plugin in Ext.define('My.custom.Grid').

with Ext.create('Ext.panel.Grid') it works

please fix it :-/

talha06
13 Aug 2013, 1:10 AM
This is me again, any news after 1 year?? I'm facing same issue with Ext JS 4.2.1 while using row expander with border layout.


By the way I'm still getting same error while using Ext JS 4.1.0 release. Bug still continues with using viewport. Hope someone can offer a certain resolve for this bug?
Thanks in advance..

Cannot call method 'addCls' of null
Cannot call method 'removeCls' of null