PDA

View Full Version : column Renderer scope issue



abhaykulkarni16
29 Oct 2009, 9:30 PM
I have an already created grid with a column model without any renderers. Now, I want to set custom coloring renderer to each of the columns based on some criteria. for that matter, i have a colors array created which has all the colors to paint with.
In a function somewhere in the grid component i am assigning the renderer to a column like this...




var colors = this.colors;
cm.setRenderer(colNo, function(v,a,b,c,d,e,colors){
var clr = "";
var ret = "";
if(v != 'NA'){
if(v < 0)
clr = colors[menuNo][0];
else if(v > 0 && v < 1000)
clr = colors[menuNo][1];
else
clr = colors[menuNo][2];
ret = '<span style="color:'+clr+';">' + v + ' days' + '</span>';
} else {
clr = '#000000';
ret = '<span style="color:'+clr+';">' + v + '</span>';
}
return ret;
});
here, the colors variable is initialized when this function is called. but when the renderer fn starts executing firebug gives me an error like "colors is undefined". menuNo is a variable i will be passing to the renderer in the same manner like colors. I m afraid its also going to give me similar error for it.
I completely understand that this is because of the scope issue. But i need a solution to this problem. Any help is deeply appreciated. :)

Animal
29 Oct 2009, 10:26 PM
It's not the scope of the renderer. You are assigning colors outside the renderer.

colors is initialized at the time the setRenderer call is made. WHat is "this" at that time? Obviously it has no colors property.

abhaykulkarni16
29 Oct 2009, 11:27 PM
You are right Animal. "this" at that time is the current column and it has no 'colors' defined.
In fact, that's what the problem seems to be. I am not able to get the scope of the gridComponent to which the 'color' is set.
Using a global var for color resolves the issue but that's not the EXT's way to do it...
Is there any way such that i will be able to have components' (here gridComponent's) scope visible inside renderer function so that i (even we) can use specific component configs and properties for rendering them?

Animal
30 Oct 2009, 12:05 AM
You need to show code. I have no idea what is where.

abhaykulkarni16
30 Oct 2009, 12:49 AM
initColorsForRendering: function(){
var clrs = new Array(this.colHeader.length);
for(var i = 0; i<this.colHeader.length; i++){
clrs[i] = new Array(3);
clrs[i][0] = '#FFCB0D';
clrs[i][1] = '#439941';
clrs[i][2] = '#E73030';
}
this.colors = clrs;
},

setRendererForDuration: function(){
var colors = this.colors;
cm.setRenderer(colNo, function(v,a,b,c,d,e,colors){
var clr = "";
var ret = "";
if(v != 'NA'){
if(v < 0)
clr = colors[menuNo][0];
else if(v > 0 && v < 1000)
clr = colors[menuNo][1];
else
clr = colors[menuNo][2];
ret = '<span style="color:'+clr+';">' + v + ' days' + '</span>';
} else {
clr = '#000000';
ret = '<span style="color:'+clr+';">' + v + '</span>';
}
return ret;
});
}
As you can see, these functions are set for my grid component. and in the 1st one i set this.colors.

What i want is, to color column values according to colors set in this.colors array, which by far(i have some idea why) is not accessible inside the renderer function.

Animal
30 Oct 2009, 1:19 AM
Calculate your colours in the constructor as soon as you've called the superclass constructor.

That way, they will be defined at the time setRendererForDuration is executed. Looks like you just have not called initColorsForRendering in time. There's no reason to delay calculating your colours.

abhaykulkarni16
30 Oct 2009, 8:45 PM
Sorry for replying late Animal,

I tried your way and called the init fun right after the constructor. but... (Now i thinking like either you are not getting what i m saying or i m not able to tell you properly...)

See, whether or not this.colors or "colors" local to that fun is getting initialized or not, look at what i am doing in that fun... I m assiging a renderer to a column...

The lives and times of executions of setRendererForDuration and the actual renderer fun are going to be different. (and i know that) what i m trying is to pass a user defined variable to the renderer fun along with the default params(in generic sense).

The problem exactly is that the variables are set in component's scope. while as the renderer function does know nothing about it.

Again, the renderer might be called each time the GridView is refreshed. but the setRendererForDuration will not be as it is grid's.

(i might be offending you, but) Have you got any idea about what i m saying as yet...?

(OK, the solution i found was to make color variable global so that it's accessible... but then is that the correct and native way? or just a workaround?...)

abhaykulkarni16
1 Nov 2009, 8:54 PM
Does anyone have the correct answer for this?

vitalets
17 Apr 2011, 2:26 AM
Hi All

the solution I found for this issue is to make simple override and automatically add link to grid.
So, grid is accessible inside renderer via this.grid


Ext.override(Ext.grid.GridView, {
getColumnData: function() {

var columns = [],
colModel = this.cm,
colCount = colModel.getColumnCount(),
fields = this.ds.fields,
i, name;

for (i = 0; i < colCount; i++) {
name = colModel.getDataIndex(i);

// adds link to grid inside renderer
colModel.config[i].grid = this;

columns[i] = {
name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
renderer: colModel.getRenderer(i),
scope : colModel.getRendererScope(i),
id : colModel.getColumnId(i),
style : this.getColumnStyle(i)
};
}

return columns;
}
});