PDA

View Full Version : Uncaught TypeError adding previously added tabs to tab panel



qt4x11
20 Jan 2012, 3:06 PM
My app is modeled on the 4.0 version of the compatibility examples. Basically it has a viewport with a border layout, a header, a navigation treepanel on the left, and a tab panel to hold menu selection tabs in the main window. My code looks like



Ext.define('Ext.reports.App', {
requires : ['Ext.data.*', 'Ext.Viewport', 'Ext.tab.Panel',
'Ext.layout.container.Border', 'Ext.reports.NavTree',
'Ext.reports.Dashboard', 'Ext.reports.OrdersTab',
'Ext.reports.OrdersModel', 'Ext.reports.OrderWindow',
'Ext.reports.CompanyCustomerSummary',
'Ext.reports.CompanyCustomerSummaryGrid',
'Ext.reports.CompanyCustomerSummaryForm',
'Ext.reports.CompanyCustomerSummaryModel',
'Ext.reports.CustomerLanguageSummary',
'Ext.reports.CustomerLanguageSummaryForm',
'Ext.reports.CustomerLanguageSummaryGrid',
'Ext.reports.CustomerLanguageSummaryModel',
'Ext.reports.CustomerServiceTypeSummary',
'Ext.reports.CustomerServiceTypeSummaryGrid',
'Ext.reports.CustomerServiceTypeSummaryForm',
'Ext.reports.CustomerServiceTypeSummaryModel',
'Ext.reports.CustomerSatisfactionSummary',
'Ext.reports.CustomerSatisfactionSummaryGrid',
'Ext.reports.CustomerSatisfactionSummaryForm',
'Ext.reports.CustomerSatisfactionSummaryModel',
'Ext.reports.AgentSatisfactionSummary',
'Ext.reports.AgentSatisfactionSummaryGrid',
'Ext.reports.AgentSatisfactionSummaryForm',
'Ext.reports.AgentSatisfactionSummaryModel',
'Ext.reports.AgentServiceTypeSummary',
'Ext.reports.AgentServiceTypeSummaryGrid',
'Ext.reports.AgentServiceTypeSummaryForm',
'Ext.reports.AgentServiceTypeSummaryModel',
'Ext.reports.AgentLanguageSummary',
'Ext.reports.CompanyAgentSummary',
'Ext.reports.AgentAverageTimeSummary',
'Ext.reports.CompanyAgentStatusSummaryReport',
'Ext.reports.StationDownReport',
'Ext.reports.ExpertiseCategoryReport',
'Ext.reports.StationLogForDay', 'Ext.reports.ExpertLogForDay',
'Ext.reports.SessionLogForDay',
'Ext.reports.SessionLogDetailForDay', 'Ext.reports.EnterpriseLog',
'Ext.reports.OldEnterpriseLog',
'Ext.reports.CustomerSatisfactionSummary2',
'Ext.reports.AgentCustomerSatisfactionSummary',
'Ext.reports.CompanyCustomerSummaryIncludeCallAbandoned',
'Ext.reports.AgentSalesSummary',
'Ext.reports.AgentProductivitySummary',
'Ext.reports.StorePerformanceSummary',
'Ext.reports.HourlyActivityReport',
'Ext.reports.MerchandiseSalesReport',
'Ext.reports.StorePerformanceOverviewSummary',
'Ext.reports.TopCustomersReport', 'Ext.reports.ManagerDashboard',
'Ext.reports.CallbackReport', 'Ext.reports.StationStatusReport',
'Ext.reports.RentalAgreementReport'],


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


this.ordersStore = new Ext.data.Store({
model : 'Ext.reports.OrdersModel',
data : [{
id : 101,
desc : 'This is order 101.',
total : 123.45,
dt : '1/12/2011'
}, {
id : 102,
desc : 'This is order 102.',
total : 345.75,
dt : '3/1/2011'
}, {
id : 103,
desc : 'This is order 103.',
total : 153.43,
dt : '4/8/2011'
}, {
id : 104,
desc : 'This is order 104.',
total : 865.28,
dt : '4/21/2011'
}]
});
new Ext.Viewport({
layout : 'border',
items : [{
xtype : 'box',
id : 'app-header',
region : 'north',
html : 'Reports <span class="subtitle">Version 3.4</span>',
height : 50
}, {
region : 'center',
layout : 'border',
border : false,
items : [{
xtype : 'reports-navtree',
id : 'app-navtree',
listeners : {


'navclick' : function(tree, nodeId) {
this.syncNavigation(nodeId);
},


'load' : function(store, node) {
// this fires after the root node has loaded
Ext.defer(this.syncNavigation, 100, this,
[node.firstChild.data.id]);
},
scope : this
}
}, {
region : 'center',
xtype : 'tabpanel',
id : 'app-tabpanel',
activeItem : 0,
items : [{
xtype : 'reports-dashboard',
id : 'tab-dashboard'
}],
listeners : {
'tabchange' : function(tabs, tab) {
this.syncNavigation(tab.id);
},
scope : this
}
}]
}]
});
},


showOrderForm : function() {
if (!this.orderWindow) {
this.orderWindow = new Ext.reports.OrderWindow({
store : this.ordersStore
});
}
this.orderWindow.show();
},


syncNavigation : function(navItemId) {
var navId = navItemId.split('.')[0], tree = Ext.getCmp('app-navtree'), tabs = Ext
.getCmp('app-tabpanel');


if (navId == 'CompanyCustomerSummary'
&& !this.CompanyCustomerSummaryTab) {
var tab = tabs.getComponent('tab-' + navId);
if (!tab) {
this.companyCustomerSummaryTab = tabs.add({
xtype : 'reports-companyCustomerSummary',
id : 'tab-' + navId
});
}
}
if (navId == 'CustomerLanguageSummary'
&& !this.CustomerLanguageSummaryTab) {
var tab = tabs.getComponent('tab-' + navId);
if (!tab) {
this.customerLanguageSummaryTab = tabs.add({
xtype : 'reports-customerLanguageSummary',
id : 'tab-' + navId
});
}
}


var node = tree.getStore().getNodeById('node-' + navId);
if (node) {
tree.getSelectionModel().select(node);
}
Ext.getCmp('app-tabpanel').setActiveTab('tab-' + navId);
}


});


