PDA

View Full Version : [OPEN] 4.2.0 Beta: Content from TabPanel is not shown



Michi_72
13 Dec 2012, 11:27 PM
Hello,

after changing to 4.2.0 beta the following code works no longer. The first tab is shown correctly - the second one is empty instead of all required code is loaded. There are no errors in the chrome console shown.

With 4.1.1 everything is working correctly.


Ext.Loader.setPath('Ext.ux', 'system/extjs/examples/ux/');

Ext.require([ 'Ext.ux.RowExpander' ]);

Ext.define('AM.view.system.info' ,{
extend: 'Ext.panel.Panel',
alias : 'widget.system_info',
iconCls : 'settings',
title : 'Systeminformation',
closable: true,
tools:[{
type:'help',
qtip: 'Hilfe anzeigen',
handler: function(event, toolEl, panel){ id = 1; hilfe_aufruf(id);
}
}],
initComponent: function() {

this.items = [
{
xtype: 'tabpanel',
activeTab: 0,
items: [
{
title: 'Allgemein',
items: [
{
xtype: 'system_details',
nameColumnWidth : 170,
iconCls : '',
title : ''
}
]
},
{
title: 'Update History',
items: [
{
xtype: 'gridpanel',
store: 'nav.system_update',
columns: [
{text: 'Build kalkTOOL', flex: 1, dataIndex: 'prg_version', summaryType: 'count',
summaryRenderer: function(value){
return ((value === 0 || value > 1) ? '' + value + ' Patches' : '1 Patch');
}
},
{text: 'Kategorie', dataIndex: 'prg_kategorie'},
{text: 'Datum', dataIndex: 'prg_time_real', renderer: Ext.util.Format.dateRenderer('d.m.Y H:i')},
{xtype:'actioncolumn', width: 20,
items: [{
icon: 'system/icons/page_white_acrobat.png',
handler: function(grid, rowIndex, colIndex) {
this.fireEvent('show_pdf', this, grid, rowIndex, colIndex);
}
}]
}
],
viewConfig: {
stripeRows: true,
loadingText: 'Daten werden geladen...'
},
features: [{ftype:'groupingsummary',
groupHeaderTpl: '{name}',
startCollapsed: true,
enableGroupingMenu: false
}],
plugins: [{
ptype: 'rowexpander',
rowBodyTpl : [
'<p><b>Informationen zum Patch:<br><br></b> {prg_text}</p>'
]
}]
}
]
}
]
}
];

this.callParent(arguments);
}
});

Any tip is useful!

Thanks in advance!

Michi

dongryphon
14 Dec 2012, 1:45 PM
Thanks for the report! I have opened a bug in our bug tracker.

Animal
16 Dec 2012, 7:38 AM
Why have you nested that GridPanel inside a layoutless Panel?

Please post a cleaned up version.

Animal
16 Dec 2012, 7:41 AM
Any why is your AM.view.system.info class a layoutless Panel which contains a TabPanel?

Whyt is it not just a TabPanel?

Animal
16 Dec 2012, 7:49 AM
Drop this completely unchanged into your SDK examples/<anywhere> directory.

It will run without you having to untangle it.

It has a grid as the second tab.

It works.



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Stateful Array Grid Example</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="../shared/example.css" />

<!-- GC -->

<script type="text/javascript" src="../../ext-all.js"></script>

<!-- page specific -->
<style type="text/css">
/* style rows on mouseover */
.x-grid-row-over .x-grid-cell-inner {
font-weight: bold;
}
/* shared styles for the ActionColumn icons */
.x-action-col-cell img {
height: 16px;
width: 16px;
cursor: pointer;
}
/* custom icon for the "buy" ActionColumn icon */
.x-action-col-cell img.buy-col {
background-image: url(../shared/icons/fam/accept.png);
}
/* custom icon for the "alert" ActionColumn icon */
.x-action-col-cell img.alert-col {
background-image: url(../shared/icons/fam/error.png);
}

.x-ie6 .x-action-col-cell img.buy-col {
background-image: url(../shared/icons/fam/accept.gif);
}
.x-ie6.x-action-col-cell img.alert-col {
background-image: url(../shared/icons/fam/error.gif);
}

.x-ie6 .x-action-col-cell img {
position:relative;
top:-1px;
}
</style>
<script type="text/javascript">
Ext.require([
'*'
]);

