PDA

View Full Version : [4.0.7] Controller listen to tab activate event



lorezyra
9 Dec 2011, 5:27 AM
I'm migrating my ExtJS 3 app to ExtJS 4 (and refactoring with MVC pattern). This is a "2-page" application that has a login and the main app. I've completed the login "app" and it works great. However, my trouble starts in the implementation of my multi-controller based app. I'm designing this app to use a separate controller per feature (as opposed to one per view).

I'm trying to setup my controller to listen for tab activations in order to process some tasks at the moment the tab is clicked on. Perhaps someone could enlighten me on the ExtJS 4 way of setting up a controller to listen for the 'activate' tab event.




Ext.define('RichieBartlett.controller.usrMangerTAB', {
extend: 'Ext.app.Controller',
//stores:[''],
views:['usrMangerTAB'],
refs: [{
ref: 'UsrMangerTAB',
selector: 'usrMangerTAB'
}],

init:function(){
if(Ext.isGecko && debug) console.log(" usrMangerTAB.controllerInit()");
var me=this;
/*
me.application.on({//handle system-application wide events and calls here!!
'event': me.event,
scope: me
});
*/
me.control({
'#usrMangerTAB':({ //tabPanel object
afterrender: me.initUsrMangerTAB,
scope: me
}/*,{ //toolbar button object
activate: me.cancelContextMenu,
scope: me
})*/,{ //toolbar button object
contextmenu: me.cancelContextMenu,
scope: me
})
},{
'#userTabGrpMgr':({ //tabPanel object
activate: me.userTabGrpMgrActivate,
scope: me
},{ //toolbar button object
contextmenu: me.cancelContextMenu,
scope: me
})
},{
'#userTabUsrMgr':({ //tabPanel object
activate: me.userTabUsrMgrActivate,
scope: me
})
},{
'#userTabSess':({ //tabPanel object
activate: me.userTabSessActivate,
scope: me
})
},{
'#userTabReq':({ //tabPanel object
activate: me.userTabReqActivate,
scope: me
})
},{
'#userTabDeclined':({ //tabPanel object
activate: me.userTabDeclineActivate,
scope: me
})
},{
'#userTabBanned':({ //tabPanel object
activate: me.userTabBanActivate, //RichieBartlett.controller.usrMangerTAB.prototype.userTabBanActivate()
scope: me
})
},{
'#userTabIP':({ //tabPanel object
activate: me.userTabIPActivate,
scope: me
},{ //toolbar button object
contextmenu: me.cancelContextMenu,
scope: me
})
},{
'#usrIPToolbarReload':({ //toolbar button object
click: me.usrIPToolbarReloadOnClick,
scope: me
})
},{
'#usrIPToolbarDel':({ //toolbar button object
click: me.usrIPToolbarDelOnClick,
scope: me
},{ //toolbar button object
contextmenu: me.cancelContextMenu,
scope: me
})
});

},
initUsrMangerTAB: function(){
var me=this;
if(Ext.isGecko && debug) console.log(" usrMangerTAB.initUsrMangerTAB()");
// setup tab listeners!
Ext.getCmp("userTabMgr").on('activate', me.userTabMgrActivate, me);
Ext.getCmp("userTabGrpMgr").on('activate', me.userTabGrpMgrActivate, me);
Ext.getCmp("userTabSess").on('activate', me.userTabSessActivate, me);
Ext.getCmp("userTabIP").on('activate', me.userTabIPActivate, me);

},
userTabGrpMgrActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogGroup").data.length<1){
//adminUIappLogBoard("Loading group stores");
Ext.StoreMgr.lookup("blogGroup").load();
}//end if storeCnt
},
userTabUsrMgrActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogUser").data.length<1){
//adminUIappLogBoard("Loading users stores");
Ext.StoreMgr.lookup("blogUser").load();
}//end if storeCnt
},
userTabSessActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogUserSess").data.length<1){
//adminUIappLogBoard("Loading concurrent sessions");
Ext.StoreMgr.lookup("blogUserSess").load();
}//end if storeCnt
},
userTabReqActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogUserReq").data.length<1){
//adminUIappLogBoard("Loading membership requestors");
Ext.StoreMgr.lookup("blogUserReq").load();
}//end if storeCnt
},
userTabDeclineActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogUserDeclined").data.length<1){
//adminUIappLogBoard("Loading declined users");
Ext.StoreMgr.lookup("blogUserDeclined").load();
}//end if storeCnt
},
userTabBanActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("blogUserBanned").data.length<1){
//adminUIappLogBoard("Loading banned users");
Ext.StoreMgr.lookup("blogUserBanned").load();
}//end if storeCnt
},
userTabIPActivate: function(tab, eOpts){
//only reload if the store is empty
if(Ext.StoreMgr.lookup("userIPban").data.length<1){
Ext.StoreMgr.lookup("userIPban").load();
this.application.fireEvent('adminlogevent',{msg:"Loading currently banned IPs"});
}//end if storeCnt
},
usrIPToolbarReloadOnClick: function(){
Ext.getCmp("usrIPGrid").getStore().reload();
},
usrIPToolbarDelOnClick: function(){
//TODO: remove ban flag on IP
},
cancelContextMenu: function(e){
e.preventDefault();
}



});