// renderers
pctg = function(value) {


if (parseInt(value) <= 0) {
return '<span style="color:red;">' + value + '%</span>';


} else {
return '<span style="color:green;">' + value + '%</span>';


}
};




This section of code adds additional tabs to the main tab panel when an item is selected from the nav menu, a new tab is created and set as active tab in the panel. I've put in checks to see if the tab already exists in the panel, and only add the tab to the tabpanel if it doesn't already exist on the panel




if (navId == 'CompanyCustomerSummary'
&& !this.CompanyCustomerSummaryTab) {
var tab = tabs.getComponent('tab-' + navId);
if (!tab) {
this.companyCustomerSummaryTab = tabs.add({
xtype : 'reports-companyCustomerSummary',
id : 'tab-' + navId
});
}
}
if (navId == 'CustomerLanguageSummary'
&& !this.CustomerLanguageSummaryTab) {
var tab = tabs.getComponent('tab-' + navId);
if (!tab) {
this.customerLanguageSummaryTab = tabs.add({
xtype : 'reports-customerLanguageSummary',
id : 'tab-' + navId
});
}
}


This seems to work initially. When I close a tab, I'm able to re-add the tab to the panel by clicking the nav item associated with that tab's navId. However, I notice some weird errors in developer console when I open, close and readd a tab a couple of times


Uncaught TypeError: Cannot read property 'style' of undefined ext-all-debug.js:8908


I noticed the stack trace for this error references this line in my code


Ext.getCmp('app-tabpanel').setActiveTab('tab-' + navId);


When I get the Uncaught TypeError, the tab that is added to the panel is empty, as in it does not contain any child panels and is basically nonfunctional. I'm not sure what is 'undefined' at that point in the code that could be triggering this error. If anyone would care to take a look at my code, I'd really appreciate it. Thanks.

mitchellsimoens
23 Jan 2012, 11:56 AM
I wouldn't use id. For stuff like this, I add a custom property and check against this property...


tab = tabpanel.down('container[navId=' + navId + ']');

if (!tab) {
tab = {
title : 'Some Title',
navId : navId,
....
};
}

tabpanel.setActiveTab(tab);

What this code does is first use ComponentQuery to check if any container (or subclass like panel or grid) has the property 'navId' is equal to the value in the navId variable. If not, it will return null so the if statement catches that and turns the tab variable into a config object. Lastly you execute setActiveTab which can accept an actual instance or a config object. If it's a config object, it will create, add, and set that component as the active tab.

qt4x11
24 Jan 2012, 4:03 PM
Thanks. I tried your suggestion, but am still having problems. I think I may have implemented your suggestion incorrectly but am not sure. My code looks like this currently