// Define Company entity
// Null out built in convert functions for performance *because the raw data is known to be valid*
// Specifying defaultValue as undefined will also save code. *As long as there will always be values in the data, or the app tolerates undefined field values*
Ext.define('Company', {
extend: 'Ext.data.Model',
fields: [
{name: 'company'},
{name: 'price', type: 'float', convert: null, defaultValue: undefined},
{name: 'change', type: 'float', convert: null, defaultValue: undefined},
{name: 'pctChange', type: 'float', convert: null, defaultValue: undefined},
{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia', defaultValue: undefined}
],
idProperty: 'company'
});

Ext.onReady(function() {
Ext.QuickTips.init();

// setup the state provider, all state information will be saved to a cookie
Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));

// sample static data for the store
var myData = [
['3m Co', 71.72, 0.02, 0.03, '9/1 12:00am'],
['Alcoa Inc', 29.01, 0.42, 1.47, '9/1 12:00am'],
['Altria Group Inc', 83.81, 0.28, 0.34, '9/1 12:00am'],
['American Express Company', 52.55, 0.01, 0.02, '9/1 12:00am'],
['American International Group, Inc.', 64.13, 0.31, 0.49, '9/1 12:00am'],
['AT&T Inc.', 31.61, -0.48, -1.54, '9/1 12:00am'],
['Boeing Co.', 75.43, 0.53, 0.71, '9/1 12:00am'],
['Caterpillar Inc.', 67.27, 0.92, 1.39, '9/1 12:00am'],
['Citigroup, Inc.', 49.37, 0.02, 0.04, '9/1 12:00am'],
['E.I. du Pont de Nemours and Company', 40.48, 0.51, 1.28, '9/1 12:00am'],
['Exxon Mobil Corp', 68.1, -0.43, -0.64, '9/1 12:00am'],
['General Electric Company', 34.14, -0.08, -0.23, '9/1 12:00am'],
['General Motors Corporation', 30.27, 1.09, 3.74, '9/1 12:00am'],
['Hewlett-Packard Co.', 36.53, -0.03, -0.08, '9/1 12:00am'],
['Honeywell Intl Inc', 38.77, 0.05, 0.13, '9/1 12:00am'],
['Intel Corporation', 19.88, 0.31, 1.58, '9/1 12:00am'],
['International Business Machines', 81.41, 0.44, 0.54, '9/1 12:00am'],
['Johnson & Johnson', 64.72, 0.06, 0.09, '9/1 12:00am'],
['JP Morgan & Chase & Co', 45.73, 0.07, 0.15, '9/1 12:00am'],
['McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am'],
['Merck & Co., Inc.', 40.96, 0.41, 1.01, '9/1 12:00am'],
['Microsoft Corporation', 25.84, 0.14, 0.54, '9/1 12:00am'],
['Pfizer Inc', 27.96, 0.4, 1.45, '9/1 12:00am'],
['The Coca-Cola Company', 45.07, 0.26, 0.58, '9/1 12:00am'],
['The Home Depot, Inc.', 34.64, 0.35, 1.02, '9/1 12:00am'],
['The Procter & Gamble Company', 61.91, 0.01, 0.02, '9/1 12:00am'],
['United Technologies Corporation', 63.26, 0.55, 0.88, '9/1 12:00am'],
['Verizon Communications', 35.57, 0.39, 1.11, '9/1 12:00am'],
['Wal-Mart Stores, Inc.', 45.45, 0.73, 1.63, '9/1 12:00am']
];

/**
* Custom function used for column renderer
* @param {Object} val
*/
function change(val) {
if (val > 0) {
return '<span style="color:green;">' + val + '</span>';
} else if (val < 0) {
return '<span style="color:red;">' + val + '</span>';
}
return val;
}

/**
* Custom function used for column renderer
* @param {Object} val
*/
function pctChange(val) {
if (val > 0) {
return '<span style="color:green;">' + val + '%</span>';
} else if (val < 0) {
return '<span style="color:red;">' + val + '%</span>';
}
return val;
}

// create the data store
var store = Ext.create('Ext.data.ArrayStore', {
model: 'Company',
data: myData
});

// create the Grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
collapsible: true,
multiSelect: true,
columns: [
{
text : 'Company',
flex : 1,
sortable : false,
dataIndex: 'company'
},
{
text : 'Price',
width : 75,
sortable : true,
renderer : 'usMoney',
dataIndex: 'price'
},
{
text : 'Change',
width : 75,
sortable : true,
renderer : change,
dataIndex: 'change'
},
{
text : '% Change',
width : 75,
sortable : true,
renderer : pctChange,
dataIndex: 'pctChange'
},
{
text : 'Last Updated',
width : 85,
sortable : true,
renderer : Ext.util.Format.dateRenderer('m/d/Y'),
dataIndex: 'lastChange'
},
{
menuDisabled: true,
sortable: false,
xtype: 'actioncolumn',
width: 50,
items: [{
icon : '../shared/icons/fam/delete.gif', // Use a URL in the icon config
tooltip: 'Sell stock',
handler: function(grid, rowIndex, colIndex) {
var rec = store.getAt(rowIndex);
alert("Sell " + rec.get('company'));
}
}, {
getClass: function(v, meta, rec) { // Or return a class from a function
if (rec.get('change') < 0) {
return 'alert-col';
} else {
return 'buy-col';
}
},
getTip: function(v, meta, rec) {
if (rec.get('change') < 0) {
return 'Hold stock';
} else {
return 'Buy stock';
}
},
handler: function(grid, rowIndex, colIndex) {
var rec = store.getAt(rowIndex);
alert((rec.get('change') < 0 ? "Hold " : "Buy ") + rec.get('company'));
}
}]
}
],

title: 'Array Grid',
viewConfig: {
stripeRows: true,
enableTextSelection: true
}
});