I've tried to use the afterrender event on the parent tab in order to setup the child tab listeners. However, this event simply doesn't fire.

Maybe after I get some sleep the answer will glare me in the face... :)

arthurakay
9 Dec 2011, 10:37 AM
Are you saying the "afterrender" event on the tab panel doesn't fire? Or the "activate" events on the child components don't fire?

I'm not clear on what you mean.

lorezyra
9 Dec 2011, 1:10 PM
Thanks for replying. This week, I haven't been getting enough sleep. So, I apologize if my clarity is lacking.

From FireBug, I can see this controller getting initialized since the console log outputs " usrMangerTAB.controllerInit()." My other controllers load without issue and I can see the configured events fired in FireBug. However, on usrMangerTAB, none of the events appear to be firing. I know I have the component names correct. (I've included the view/ui for the usrMangerTAB below.)

I click on the user manager tab and no events are fired. I clicked on the child tabs and no events are fired. Surely, I must be doing something wrong. I just can't see it yet. Can you advise me?



/*
* File: app/view/ui/usrMangerTAB.js
* Date: Tue Dec 06 2011 05:36:14 GMT+0900 (Tokyo Standard Time)
*
* This file was generated by Ext Designer version 1.2.2.
* http://www.sencha.com/products/designer/
*
* This file will be auto-generated each and everytime you export.
*
* Do NOT hand edit this file.
*/

Ext.define('RichieBartlett.view.ui.usrMangerTAB', {
extend: 'Ext.tab.Panel',

border: 0,
id: 'usrMangerTAB',
itemId: 'usrMangerTAB',
iconCls: 'icon-TABusrMgr',
title: 'Users & Groups',

initComponent: function() {
var me = this;

Ext.applyIf(me, {
items: [
{
xtype: 'panel',
id: 'userTabGrpMgr',
itemId: 'userTabGrpMgr',
layout: {
type: 'border'
},
iconCls: 'icon-TABusrMgr',
title: 'Group Manager',
dockedItems: [
{
xtype: 'toolbar',
id: 'groupTabMgrTools',
itemId: 'groupTabMgrTools',
region: 'center',
dock: 'top',
items: [
{
xtype: 'button',
id: 'UserViewPanelGrpAdd',
itemId: 'UserViewPanelGrpAdd',
iconCls: 'icon-groupBtnAdd',
scale: 'medium',
text: 'Add'
},
{
xtype: 'button',
id: 'UserViewPanelGrpDel',
itemId: 'UserViewPanelGrpDel',
iconCls: 'icon-groupBtnDel',
scale: 'medium',
text: 'Remove'
},
{
xtype: 'button',
id: 'UserViewPanelGrpReload',
itemId: 'UserViewPanelGrpReload',
iconCls: 'icon-reload2',
scale: 'medium',
text: 'Reload'
},
{
xtype: 'button',
id: 'UserViewPanelGrpSaves',
itemId: 'UserViewPanelGrpSaves',
iconCls: 'icon-disk2',
scale: 'medium',
text: 'Save Changes'
},
{
xtype: 'button',
id: 'UserViewPanelGrpForget',
itemId: 'UserViewPanelGrpForget',
iconCls: 'icon-trashcan',
scale: 'medium',
text: 'Forget Changes'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'grpViewPanelGrpBBfilter',
itemId: 'grpViewPanelGrpBBfilter',
width: 200,
name: 'grpViewPanelGrpBBfilter',
fieldLabel: 'Filter',
labelWidth: 40,
emptyText: 'Group Search...',
hideTrigger: true
},
{
xtype: 'button',
id: 'grpViewPanelUsrBBfilterFind',
itemId: 'grpViewPanelUsrBBfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'grpViewPanelUsrBBfilterClear',
itemId: 'grpViewPanelUsrBBfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
items: [
{
xtype: 'gridpanel',
id: 'grpViewPanel',
itemId: 'grpViewPanel',
store: 'blogGroup',
region: 'center',
split: true,
dockedItems: [
{
xtype: 'pagingtoolbar',
id: 'grpViewPanelPageBar',
itemId: 'grpViewPanelPageBar',
displayInfo: true,
store: 'blogGroup',
dock: 'bottom',
items: [
{
xtype: 'tbseparator'
},
{
xtype: 'button',
id: 'grpViewPanelGrpBBSaves',
itemId: 'grpViewPanelGrpBBSaves',
width: 125,
iconCls: 'icon-disk2',
text: 'Save Changes'
},
{
xtype: 'button',
id: 'grpViewPanelGrpBBForget',
itemId: 'grpViewPanelGrpBBForget',
width: 125,
iconCls: 'icon-disk2',
text: 'Forget Changes'
}
]
}
],
viewConfig: {
emptyText: 'Loading Groups',
loadingText: 'Loading User database...',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
columns: [
{
xtype: 'numbercolumn',
hidden: true,
width: 35,
align: 'right',
dataIndex: 'id',
text: 'ID'
},
{
xtype: 'booleancolumn',
width: 40,
resizable: false,
dataIndex: 'visible',
text: 'Visible',
field: {
xtype: 'checkboxfield'
}
},
{
xtype: 'gridcolumn',
width: 120,
dataIndex: 'name',
hideable: false,
text: 'Name',
field: {
xtype: 'textfield'
}
},
{
xtype: 'gridcolumn',
width: 300,
dataIndex: 'description',
text: 'Description',
field: {
xtype: 'textareafield'
}
},
{
xtype: 'booleancolumn',
width: 50,
resizable: false,
dataIndex: 'attachEnabled',
text: 'Attach?',
field: {
xtype: 'checkboxfield'
}
},
{
xtype: 'booleancolumn',
width: 75,
resizable: false,
dataIndex: 'userManage',
text: 'User Manager',
field: {
xtype: 'checkboxfield'
}
},
{
xtype: 'numbercolumn',
width: 100,
dataIndex: 'attachLimit',
text: 'Limit (Bytes)',
format: '0,000',
field: {
xtype: 'numberfield',
allowDecimals: false,
decimalPrecision: 0,
minValue: -1
}
},
{
xtype: 'gridcolumn',
width: 250,
dataIndex: 'attachType',
text: 'Type of Attachments (regex)',
field: {
xtype: 'textfield'
}
},
{
xtype: 'gridcolumn',
width: 275,
dataIndex: 'attachDescript',
text: 'Description of the Type',
field: {
xtype: 'textareafield'
}
},
{
xtype: 'numbercolumn',
hidden: true,
width: 75,
dataIndex: 'parent',
text: 'Parent Group',
field: {
xtype: 'numberfield',
minValue: 0
}
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabUsrMgr',
itemId: 'userTabUsrMgr',
layout: {
type: 'border'
},
iconCls: 'icon-TABusrMgr',
title: 'User Manager',
dockedItems: [
{
xtype: 'toolbar',
id: 'userTabMgrTools',
itemId: 'userTabMgrTools',
region: 'center',
dock: 'top',
items: [
{
xtype: 'button',
id: 'UserViewPanelUsrAdd',
itemId: 'UserViewPanelUsrAdd',
iconCls: 'icon-userBtnAdd',
scale: 'medium',
text: 'New'
},
{
xtype: 'splitbutton',
id: 'UserViewPanelUsrBan',
itemId: 'UserViewPanelUsrBan',
iconCls: 'icon-TABusrBanned',
scale: 'medium',
text: 'Ban',
menu: {
xtype: 'menu',
id: 'UserViewPanelUsrBanMenu',
itemId: 'UserViewPanelUsrBanMenu',
items: [
{
xtype: 'menuitem',
id: 'UserTABusrBannedUser',
itemId: 'UserTABusrBannedUser',
iconCls: 'icon-TABusrBanned',
text: 'User'
},
{
xtype: 'menuitem',
id: 'UserTABusrBannedIP',
itemId: 'UserTABusrBannedIP',
text: 'IP Address'
}
]
}
},
{
xtype: 'button',
id: 'UserViewPanelUsrDel',
itemId: 'UserViewPanelUsrDel',
iconCls: 'icon-userBtnDel',
scale: 'medium',
text: 'Delete'
},
{
xtype: 'button',
id: 'UserViewPanelUsrReload',
itemId: 'UserViewPanelUsrReload',
iconCls: 'icon-reload2',
scale: 'medium',
text: 'Refresh'
},
{
xtype: 'button',
id: 'UserViewPanelUsrSaves',
itemId: 'UserViewPanelUsrSaves',
iconCls: 'icon-disk',
scale: 'medium',
text: 'Save All Changes'
},
{
xtype: 'button',
id: 'UserViewPanelUsrRejectChange',
itemId: 'UserViewPanelUsrRejectChange',
iconCls: 'icon-trashcan',
scale: 'medium',
text: 'Discard Changes'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'UserViewPanelGrpBBfilter',
itemId: 'UserViewPanelGrpBBfilter',
width: 200,
name: 'UserViewPanelGrpBBfilter',
fieldLabel: 'Filter',
labelWidth: 40,
emptyText: 'User Search...',
hideTrigger: true
},
{
xtype: 'button',
id: 'UserViewPanelUsrBBfilterFind',
itemId: 'UserViewPanelUsrBBfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'UserViewPanelUsrBBfilterClear',
itemId: 'UserViewPanelUsrBBfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
items: [
{
xtype: 'gridpanel',
id: 'usrViewPanel',
itemId: 'usrViewPanel',
store: 'blogUser',
region: 'center',
dockedItems: [
{
xtype: 'pagingtoolbar',
id: 'UserViewPanelPageBar',
itemId: 'UserViewPanelPageBar',
displayInfo: true,
store: 'blogUser',
dock: 'bottom',
items: [
{
xtype: 'tbseparator'
},
{
xtype: 'button',
id: 'UserViewPanelGrpBBSaves',
itemId: 'UserViewPanelGrpBBSaves',
width: 125,
iconCls: 'icon-disk2',
text: 'Save All Changes'
},
{
xtype: 'button',
id: 'UserViewPanelGrpBBForget',
itemId: 'UserViewPanelGrpBBForget',
width: 125,
iconCls: 'icon-disk2',
text: 'Discard Changes'
}
]
}
],
viewConfig: {
loadingText: 'Loading User database...',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
columns: [
{
xtype: 'numbercolumn',
hidden: true,
width: 40,
align: 'right',
dataIndex: 'id',
text: 'ID',
format: 0
},
{
xtype: 'gridcolumn',
hidden: true,
width: 150,
dataIndex: 'fullName',
text: 'Full Name',
field: {
xtype: 'textfield',
allowBlank: false,
blankText: 'User\'s name must be filled in!',
maskRe: /[\w\-\+_A-Za-z0-9\.]/
}
},
{
xtype: 'gridcolumn',
width: 150,
dataIndex: 'username',
text: 'Username',
field: {
xtype: 'textfield',
allowBlank: false,
blankText: 'Username is required!',
maskRe: /[A-Za-z0-9\@\!\.]/
}
},
{
xtype: 'gridcolumn',
hidden: true,
width: 150,
dataIndex: 'email',
text: 'Email',
field: {
xtype: 'textfield',
allowBlank: false,
blankText: 'Email is required',
maskRe: /[A-Za-z0-9\@\!\.]/,
regex: /^\s*[\w\-\+_]+(\.[\w\-\+_]+)*\@[\w\-\+_]+\.[\w\-\+_]+(\.[\w\-\+_]+)*\s*$/,
regexText: 'Enter a valid email address'
}
},
{
xtype: 'gridcolumn',
width: 110,
dataIndex: 'lastIP',
text: 'Last IP'
},
{
xtype: 'gridcolumn',
hidden: true,
width: 100,
dataIndex: 'password',
groupable: true,
text: 'Password',
field: {
xtype: 'textfield',
inputType: 'password',
allowBlank: false,
blankText: 'What? No password?!',
maskRe: /[A-Za-z0-9\@\!\.]/
}
},
{
xtype: 'gridcolumn',
hidden: true,
width: 200,
dataIndex: 'secretPhrase',
groupable: true,
text: 'PW Recover Phrase',
field: {
xtype: 'textfield'
}
},
{
xtype: 'gridcolumn',
hidden: true,
width: 150,
dataIndex: 'secretWord',
groupable: true,
text: 'PW Recover Answer',
field: {
xtype: 'textfield'
}
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'lastLogin',
text: 'Last Login',
format: 'Y/m/d H:i:s'
},
{
xtype: 'datecolumn',
hidden: true,
dataIndex: 'joinDate',
text: 'Joined',
format: 'Y/m/d H:i:s'
},
{
xtype: 'booleancolumn',
hidden: true,
width: 75,
resizable: false,
dataIndex: 'emailVerified',
text: 'Email Verified',
field: {
xtype: 'checkboxfield'
}
},
{
xtype: 'numbercolumn',
width: 60,
align: 'right',
dataIndex: 'offenseCount',
text: 'Offenses',
format: 0,
field: {
xtype: 'numberfield',
allowDecimals: false,
minValue: 0
}
},
{
xtype: 'gridcolumn',
width: 130,
dataIndex: 'lang',
text: 'Language',
field: {
xtype: 'combobox',
maxHeight: 200,
name: 'usrMgrGridLang',
emptyText: 'Select Language',
selectOnFocus: true,
editable: false,
displayField: 'name',
forceSelection: true,
queryMode: 'local',
store: 'languages',
valueField: 'roman'
}
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'country',
text: 'Country',
field: {
xtype: 'combobox',
name: 'usrMgrGridCountry',
selectOnFocus: true,
editable: false,
displayField: 'name',
forceSelection: true,
queryMode: 'local',
store: 'countries',
valueField: 'roman'
}
},
{
xtype: 'gridcolumn',
hidden: true,
width: 250,
dataIndex: 'descript',
text: '(User\'s) Description',
field: {
xtype: 'textareafield'
}
},
{
xtype: 'numbercolumn',
width: 100,
align: 'right',
dataIndex: 'group',
text: 'GroupID',
format: 0,
field: {
xtype: 'combobox',
name: 'grpID',
displayField: 'name',
queryMode: 'local',
store: 'blogGroup',
valueField: 'id'
}
},
{
xtype: 'gridcolumn',
width: 300,
dataIndex: 'adminComment',
text: 'AdminComment',
field: {
xtype: 'textareafield'
}
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabSess',
itemId: 'userTabSess',
layout: {
type: 'fit'
},
iconCls: 'icon-TABusrSession',
title: 'Concurrent Sessions',
items: [
{
xtype: 'gridpanel',
id: 'usrSessGrid',
itemId: 'usrSessGrid',
store: 'blogUserSess',
dockedItems: [
{
xtype: 'toolbar',
id: 'usrSessToolbar',
dock: 'top',
items: [
{
xtype: 'button',
id: 'usrSessToolbarReload',
itemId: 'usrSessToolbarReload',
iconCls: 'icon-reload2',
scale: 'medium',
text: 'Refresh'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'usrSessToolbarDel',
itemId: 'usrSessToolbarDel',
iconCls: 'icon-usrSessRemove',
scale: 'medium',
text: 'Remove'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'usrSessToolbarRemAll',
itemId: 'usrSessToolbarRemAll',
iconCls: 'icon-usrSessRemoveAll',
scale: 'medium',
text: 'Remove ALL'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'usrSessGridfilter',
width: 250,
fieldLabel: 'Search Filter',
labelWidth: 75,
emptyText: 'Search Sessions',
hideTrigger: true
},
{
xtype: 'button',
id: 'usrSessGridfilterFind',
itemId: 'usrSessGridfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'usrSessGridfilterClear',
itemId: 'usrSessGridfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
viewConfig: {
loadingText: 'Checking for currently logged on users.',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
columns: [
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'logTime',
hideable: false,
text: 'LogTime',
format: 'Y/m/d H:i:s'
},
{
xtype: 'gridcolumn',
width: 100,
dataIndex: 'IP',
text: 'IP Address'
},
{
xtype: 'gridcolumn',
width: 50,
align: 'right',
dataIndex: 'userId',
text: 'UserId'
},
{
xtype: 'gridcolumn',
width: 215,
dataIndex: 'PHPsessID',
hideable: false,
text: 'PHPsessID'
},
{
xtype: 'gridcolumn',
width: 125,
dataIndex: 'OS',
hideable: false,
text: 'Operating System'
},
{
xtype: 'gridcolumn',
width: 130,
dataIndex: 'OSver',
text: 'OS Version'
},
{
xtype: 'gridcolumn',
width: 80,
dataIndex: 'OSmake',
text: 'OS Maker'
},
{
xtype: 'gridcolumn',
dataIndex: 'browser',
hideable: false,
text: 'Browser'
},
{
xtype: 'numbercolumn',
width: 75,
align: 'right',
dataIndex: 'browserVer',
hideable: false,
text: 'BrowserVer',
format: 0
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'logicalXDPI',
text: 'Display Width',
format: 0
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'logicalYDPI',
text: 'Display Height',
format: 0
},
{
xtype: 'gridcolumn',
hidden: true,
width: 300,
dataIndex: 'referrer',
text: 'Referrer'
},
{
xtype: 'templatecolumn',
tpl: Ext.create('Ext.XTemplate',
'{[(values.mobileUser==1)? "Yes":""]}'
),
width: 50,
align: 'center',
dataIndex: 'mobileUser',
text: 'Mobile'
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabReq',
itemId: 'userTabReq',
layout: {
type: 'fit'
},
iconCls: '\'icon-TABusrReq',
title: 'Membership Requests',
items: [
{
xtype: 'gridpanel',
id: 'userReqGrid',
itemId: 'userReqGrid',
store: 'blogUserReq',
dockedItems: [
{
xtype: 'toolbar',
id: 'usrRequestToolbar',
dock: 'top',
items: [
{
xtype: 'button',
id: 'userReqGridAdd',
itemId: 'userReqGridAdd',
iconCls: 'icon-userBtnApprove',
scale: 'medium',
text: 'Approve'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'userReqGridDel',
itemId: 'userReqGridDel',
iconCls: 'icon-userBtnDecline',
scale: 'medium',
text: 'Decline'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'userReqGridReload',
itemId: 'userReqGridReload',
iconCls: 'icon-usrSessRemoveAll',
scale: 'medium',
text: 'Refresh'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'userReqGridfilter',
width: 250,
fieldLabel: 'Search Filter',
labelWidth: 75,
emptyText: 'Filter Users',
hideTrigger: true
},
{
xtype: 'button',
id: 'userReqGridfilterFind',
itemId: 'userReqGridfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'userReqGridfilterClear',
itemId: 'userReqGridfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
viewConfig: {
autoScroll: true,
loadingText: 'Checking for new membership requests.',
multiSelect: true,
trackOver: true
},
columns: [
{
xtype: 'numbercolumn',
hidden: true,
width: 60,
dataIndex: 'id',
text: 'ID',
format: 0
},
{
xtype: 'gridcolumn',
width: 150,
dataIndex: 'username',
hideable: false,
text: 'Username'
},
{
xtype: 'gridcolumn',
width: 250,
dataIndex: 'fullName',
text: 'Full Name'
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'email',
text: 'Email'
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'joinDate',
text: 'JoinDate',
format: 'Y/m/d H:i:s'
},
{
xtype: 'gridcolumn',
width: 110,
dataIndex: 'lang',
text: 'Language'
},
{
xtype: 'gridcolumn',
width: 300,
dataIndex: 'descript',
text: 'Self Descript',
field: {
xtype: 'textareafield'
}
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabDeclined',
itemId: 'userTabDeclined',
layout: {
type: 'fit'
},
iconCls: 'icon-TABusrDeclined',
title: 'Declined Users',
items: [
{
xtype: 'gridpanel',
border: 0,
id: 'usrDeclinedGrid',
itemId: 'usrDeclinedGrid',
store: 'blogUserDeclined',
dockedItems: [
{
xtype: 'toolbar',
id: 'usrDeclinedToolbar',
dock: 'top',
items: [
{
xtype: 'button',
id: 'usrDeclinedToolbarRem',
itemId: 'usrDeclinedToolbarRem',
iconCls: 'icon-userBtnReInstate',
scale: 'medium',
text: 'Remove Decline Flag'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'usrDeclinedToolbarReload',
itemId: 'usrDeclinedToolbarReload',
iconCls: 'icon-userBtnDecline',
scale: 'medium',
text: 'Decline'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'memberReqGridReload',
itemId: 'memberReqGridReload',
iconCls: 'icon-usrSessRemoveAll',
scale: 'medium',
text: 'Refresh'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'usrDeclinedGridfilter',
width: 250,
fieldLabel: 'Search Filter',
labelWidth: 75,
emptyText: 'Filter Users',
hideTrigger: true
},
{
xtype: 'button',
id: 'usrDeclinedGridfilterFind',
itemId: 'usrDeclinedGridfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'usrDeclinedGridfilterClear',
itemId: 'usrDeclinedGridfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
viewConfig: {
loadingText: 'Looking for Declined memberships.',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
columns: [
{
xtype: 'gridcolumn',
width: 150,
dataIndex: 'username',
hideable: false,
text: 'Username'
},
{
xtype: 'gridcolumn',
width: 250,
dataIndex: 'fullName',
text: 'Name'
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'email',
text: 'Email'
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'declineDate',
text: 'Decline Date',
format: 'Y/m/d H:i:s'
},
{
xtype: 'gridcolumn',
width: 300,
dataIndex: 'declineReason',
text: 'Reason / History',
field: {
xtype: 'textareafield'
}
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabBanned',
itemId: 'userTabBanned',
layout: {
type: 'fit'
},
iconCls: 'icon-TABusrBanned',
title: 'Banned Users',
items: [
{
xtype: 'gridpanel',
border: 0,
id: 'usrBannGrid',
itemId: 'usrBannGrid',
store: 'blogUserBanned',
dockedItems: [
{
xtype: 'toolbar',
id: 'usrBannedToolbar',
dock: 'top',
items: [
{
xtype: 'button',
id: 'usrBannedToolbarRem',
itemId: 'usrBannedToolbarRem',
iconCls: '\'icon-userBtnUnBan',
scale: 'medium',
text: 'Remove Ban Flag'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'usrBannedToolbarReload',
itemId: 'usrBannedToolbarReload',
iconCls: 'icon-reload2',
scale: 'medium',
text: 'Decline'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'usrBannedGridfilter',
width: 250,
fieldLabel: 'Search Filter',
labelWidth: 75,
emptyText: 'Filter Users',
hideTrigger: true
},
{
xtype: 'button',
id: 'usrBannedGridfilterFind',
itemId: 'usrBannedGridfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'usrBannedGridfilterClear',
itemId: 'usrBannedGridfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
viewConfig: {
loadingText: 'Querying Database for Banned Users.',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
columns: [
{
xtype: 'gridcolumn',
width: 150,
dataIndex: 'username',
hideable: false,
text: 'Username'
},
{
xtype: 'gridcolumn',
width: 250,
dataIndex: 'fullName',
text: 'Name'
},
{
xtype: 'gridcolumn',
width: 200,
dataIndex: 'email',
text: 'Email'
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'bannDate',
text: 'Banned Date',
format: 'Y/m/d H:i:s'
},
{
xtype: 'numbercolumn',
width: 75,
align: 'right',
dataIndex: 'bannDuration',
text: 'Duration',
format: 0
},
{
xtype: 'gridcolumn',
width: 250,
dataIndex: 'banReason',
text: 'Reason / History',
field: {
xtype: 'textareafield'
}
}
]
}
]
},
{
xtype: 'panel',
id: 'userTabIP',
itemId: 'userTabIP',
layout: {
type: 'fit'
},
title: 'Banned IP',
items: [
{
xtype: 'gridpanel',
border: 0,
id: 'usrIPGrid',
itemId: 'usrIPGrid',
store: 'userIPban',
dockedItems: [
{
xtype: 'toolbar',
id: 'usrIP',
dock: 'top',
items: [
{
xtype: 'button',
id: 'usrIPToolbarDel',
itemId: 'usrIPToolbarDel',
iconCls: 'icon-userBtnReInstate',
scale: 'medium',
text: 'Remove Flag'
},
{
xtype: 'tbspacer',
width: 20
},
{
xtype: 'button',
id: 'usrIPToolbarReload',
itemId: 'usrIPToolbarReload',
iconCls: 'icon-reload2',
scale: 'medium',
text: 'Refresh'
},
{
xtype: 'tbfill'
},
{
xtype: 'triggerfield',
id: 'usrIPGridfilter',
width: 250,
fieldLabel: 'Search Filter',
labelWidth: 75,
emptyText: 'Filter IP\'s',
hideTrigger: true
},
{
xtype: 'button',
id: 'usrIPGridfilterFind',
itemId: 'usrIPGridfilterFind',
iconCls: 'icon-filter'
},
{
xtype: 'button',
id: 'usrIPGridfilterClear',
itemId: 'usrIPGridfilterClear',
iconCls: 'icon-filterClear'
}
]
}
],
plugins: [
Ext.create('Ext.grid.plugin.CellEditing', {

})
],
viewConfig: {
loadingText: 'Searching for Banned IP\'s.',
multiSelect: true,
trackOver: true
},
selModel: Ext.create('Ext.selection.RowModel', {
mode: 'MULTI'
}),
columns: [
{
xtype: 'numbercolumn',
hidden: true,
width: 50,
dataIndex: 'id',
text: 'ID',
format: 0
},
{
xtype: 'gridcolumn',
width: 100,
dataIndex: 'IP',
hideable: false,
text: 'IP address'
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'logTime',
text: 'LogTime',
format: 'Y/m/d H:i:s'
},
{
xtype: 'datecolumn',
width: 150,
dataIndex: 'banUntil',
text: 'Ban Expiration',
format: 'Y/m/d H:i:s'
},
{
xtype: 'gridcolumn',
width: 150,
dataIndex: 'userId',
text: 'UserId'
},
{
xtype: 'gridcolumn',
dataIndex: 'browser',
text: 'Browser'
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'browserVer',
text: 'BrowserVer'
},
{
xtype: 'gridcolumn',
dataIndex: 'OS',
text: 'OS'
},
{
xtype: 'gridcolumn',
hidden: true,
dataIndex: 'OSver',
text: 'OSver'
},
{
xtype: 'gridcolumn',
hidden: true,
dataIndex: 'OSmake',
text: 'OSmake'
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'logicalXDPI',
text: 'Display Width',
format: 0
},
{
xtype: 'numbercolumn',
hidden: true,
dataIndex: 'logicalYDPI',
text: 'Display Height',
format: 0
},
{
xtype: 'templatecolumn',
tpl: Ext.create('Ext.XTemplate',
'{[(values.mobileUser==1)? "yes":""]}'
),
dataIndex: 'mobileUser',
text: 'MobileUser'
},
{
xtype: 'gridcolumn',
width: 300,
dataIndex: 'reason',
text: 'Reason',
field: {
xtype: 'textareafield'
}
},
{
xtype: 'gridcolumn',
hidden: true,
width: 300,
dataIndex: 'referrer',
text: 'Referrer'
}
]
}
]
}
]
});

me.callParent(arguments);
}
});

arthurakay
9 Dec 2011, 1:16 PM
Put a breakpoint in your init() method. Has the "usrMangerTAB" tab panel actually been instantiated at that point?

Your code seems to look okay (at first glance), so maybe it's an order-of-operations thing.

lorezyra
9 Dec 2011, 2:52 PM
I know that init() is called... FireBug outputs " usrMangerTAB.controllerInit()" upon entry to that method. Since the cache buster is enabled, breakpoints are not persistent between loads. I'll try to disable the cache buster and go from there...

I do believe I'm setting this up correctly... unless I'm missing something.

BTW, you're welcomed to check this out live on my webserver: http://www.RichieBartlett.com/!Admin/
I can send you the login details if you're interested.

lorezyra
9 Dec 2011, 6:45 PM
Okay, I set a break point on Ext.util.Event.fire method to see what events are going through...

Shortly after clicking on the usrMangerTAB (tab.panel component), I see a series of events fly by... among them, the "afterrender" event of the usrMangerTAB. However, my function initUsrMangerTAB is not called. Did I not define the config correctly?

However, on the childTabs, I do see an error occuring after the "afterrender" event: "Mozilla error: invalid scope variables..." I don't see how this is a scope issue. I passed the scope var.

lorezyra
9 Dec 2011, 7:40 PM
From Firebug, I can manually force a listener to watch for the activate event...


Ext.getCmp("usrMangerTAB").on('afterrender', RichieBartlett.controller.usrMangerTAB.prototype.initUsrMangerTAB, RichieBartlett.controller.usrMangerTAB.prototype);

And, it launches without errors in Firebug. This suggests to me that something is not right with the me.control block...

lorezyra
11 Dec 2011, 2:03 PM
After further debugging... I found when I manually set the listener for the parent TAB and activated that tab, the components have not been rendered yet! (I realize this is one of the new performance features of Ext4). This is, I suspect, the reason the control() method fails to create the listeners.


this.control({//watch line 16982 of ext-4.0.7-gpl/ext-all-debug-w-comments.js for event fires
'[id=usrMangerTAB]':({ //tabPanel object
afterrender: me.initUsrMangerTAB,
scope: me
},/*{ //tab 'click' event
activate: me.initUsrMangerTAB,
scope: me
},*/{ //capture right-click
contextmenu: me.cancelContextMenu,
scope: me
})
},{//"Mozilla error: invalid scope variables"

//...
initUsrMangerTAB: function(){
var me=this;
if(Ext.isGecko && debug) console.log(" usrMangerTAB.initUsrMangerTAB()");
// setup tab listeners!
Ext.getCmp("userTabUsrMgr").on('activate', me.userTabMgrActivate, me);
Ext.getCmp("userTabGrpMgr").on('activate', me.userTabGrpMgrActivate, me);
Ext.getCmp("userTabSess").on('activate', me.userTabSessActivate, me);
Ext.getCmp("userTabIP").on('activate', me.userTabIPActivate, me);

},


So, this code fails with ...
Ext.getCmp("userTabMgr") is undefined

I was hoping to place all the control logic in the controller. Now, it looks like I may have to setup the listeners inside the view code.

As arthurakay said:

so maybe it's an order-of-operations thing.
I think he's right. The controller is being called before anything is rendered.

lorezyra
11 Dec 2011, 8:31 PM
I don't believe this is the best way... and it's certainly not the best practice... but this did work. I'm not sure if this is a bug or not. The control method referenced in a child tab did not seem to fire the associated listener at all. The event *fired* but the function I registered did not run! I'm not sure if it's due to the fact the component was not rendered yet.



Ext.application({
name: 'RichieBartlett',
//appFolder: 'app',
controllers: ['adminUIviewport','usrMangerTAB'],
stores: [
// stores
],
launch: function() {
Ext.QuickTips.init();
if(Ext.isGecko && debug){ console.log(" RichieBartlett launch");}

try{bodyMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait... ロード中です。お待ちくださませ。"} );}catch(e){}

Ext.get('initLoadMask').remove();//delete the initLoadMask element

if(Ext.isGecko){ console.log(" adminUIviewport prep");}
try{
adminBASEview = Ext.create('RichieBartlett.view.adminUIviewport', {renderTo: Ext.getBody()});
adminBASEview.show();
if(Ext.isGecko && debug){ console.log(" adminUIviewport Rendered");}

Ext.getCmp("usrMangerTAB").on('afterrender', RichieBartlett.controller.usrMangerTAB.prototype.initUsrMangerTAB, RichieBartlett.controller.usrMangerTAB.prototype);

}catch(e){
if(Ext.isGecko && debug){ Ext.Error.raise(' adminUIviewport failed\n' + e.description);}
}



So, to work around the "bug," I simply created the on(afterrender) call within the main launch method.

lorezyra
11 Dec 2011, 8:45 PM
Has anyone else experienced this issue? Can you advise the best practice approach to handling nested tab.panel listeners?

arthurakay
12 Dec 2011, 8:39 AM
I'm glad that you found a work-around, although yes it is a bit of a hack.

Part of the problem you're running into is the fact you're relying on Ext.getCmp() - which necessitates that the components already exist in memory.

I would encourage you to get rid of as many of those references as possible - and instead use the controller to add listeners via "itemId" or some other component query.

lorezyra
12 Dec 2011, 6:04 PM
@arthurKey:
Thanks! Your hint about using itemId was the ticket I needed! This fixed my problem! Now, I don't have to use my hack to get things working! :D




Ext.define('RichieBartlett.controller.usrMangerTAB', {
extend: 'Ext.app.Controller',
//stores:[''],
views:['usrMangerTAB'],
refs: [{
ref: 'UsrMangerTAB',
selector: 'usrMangerTAB'
}],

init:function(){
if(Ext.isGecko && debug) console.log(" usrMangerTAB.controllerInit()");
var me=this;
/*
me.application.on({//handle system-application wide events and calls here!!
'event': me.event,
scope: me
});
*/
me.control({
'[itemId=usrMangerTAB]':{ //tabPanel object
afterrender: me.initUsrMangerTAB,
scope: me
},{//...


Furthermore, the problem was indeed in the me.control() block. It seems I had a syntax error that wasn't obvious and this killed the setup for the listeners. I noticed how I removed the encapsulating parenthesis from the tab's afterrender block and everything started working.

arthurakay
13 Dec 2011, 6:13 AM
That was a tricky syntax error... wish I had seen that in the first place, could have saved us both some work :D

Happy coding!