Ext.define('Ext.reports.App', {
requires : ['Ext.data.*', 'Ext.Viewport', 'Ext.tab.Panel',
'Ext.layout.container.Border', 'Ext.reports.NavTree',
'Ext.reports.Dashboard', 'Ext.reports.OrdersTab',
'Ext.reports.OrdersModel', 'Ext.reports.OrderWindow',
'Ext.reports.CompanyCustomerSummary',
'Ext.reports.CompanyCustomerSummaryGrid',
'Ext.reports.CompanyCustomerSummaryForm',
'Ext.reports.CompanyCustomerSummaryModel',
'Ext.reports.CustomerLanguageSummary',
'Ext.reports.CustomerLanguageSummaryForm',
'Ext.reports.CustomerLanguageSummaryGrid',
'Ext.reports.CustomerLanguageSummaryModel',
'Ext.reports.CustomerServiceTypeSummary',
'Ext.reports.CustomerServiceTypeSummaryGrid',
'Ext.reports.CustomerServiceTypeSummaryForm',
'Ext.reports.CustomerServiceTypeSummaryModel',
'Ext.reports.CustomerSatisfactionSummary',
'Ext.reports.CustomerSatisfactionSummaryGrid',
'Ext.reports.CustomerSatisfactionSummaryForm',
'Ext.reports.CustomerSatisfactionSummaryModel',
'Ext.reports.AgentSatisfactionSummary',
'Ext.reports.AgentSatisfactionSummaryGrid',
'Ext.reports.AgentSatisfactionSummaryForm',
'Ext.reports.AgentSatisfactionSummaryModel',
'Ext.reports.AgentServiceTypeSummary',
'Ext.reports.AgentServiceTypeSummaryGrid',
'Ext.reports.AgentServiceTypeSummaryForm',
'Ext.reports.AgentServiceTypeSummaryModel',
'Ext.reports.AgentLanguageSummary',
'Ext.reports.AgentLanguageSummaryGrid',
'Ext.reports.AgentLanguageSummaryForm',
'Ext.reports.AgentLanguageSummaryModel',
'Ext.reports.CompanyAgentSummary',
'Ext.reports.CompanyAgentSummaryGrid',
'Ext.reports.CompanyAgentSummaryForm',
'Ext.reports.CompanyAgentSummaryModel',
'Ext.reports.AgentAverageTimeSummary',
'Ext.reports.AgentAverageTimeSummaryGrid',
'Ext.reports.AgentAverageTimeSummaryForm',
'Ext.reports.AgentAverageTimeSummaryModel',
'Ext.reports.CompanyAgentStatusSummaryReport',
'Ext.reports.StationDownReport',
'Ext.reports.ExpertiseCategoryReport',
'Ext.reports.StationLogForDay', 'Ext.reports.ExpertLogForDay',
'Ext.reports.SessionLogForDay',
'Ext.reports.SessionLogDetailForDay', 'Ext.reports.EnterpriseLog',
'Ext.reports.OldEnterpriseLog',
'Ext.reports.CustomerSatisfactionSummary2',
'Ext.reports.AgentCustomerSatisfactionSummary',
'Ext.reports.CompanyCustomerSummaryIncludeCallAbandoned',
'Ext.reports.AgentSalesSummary',
'Ext.reports.AgentProductivitySummary',
'Ext.reports.StorePerformanceSummary',
'Ext.reports.HourlyActivityReport',
'Ext.reports.MerchandiseSalesReport',
'Ext.reports.StorePerformanceOverviewSummary',
'Ext.reports.TopCustomersReport', 'Ext.reports.ManagerDashboard',
'Ext.reports.CallbackReport', 'Ext.reports.StationStatusReport',
'Ext.reports.RentalAgreementReport'],


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


this.ordersStore = new Ext.data.Store({
model : 'Ext.reports.OrdersModel',
data : [{
id : 101,
desc : 'This is order 101.',
total : 123.45,
dt : '1/12/2011'
}, {
id : 102,
desc : 'This is order 102.',
total : 345.75,
dt : '3/1/2011'
}, {
id : 103,
desc : 'This is order 103.',
total : 153.43,
dt : '4/8/2011'
}, {
id : 104,
desc : 'This is order 104.',
total : 865.28,
dt : '4/21/2011'
}]
});
new Ext.Viewport({
layout : 'border',
items : [{
xtype : 'box',
id : 'app-header',
region : 'north',
html : 'Reports <span class="subtitle">Version 3.4</span>',
height : 50
}, {
region : 'center',
layout : 'border',
border : false,
items : [{
xtype : 'reports-navtree',
id : 'app-navtree',
listeners : {


'navclick' : function(tree, nodeId) {
this.syncNavigation(nodeId);
},


'load' : function(store, node) {
// this fires after the root node has loaded
Ext.defer(this.syncNavigation, 100, this,
[node.firstChild.data.id]);
},
scope : this
}
}, {
region : 'center',
xtype : 'tabpanel',
id : 'app-tabpanel',
activeItem : 0,
items : [{
xtype : 'reports-dashboard',
id : 'tab-dashboard'
}],
listeners : {
'tabchange' : function(tabs, tab) {
this.syncNavigation(tab.id);
},
scope : this
}
}]
}]
});
},


showOrderForm : function() {
if (!this.orderWindow) {
this.orderWindow = new Ext.reports.OrderWindow({
store : this.ordersStore
});
}
this.orderWindow.show();
},


//this function has problems setting active tab if nodeId has already been selected and closed
//to fix later
syncNavigation : function(navItemId) {
var navId = navItemId.split('.')[0], tree = Ext.getCmp('app-navtree'), tabs = Ext
.getCmp('app-tabpanel');


if (navId == 'CompanyCustomerSummary'
&& !this.CompanyCustomerSummaryTab) {
//var tab = tabs.getComponent('tab-' + navId);
var tab = tabs.down('container[navId=' + navId + ']');

if (!tab) {
this.companyCustomerSummaryTab = tabs.add({
xtype : 'reports-companyCustomerSummary',
id : 'tab-' + navId
});
}
tabs.setActiveTab('tab-' + navId);
}
if (navId == 'CustomerLanguageSummary'
&& !this.CustomerLanguageSummaryTab) {
//var tab = tabs.getComponent('tab-' + navId);
var tab = tabs.down('container[navId=' + navId + ']');

if (!tab) {
this.customerLanguageSummaryTab = tabs.add({
xtype : 'reports-customerLanguageSummary',
id : 'tab-' + navId
});
}
tabs.setActiveTab('tab-' + navId);
}


var node = tree.getStore().getNodeById('node-' + navId);
if (node) {
tree.getSelectionModel().select(node);
}
}


});


