PDA

View Full Version : Struggling with scope..



rijkvanwel
11 Feb 2011, 5:46 AM
Hi all,

I'm sorry to bother you with such a noob question, but I've spent the last 4 hours reading articles and tutorials and I still can't figure this out.

I have a grid with a toolbar, for that I've basically copied the "Grid3 Grouping" example and added some stuff. Most importantly, a button with a menu, which I want to use to present different views to the user. I put that in the top bar:



tbar: new Ext.Toolbar({
items: [
{
text: 'View: Importance',
tooltip: {title:'Select view',text:'Select one of the customized views for more insight.'},
menu:{
items: [{
text: 'Importance',
checked: true,
group:'actview',
checkHandler: function(){console.log(this)},
iconCls: 'preview-bottom'
},{
text: 'Due date',
checked: true,
group:'actview',
checkHandler: function(){
console.log(this);
this.getTopToolbar().items.get(1).text = 'whatever';
},
iconCls: 'preview-bottom'
}]
}
},
'->' ]
}),


However, 'this' keeps changing, depending on the situation. Now I've learned that it will be set to the object triggering the event, unless you bind it to something else (using the scope parameter of the menu item, right?). However, when I set 'scope' to 'this', the console.log will say this is the DOM Window.. I think that's because the grid is created like this:


var ActivityGrid = new Ext.grid.GridPanel({

.. and the toolbar is built up in this same statement.

Now the question: I would like to have a method of ActivityGrid, like changeView(), be the changeHandler of the menu items. How do I do that?? I can't find out how to access the right object. When I try to do 'changeHandler: ActivityGrid.changeView,', it triggers an error since ActivityGrid is still undefined at that point. But I also can't use the 'this' to traverse up the hierarchy, and do it that way.

I'm sorry if this is a stupid question, I'm just trying to really understand this stuff you know! :)

Edit 11/02 15:22: I've managed to do do a call to a function - but it's not a very pretty solution.. Is there a better way to do it??


// ...
tbar: new Ext.Toolbar({
items: [
{
text: 'View: Importance',
tooltip: {title:'Select view',text:'Select one of the customized views for more insight.'},
menu:{
items: [{
text: 'Importance',
checked: true,
group:'actview',
checkHandler: function(){
ActivityGrid.changeView( arguments[0], arguments[1] );
},
iconCls: 'preview-bottom'
},{
text: 'Due date',
checked: true,
group:'actview',
checkHandler: function(){
ActivityGrid.changeView( arguments[0], arguments[1] );
},
iconCls: 'preview-bottom'
},{
text: 'Types',
checked: true,
group:'actview',
checkHandler: function(){
ActivityGrid.changeView( arguments[0], arguments[1] );
},
iconCls: 'preview-bottom'
},{
text: 'Goals',
checked: true,
group:'actview',
checkHandler: function(){
ActivityGrid.changeView( arguments[0], arguments[1] );
},
iconCls: 'preview-bottom'
}]
}
},
'->' ]
}),
changeView: function( m, pushed ) {
if ( pushed ) {
this.getTopToolbar().items.get(0).setText( 'View: ' + m.text );
}
},
renderTo: document.body
});

johnathanhebert
11 Feb 2011, 6:00 AM
Since your toolbar button uses a tooltip, you have to initialize QuickTips... call this at the beginning of your code:

Ext.QuickTips.init();

rijkvanwel
11 Feb 2011, 6:10 AM
Sorry, I haven't posted the whole script. QuickTips are initialized, and I don't get any JS errors or anything. Just the scope issue.

However, I've found a forum thread (http://www.sencha.com/forum/showthread.php?107156-Grid-Toolbar-Button-scope!-(Again-I-know-but-I-m-really-struggling)) that finally helped me out a little bit. I've now managed to change the button's text onchange, might be able to work this out into a method call..



checkHandler: function(){
// of course, ActivityGrid ís defined at the time the event is fired!
ActivityGrid.getTopToolbar().items.get(0).setText('whatever');
},

rijkvanwel
11 Feb 2011, 6:12 AM
Here's the complete code:



/*!
* Ext JS Library 3.3.1
* Copyright(c) 2006-2010 Sencha Inc.
* [email protected]
* http://www.sencha.com/license
*/
Ext.onReady(function(){

Ext.QuickTips.init();

// shared reader
var reader = new Ext.data.ArrayReader({}, [
{name: 'activity_id'},
{name: 'title'},
{name: 'description'},
{name: 'type'},
{name: 'urgency'},
{name: 'importance'},
{name: 'dueDate', type: 'date', dateFormat: 'd/m/Y'},
]);

var store = new Ext.data.GroupingStore({
reader: reader,
data: Ext.grid.dummyData,
sortInfo:{field: 'type', direction: "ASC"},
groupField:'importance'
});

var ActivityGrid = new Ext.grid.GridPanel({
store: store,
columns: [
//{header: "", width: 10, sortable: false},
//{header: "Activity", width: 60, sortable: true, dataIndex: 'company'},
{header: "Activity", width: 80, sortable: true, groupable: false, dataIndex: 'title'},
{header: "Description", width: 120, sortable: false, groupable: false, dataIndex: 'description'},
{header: "Type", width: 20, sortable: true, dataIndex: 'type'},
{header: "Urgency", width: 15, sortable: true, dataIndex: 'urgency'},
{header: "Importance", width: 35, sortable: true, dataIndex: 'importance'},
{header: "Due Date", width: 30, sortable: true, groupable: false, renderer: Ext.util.Format.dateRenderer('d/m/Y'), dataIndex: 'dueDate'},
{
xtype: 'actioncolumn',
width: 25,
items: [{
//icon : '../../../wrench.png', // Use a URL in the icon config
iconCls: 'icon-edit',
tooltip: 'Edit activity properties (review)',
handler: function(grid, rowIndex, colIndex) {
alert("Edit activity");
}
}, {
iconCls: 'icon-delete',
tooltip: 'Remove activity',
handler: function(grid, rowIndex, colIndex) {
alert("Are you sure you want to remove the activity from your records? If you're just done doing the activity, please use the 'mark as complete' button.");
}
}, {
iconCls: 'icon-complete',
tooltip: 'Mark activity as complete',
handler: function(grid, rowIndex, colIndex) {
alert("Done with activity");
}
}]
}
],

view: new Ext.grid.GroupingView({
forceFit:true,
groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "items" : "item"]})'
}),

frame: false,
enableHdMenu: false,
enableColumnMove: false,
width: 850,
height: 450,
//collapsible: true,
animCollapse: false,
// title: 'Grouping Example',
iconCls: 'icon-grid',
// fbar : ['->', {
// text:'Clear Grouping',
// iconCls: 'icon-clear-group',
// handler : function(){
// store.clearGrouping();
// }
// }],
plugins: [
new Ext.ux.grid.Search({
mode: 'local',
position: 'top',
width: 200,
searchText: 'Filter:',
readonlyIndexes: [],
disableIndexes: [],
minChars: 2
})
],
tbar: new Ext.Toolbar({
items: [
// { xtype: 'tbtext', text: 'Select view:' },
{
// split:true,
text: 'View: Importance',
tooltip: {title:'Select view',text:'Select one of the customized views for more insight.'},
// iconCls: 'preview-bottom',
menu:{
// id:'reading-menu',
// cls:'reading-menu',
items: [{
text: 'Importance',
checked: true,
group:'actview',
checkHandler: function(){console.log(this)},
iconCls: 'preview-bottom'
},{
text: 'Due date',
checked: true,
group:'actview',
checkHandler: function(){
//console.log(this);
console.log('setting', ActivityGrid.getTopToolbar().items.get(0), 'to whatever');
ActivityGrid.getTopToolbar().items.get(0).setText('whatever');
// console.log(ActivityGrid);
},
// checkHandler: this.changeView,
iconCls: 'preview-bottom'
},{
text: 'Types',
checked: true,
group:'actview',
// checkHandler: this.changeView,
iconCls: 'preview-bottom'
},{
text: 'Goals',
checked: true,
group:'actview',
// checkHandler: this.changeView,
iconCls: 'preview-bottom'
}]
}
},
'->' ]
}),
changeView: function( m ) {
alert('changing view to ' + m.text);
},
renderTo: document.body
});
});


// Array data for the grids
Ext.grid.dummyData = [
[1,'Soft Goals interface design','Yetta yetta','task','!!','<!--1-->very important','11/02/2011'],
[2,'KPN Merkactivatie module','Yetta yetta','project','!','<!--2-->important','15/02/2011'],
[3,'ABN GOR 2011','Yetta yetta','project','','<!--2-->important','18/02/2011'],
[4,'BusinessWise aanpassingen','Yetta yetta yetta','project','','<!--3-->normal',''],
[5,'ABF layout vragen','Yetta yetta yetta','task','!','<!--3-->normal',''],
[6,'Quaestio admin module','Code van de Quaestio admin omzetten naar een 5.8 module.','project','','<!--3-->normal','']
];

//// 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. Maecenas tortor turpis, interdum non, sodales non, iaculis ac, lacus. Vestibulum auctor, tortor quis iaculis malesuada, libero lectus bibendum purus, sit amet tincidunt quam turpis vel lacus. In pellentesque nisl non sem. Suspendisse nunc sem, pretium eget, cursus a, fringilla vel, urna.<br/><br/>Aliquam commodo ullamcorper erat. Nullam vel justo in neque porttitor laoreet. Aenean lacus dui, consequat eu, adipiscing eget, nonummy non, nisi. Morbi nunc est, dignissim non, ornare sed, luctus eu, massa. Vivamus eget quam. Vivamus tincidunt diam nec urna. Curabitur velit.');
//}

rijkvanwel
11 Feb 2011, 6:26 AM
Managed to do a function call - but not in a very elegent way.. :-? (see the edited first post)

johnathanhebert
11 Feb 2011, 6:45 AM
Since functions are object instances in javascript, you can just set the checkHandler config to the instance of the function you want it to call, and it will be called with the arguments that are passed to checkHandler... additionally, if you want to ensure that it runs in a particular scope, there is a method on the Function prototype called createDelegate that will allow you to specify the scope you want:

checkHandler:ActivityGrid.changeView.createDelegate(ActivityGrid)

That will call your changeView method where "this" will refer to the ActivityGrid

rijkvanwel
11 Feb 2011, 7:09 AM
Thanks! Good idea, however, I think I'm not able to use the ActivityGrid object at that point, since this is still all the in the definition of the grid.. So this would trigger an undefined error I think (unfortunately I'm not able to test ATM).

rijkvanwel
15 Feb 2011, 1:43 AM
Finally solved the puzzle with the help of these two tutorials:

http://www.sencha.com/learn/Tutorial:Application_Layout_for_Beginners
http://www.sencha.com/learn/Tutorial:Extending_Ext_Class