new Ext.tab.Panel({
height: 400,
width: 600,
activeTab: 0,
items: [{
title: 'Tab 1'
}, grid],
renderTo: document.body
})
});
</script>
</head>
<body style="padding:10px"></body>
</html>

Michi_72
16 Dec 2012, 12:13 PM
Hello Animal,

i have changed the code and removed the useless panel - the code looks like:



Ext.Loader.setPath('Ext.ux', 'system/extjs/examples/ux/');

Ext.require([ 'Ext.ux.RowExpander' ]);

Ext.define('AM.view.system.info' ,{
extend: 'Ext.tab.Panel',
alias : 'widget.system_info',
iconCls : 'settings',
title : 'Systeminformation',
activeTab: 0,
closable: true,
tools:[{
type:'help',
qtip: 'Hilfe anzeigen',
handler: function(event, toolEl, panel){ id = 1; hilfe_aufruf(id);
}
}],
initComponent: function() {

this.items = [
{
title : 'Allgemein',
items : [
{
xtype : 'system_details',
nameColumnWidth : 170,
iconCls : '',
title : ''
}
]
},
{
title : 'Update History',
items : [
{
xtype : 'gridpanel',
store : 'nav.system_update',
columns : [
{
text : 'Build kalkTOOL',
flex : 1,
dataIndex : 'prg_version',
summaryType : 'count',
summaryRenderer : function(value) {
return ((value === 0 || value > 1) ? '' + value + ' Patches' : '1 Patch');
}
},
{
text : 'Kategorie',
dataIndex : 'prg_kategorie'
},
{
text : 'Datum',
dataIndex : 'prg_time_real',
renderer : Ext.util.Format.dateRenderer('d.m.Y H:i')
},
{
xtype : 'actioncolumn',
width : 20,
items : [
{
icon : 'system/icons/page_white_acrobat.png',
handler : function(grid, rowIndex, colIndex) {
this.fireEvent('show_pdf', this, grid, rowIndex, colIndex);
}
}
]
}
],
viewConfig :
{
stripeRows : true,
loadingText : 'Daten werden geladen...'
},
features : [
{
ftype : 'groupingsummary',
groupHeaderTpl : '{name}',
startCollapsed : true,
enableGroupingMenu : false
}
],
plugins : [
{
ptype : 'rowexpander',
rowBodyTpl : ['<p><b>Informationen zum Patch:<br><br></b> {prg_text}</p>'
]
}
]
}
]
}
];

this.callParent(arguments);
}
});


I have tried your example and it is working to me.

Instead of removing nothing changed and the second tab isn't shown correctly! Do not know what the diffenrece is to your working example.

Is the my problem caused using mvc?

Thanks!

Animal
17 Dec 2012, 1:49 AM
Instead of a Panel with no layout (WILL NOT LAY OUT ITS CHILD COMPONENT) with title "Update History" as the second tab, just configure the grid with title "Update History" and use that as the second item.

As you saw in the example I posted, and every example of a TabPanel in documentation and example code.

