PDA

View Full Version : Populate items of actioncolumn dynamically



kathy_s
16 Dec 2011, 1:27 AM
Hi,
I am trying to make it possible to populate the items of the actioncolumn dynamically.
I extend the actioncolumn and in the constructor I add the items, but they are not shown in the grid.
Can anyone tell me what I'm doing wrong?



Ext.define('my.ActionColumn', {
extend: 'Ext.grid.column.Action',

width: 90,
hideable: false,
sortable: false,

editAction: false,
editIndex: 0,

copyAction: false,
copyIndex: 1,


constructor: function(config) {
var items = this.getActions();
config.items = items;
this.callParent(config);//Calling the parent class constructor
},

getActions: function() {
var items = new Array();
var editItem;
var copyItem;

if(this.editAction) {alert(editAction);
editItem = {
iconCls:'icon-action-edit-record',
tooltip: '<b>Edit</b><BR>Edit the selected record',
handler: function(grid, rowIndex, colIndex) {
this.editFunction.call(this, grid, rowIndex);
}
};
items[this.editIndex] = editItem;
}

if(this.copyAction){
copyItem = {
iconCls:'icon-action-copy-record',
tooltip: '<b>Copy</b><BR>Copy the selected record',
handler: function(grid, rowIndex, colIndex) {
this.copyFunction.call(this, grid, rowIndex);
}
};
items[this.copyIndex] = copyItem;
}
return items;
}
});


var myColumn = Ext.create('my.ActionColumn', {
editAction: true,
editFunction: edit,
editIndex: 0,
copyAction: true,
copyFunction: copy,
copyIndex: 1
});

Ext.create('Ext.grid.Panel', {
border:false,
store: g_clFolderStore,
columnLines: true,
stripeRows: true,
viewConfig: {
stripeRows: true
},
columns: [
new Ext.grid.RowNumberer(),
myColumn,

...

});


Thanks!
Kathy

tvanzoelen
16 Dec 2011, 1:51 AM
I think your vars like editAction, copyAction are still false because you don;t set the new values in the constructor explicitly.

Try



constructor: function(config) {
var items = this.getActions();
config.items = items;
this.copyAction = config.copyAction;
this.editAction = config.editAction;
this.callParent(config);//Calling the parent class constructor
},

kathy_s
16 Dec 2011, 2:05 AM
Thanks for the quick response!
Those variables are correctly configured when I create my actioncolumn:



var myColumn = Ext.create('my.ActionColumn', {
editAction: true,
editFunction: edit,
editIndex: 0,
copyAction: true,
copyFunction: copy,
copyIndex: 1
});

I tested this and the getActions method fills up the items correctly).

kathy_s
16 Dec 2011, 2:25 AM
Ignore my previous post. You were right, the configuration that I provide during creation isn't picked up.
Can you explain me why?

But even when I change them to true it stil doesn't show anything.
Any other suggestions?

tvanzoelen
16 Dec 2011, 2:39 AM
I tried this. And then I get an alert. The properties were not set, maybe because you called getActions before aplying the config on the parent.

I am missing data to test myself, but the icons should appear in the rows below that column. See http://docs.sencha.com/ext-js/4-0/#!/example/grid/array-grid.html for an example.

there is a getClass method there, maybe you need to implement it.



Ext.onReady(function() {

Ext.define('my.ActionColumn', {
extend: 'Ext.grid.column.Action',

width: 90,
hideable: false,
sortable: false,

editAction: false,
editIndex: 0,

copyAction: false,
copyIndex: 1,


constructor: function(config) {


this.editAction = config.editAction;
this.copyAction = config.copyAction;


this.editFunction = config.editFunction;
this.editIndex = config.editIndex;
this.copyFunction = config.copyFunction;
this.copyIndex = config.copyIndex;

var items = this.getActions();
config.items = items;

this.callParent(config); //Calling the parent class constructor
},

getActions: function() {
var items = new Array();
var editItem;
var copyItem;

if (this.editAction) {
alert(this.editAction);
editItem = {
iconCls: 'icon-action-edit-record',
tooltip: '<b>Edit</b><BR>Edit the selected record',
handler: function(grid, rowIndex, colIndex) {
this.editFunction.call(this, grid, rowIndex);
}
};
items[this.editIndex] = editItem;
}

if (this.copyAction) {
copyItem = {
iconCls: 'icon-action-copy-record',
tooltip: '<b>Copy</b><BR>Copy the selected record',
handler: function(grid, rowIndex, colIndex) {
this.copyFunction.call(this, grid, rowIndex);
}
};
items[this.copyIndex] = copyItem;
}
return items;
}
});


var myColumn = Ext.create('my.ActionColumn', {
editAction: true,
editFunction: function() { alert('edit'); },
editIndex: 0,
copyAction: true,
copyFunction: function() { alert('copy'); },
copyIndex: 1
});

Ext.create('Ext.grid.Panel', {
border: false,
columnLines: true,
stripeRows: true,
viewConfig: {
stripeRows: true
},
renderTo: Ext.getBody(),
columns: [
new Ext.grid.RowNumberer(),
myColumn
]
});


});

kathy_s
16 Dec 2011, 3:01 AM
The config that I pass during creation is now picked up correctly. Thanks for that!
But the icons are still not shown. Even if I replace in the constructor:


var items = this.getActions();

with:


var items = [{
iconCls:'icon-action-edit-record',
tooltip: '<b>Edit</b><BR>Edit the selected record',
handler: function(grid, rowIndex, colIndex) {
this.editFunction.call(this, grid, rowIndex);
}
},{
iconCls:'icon-action-copy-record',
tooltip: '<b>Copy</b><BR>Copy the selected record',
handler: function(grid, rowIndex, colIndex) {
this.copyFunction.call(this, grid, rowIndex);
}
}];



Only if I add the items during creation, they are shown correctly.
Any more suggestions?

tvanzoelen
16 Dec 2011, 4:06 AM
In the example I see that icon is set directly and the class name is returned on condition.

Create a getClass function in your ActionColum. Check the record and return the corresponding class.
In your case icon-action-edit-record or icon-action-copy-record.

The icon gif you give directly to the ActionCololmn item.

like

icon:'icon-action-edit-record.png'


Also see http://docs.sencha.com/ext-js/4-0/#!/example/grid/array-grid.html




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) {
this.items[1].tooltip = 'Hold stock';
return 'alert-col';
} else {
this.items[1].tooltip = 'Buy stock';
return 'buy-col';
}
},
handler: function(grid, rowIndex, colIndex) {
var rec = store.getAt(rowIndex);
alert((rec.get('change') < 0 ? "Hold " : "Buy ") + rec.get('company'));
}
}]

kathy_s
16 Dec 2011, 5:18 AM
I saw that example as well, but what I am doing is different.
In the example the class changes depending on a record value. I want to change the items depending on a config value.
The reason that I was not using a 'icon' is that I put my url of the icon in the css class as a background image (which works fine in the actioncolumns that are not populated dynamically).

Anyway, I tried it with the getClass(), like you suggested, but that didn't work.
And now I'm not using an iconCls, but only an icon, but that doesn't work either.

The strange thing is that when I put exactly the same items hardcoded in 'items: ...' while creating the column, that everything works fine. I really don't understand what is the difference.

my current code of the actioncolumn:


Ext.namespace('my');

Ext.define('my.ActionColumn', {
extend: 'Ext.grid.column.Action',

width: 90,
hideable: false,
sortable: false,
editAction: false, // default is false
editIndex: 0,
copyAction: false, // default is false
copyIndex: 1,


constructor: function(config) {
this.editAction = config.editAction;
this.copyAction = config.copyAction;
this.editFunction = config.editFunction;
this.editIndex = config.editIndex;
this.copyFunction = config.copyFunction;
this.copyIndex = config.copyIndex;

var items = this.getActions();

config.items = items;
this.callParent(config);//Calling the parent class constructor
},

getActions: function() {
var items = new Array();

if(this.editAction) {
items[this.editIndex] = {
icon: '../icons/table_edit.png',
//iconCls:'icon-action-edit-record',
tooltip: '<b>Edit</b><BR>Edit the selected record',

handler: function(grid, rowIndex, colIndex) {
this.editFunction.call(this, grid, rowIndex);
}
};
}

if(this.copyAction){
items[this.copyIndex] = {
icon: '../icons/table_multiple.png',
//iconCls:'icon-action-copy-record',
tooltip: '<b>Copy</b><BR>Copy the selected record',

handler: function(grid, rowIndex, colIndex) {
this.copyFunction.call(this, grid, rowIndex);
}
};
alert(items.length);
}
return items;
}
});

tvanzoelen
16 Dec 2011, 6:25 AM
Its in the constructor then. The items are not configured the rightway.

There are multiple ways to do it.

Try



constructor: function(config) {
this.editAction = config.editAction;
this.copyAction = config.copyAction;
this.editFunction = config.editFunction;
this.editIndex = config.editIndex;
this.copyFunction = config.copyFunction;
this.copyIndex = config.copyIndex;

var items = this.getActions();

config.items = items;

this.callParent(arguments);//Calling the parent class constructor
this.initConfig(config);
return this;
},


or


,constructor:function(config) {
var me=this;

this.editAction = config.editAction;
this.copyAction = config.copyAction;
this.editFunction = config.editFunction;
this.editIndex = config.editIndex;
this.copyFunction = config.copyFunction;
this.copyIndex = config.copyIndex;

var items = this.getActions();
config.items = items;

me.setConfig(config);
me.callParent(arguments);
return me;
}


Sencha made mulitple way to extends new classes. Items can also be set in initComponent with Ext.apply

In any way. In the constructor, you do callParent with arguments. do a setConfig or a call to initConfig. And return itself.

kathy_s
16 Dec 2011, 7:15 AM
I tried out both code snippets, but I get the same error in both cases:

this.el is undefined
return this.el.getWidth();

Any ideas where this is coming from?

tvanzoelen
16 Dec 2011, 7:31 AM
Do not know. Then I need some code were I can test it with data.

kathy_s
19 Dec 2011, 1:47 AM
It works!
I made a small change in the constructor and now it works fine :

constructor: function(config) {
var me=this;

this.editAction = config.editAction;
this.copyAction = config.copyAction;
this.editFunction = config.editFunction;
this.editIndex = config.editIndex;
this.copyFunction = config.copyFunction;
this.copyIndex = config.copyIndex;

var items = this.getActions();
config.items = items;

//me.setConfig(config);
//me.callParent(arguments);
me.callParent([config]);

return me;

},



Thanks for all your usefull answers! Being new to extjs, it would have taken me ages to figure this out on my own.