// renderers
pctg = function(value) {


if (parseInt(value) <= 0) {
return '<span style="color:red;">' + value + '%</span>';


} else {
return '<span style="color:green;">' + value + '%</span>';


}
};


secondsToHms = function (value) {
value = Number(value);
var h = Math.floor(value / 3600);
var m = Math.floor(value % 3600 / 60);
var s = Math.floor(value % 3600 % 60);
return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s);
}


so the syncNavigation() function that adds tabs to the tabpanel looks like


syncNavigation : function(navItemId) {
var navId = navItemId.split('.')[0], tree = Ext.getCmp('app-navtree'), tabs = Ext
.getCmp('app-tabpanel');


if (navId == 'CompanyCustomerSummary'
&& !this.CompanyCustomerSummaryTab) {
//var tab = tabs.getComponent('tab-' + navId);
var tab = tabs.down('container[navId=' + navId + ']');

if (!tab) {
this.companyCustomerSummaryTab = tabs.add({
xtype : 'reports-companyCustomerSummary',
id : 'tab-' + navId
});
}
tabs.setActiveTab('tab-' + navId);
}
if (navId == 'CustomerLanguageSummary'
&& !this.CustomerLanguageSummaryTab) {
//var tab = tabs.getComponent('tab-' + navId);
var tab = tabs.down('container[navId=' + navId + ']');

if (!tab) {
this.customerLanguageSummaryTab = tabs.add({
xtype : 'reports-customerLanguageSummary',
id : 'tab-' + navId
});
}
tabs.setActiveTab('tab-' + navId);
}


I'm still having the same problem - this code will add a new tab to the tabpanel,

30962

I can close this tab and reopen it. But the reopened tab window is empty and I see an error in the debugger

30963

the stack trace in the debugger point to the line in the code where I setActiveTab

30964

Any suggestions? I'm not sure why this is generating 'undefined'.... Thanks.

qt4x11
25 Jan 2012, 3:53 PM
In case it would be helpful, I'm pasting below the code for one of my tabpanel classes


Ext.define('Ext.reports.CompanyCustomerSummary', {
extend : 'Ext.Panel',
alias : 'widget.reports-companyCustomerSummary',
title : 'Customer Interaction Summary',
closable : true,
id: 'CompanyCustomerSummary',
layout : {
type : 'vbox',
align : 'stretch'
},
items : [{
xtype : 'reports-companyCustomerSummaryForm',
height : 100
}, {
xtype : 'reports-companyCustomerSummaryGrid',
flex : 1


}],


initComponent : function() {
this.callParent(arguments);
}


});

jay@moduscreate.com
25 Jan 2012, 4:43 PM
With all due respect, posting code like this isn't very helpful. Many folks might opt not to assist because it's extremely hard to digest. :(

That said, you absolutely should stop using static component ids.

What you need to do is set a break point in our code and step through it. Are your itemIds setup properly? is there an exception during the add phase?

rv77ax
2 May 2012, 4:30 AM
I have the same problem. Did you find the solution?