Why did you add that extra, layoutless layer?

Michi_72
17 Dec 2012, 4:07 AM
Hello Animal,

i have changed the code to this and i removed all unneccessary panels (i hope so):



Ext.Loader.setPath('Ext.ux', 'system/extjs/examples/ux/');

Ext.require([ 'Ext.ux.RowExpander' ]);

Ext.define('AM.view.system.info' ,{
extend: 'Ext.tab.Panel',
alias : 'widget.system_info',
iconCls : 'settings',
layout: 'fit',
title : 'Systeminformation',
activeTab: 0,
closable: true,
tools:[{
type:'help',
qtip: 'Hilfe anzeigen',
handler: function(event, toolEl, panel){ id = 1; hilfe_aufruf(id);
}
}],
initComponent: function() {

this.items = [

{
xtype : 'system_details',
title : 'Allgemein',
nameColumnWidth : 170,
iconCls : ''
},
{

xtype : 'gridpanel',
title : 'Updateverlauf',
store : 'nav.system_update',
columns : [
{
text : 'Build kalkTOOL',
flex : 1,
dataIndex : 'prg_version',
summaryType : 'count',
summaryRenderer : function(value) {
return ((value === 0 || value > 1) ? '' + value + ' Patches' : '1 Patch');
}
},
{
text : 'Kategorie',
dataIndex : 'prg_kategorie'
},
{
text : 'Datum',
dataIndex : 'prg_time_real',
renderer : Ext.util.Format.dateRenderer('d.m.Y H:i')
},
{
xtype : 'actioncolumn',
width : 20,
items : [
{
icon : 'system/icons/page_white_acrobat.png',
handler : function(grid, rowIndex, colIndex) {
this.fireEvent('show_pdf', this, grid, rowIndex, colIndex);
}
}
]
}
],
viewConfig :
{
stripeRows : true,
loadingText : 'Daten werden geladen...'
},
features : [
{
ftype : 'groupingsummary',
groupHeaderTpl : '{name}',
startCollapsed : true,
enableGroupingMenu : false
}
],
plugins : [
{
ptype : 'rowexpander',
rowBodyTpl : ['<p><b>Informationen zum Patch:<br><br></b> {prg_text}</p>'
]
}
]
}

];

this.callParent(arguments);
}
});


This change makes my app a little faster, but unfortunately the second tab is still empty.

Any ideas yet?

Thanks!

Michael

Animal
17 Dec 2012, 5:30 AM
OK, that looks good.

I suspect that there is some overnesting and lack of layouts above that in the container hierarchy.

Also, what browser, OS? And if on OSX, do you have scrollbars turned off?

Michi_72
17 Dec 2012, 5:52 AM
Hello Animal,

thanks for your reply!

The needed informations are:

OS: Windows 7
Browser: Chrome 23.0.1271.97.m

I added this content and controller to the center region of my viewport like this:



this.getController(addTabController); //in my example controller = system.info
content = prg_content //in my example content = system_info

var tab = main_tab.add({
items: [{
xtype: content
}]
})


The center region and main_tab look like this:



main_tab = Ext.create('Ext.tab.Panel',{
activeTab: 0,
items: [
{
title: 'Information' //adding a first empty Tab to the panel
}
]
});

...
{
region: 'center',
autoScroll: 'true',
items: [
main_tab
]
}
...


I hope this are the right informations!

Thanks!

Michi

Animal
17 Dec 2012, 11:04 AM
var tab = main_tab.add({
items: [{
xtype: content
}]
})


That's an overnest in a layoutless panel.

Read your code carefully.

You are adding to "main_tab" a Panel with no configuration except that it has one child: a component of xtype: content.

That Panel will not lay out its children!

The API documentation hammers this message into the reader!

Animal
17 Dec 2012, 11:05 AM
Likewise your region: 'center'.

How are you hoping that it lays out its children?

Does it need children?

Michi_72
17 Dec 2012, 12:28 PM
Hello Animal,

thanks for your reply and pointing me towards nearer to the solution.

I have changed my code like this:



var tab = main_tab.add({
xtype: content,
helpId: prg_helpId
});


The code of the center region i have changed like this:



{
region : 'center',
autoScroll : true,
itemId : 'center_id',
id : 'center_id',
xtype : 'tabpanel',
items : [
{
title : 'Information',
itemId : 'home'
}
}


Is this right?

The second tab is still not shown and the console throws
"Uncaught TypeError: Cannot read property 'childNodes' of null"
when changing to the second tab.

How to add a title, tools and so on to the tabpanel, this issue caused me in overnesting layouts!

Thanks in advance.

Michi

dongryphon
18 Dec 2012, 12:37 AM
If you need the panel header (and title/tools) inside the tab of a tab panel, then you could do this:



{
xtype: 'tabpanel',
items: [{
xtype: 'panel',
title: 'Tab Text',
layout: 'fit', // important :)
items: [{
title: 'Titlebar in the Tab',
tools: ...
}]
}]
}

Michi_72
18 Dec 2012, 4:35 AM
Hello,

what is the content from this bug "EXTJSIV-8037"? Can you short explain?

I working on my app and remove all overnesting layouts!

Thanks!

Michi

dongryphon
18 Dec 2012, 4:26 PM
I opened the ticket because this looks/looked like it may be a regression. It may yet be, but the removal of over-nesting is always a "Good Thing" so I would highly recommend you proceed :)

As you see, the "over" part can be a question at times. There are cases where nesting is necessary. In those cases, you may just need to specify the layout (typically "fit" if you have a single child item). If you don't specify a layout config, you get the "auto" layout which does not manage the size of the child items in any way. It does react to their "auto size" but that can be confusing to understand the "auto size" of a bunch of child components. Often this is not what you want, but could be.

If the nesting is intentional, I would also highly recommend a comment stating the reasons (such as "need panel header/tools inside the tab") or something so the next person to maintain the code does not "fix" the problem by removing the nesting.

I would also suggestion adding "layout: 'auto'" to any place where that is specifically what you want, again because it often looks like a mistake when you don't specify the layout.

While one could argue this more broadly (I mean, there are other config properties that have default values), over-nesting and unintentional use of "auto" layout are very common mistakes.

Michi_72
18 Dec 2012, 10:34 PM
Hello,

thanks for your explanation! I will take your advise / hints and rework my whole application with removing all over-nesting layouts.

After removing the layouts in my example, which was the cause of this thread, now i got this error with 4.2.0 beta:

The console throws "Uncaught TypeError: Cannot read property 'childNodes' of null"
when changing to the second tab.

Any Idea?

Thanks for your support!

Michi

dongryphon
19 Dec 2012, 12:50 AM
I would stop on that error in the debugger (Chrome or Firefox/Firebug make this easy) and see if you can tell from the callstack what is attempting to happen. If you cannot figure it out, posting the callstack here may help others understand the situation.

Michi_72
19 Dec 2012, 9:05 PM
Hello,

i have founded the piece of code which makes problems:

The modell:


Ext.define('AM.model.nav.system_update',
{
extend : 'Ext.data.Model',
fields : [
{
name : 'id',
type : 'int'
},
{
name : 'prg_version'
},
{
name : 'prg_time_real',
type : 'date',
dateFormat : 'Y-m-d H:i:s'
},
{
name : 'prg_time_year',
convert : function(value, record) {
prg_time_year = record.data.prg_time_real.getFullYear();
return prg_time_year;
}
},
{
name : 'prg_kategorie'
},
{
name : 'prg_text'
},
{
name : 'prg_document_path'
}
],
idProperty : 'id'
});


The Store:



Ext.define('AM.store.nav.system_update',
{
extend : 'Ext.data.Store',
model : 'AM.model.nav.system_update',
autoLoad : true,
groupDir : 'DESC',
groupField : 'prg_time_year',
proxy :
{
type : 'ajax',
url : 'prg/system_updateverlauf/system_updateverlauf_db.php',
reader :
{
root : 'data',
totalProperty : 'count',
id : 'id'
}
}
});


The store has the groupField 'prg_time_year' which is in the modell defined like this:



{
name : 'prg_time_year',
convert : function(value, record) {
prg_time_year = record.data.prg_time_real.getFullYear();
return prg_time_year;
}
},


In the grid i use this feature:



features : [
{
ftype : 'groupingsummary',
groupHeaderTpl : '{name}',
startCollapsed : true,
enableGroupingMenu : false
}
],


The grid columns are shown (after removing all overnested layouts ;)), but wihtout data.

When using this feature i got an error 'Uncaught TypeError: Cannot read property 'childNodes' of null' - whithout everything works fine in 4.2.0 beta (without grouping)!

Thanks!

Michi