Checkboxes in only some rows
I'm in the process of transitioning our app from V1.0 to 2.0 and we would like to use the new Checkbox widget, but we've run into a little snag.
We need a checkbox in a single column, but for only certain rows, to be determined by a function that examines the data that gets put into the rows. So far it appears to me that the only way to create checkboxes is via setCellTemplate() and the only examples I've seen are similar to:
grid.setCellTemplate(new AW.Templates.Checkbox, 0);
This creates a box in each row, but it seems that setCellTemplate() won't accept a callback function to determine which rows get checkboxes and which don't.
Does anyone have any ideas?
Thanks,
Jesse
Jesse
March 1,
try this:
grid.setCellTemplate(new AW.Templates.Checkbox, COL, ROW)
Jim Hunter (www.FriendsOfAW.com)
March 1,
It slows down the initial render of 500 rows, but that did the trick. Thanks Jim.
Jesse
March 2,
It looks like the render time for 500+ rows is a lot slower than I initially suspected when using
grid.setCellTemplate(new AW.Templates.Checkbox, 0, i);
I just call this once for each row, if the row data meets a particular condition. If only a handful meet the condition, the grid doesn't seem to take any longer to render than without calling setCellTemplate(), but if a large percentage of the rows meets the condition (which happens), then the render time goes from about 0.5 seconds to about 3.5 in IE! Firefox doesn't seem to have any problem with it though. Any thoughts?
Jesse
March 3,
I am assuming that the checkboxes are going to be limitted to one column, possible two. I would suggest that you go ahead and render the grid normally, the use setTimeout() to itterate over each row and check your target cell to see if it has the correct value, if yes, then set the cell template to be the checkbox, if not move on. This should show the grid very quickly and then only take a tiny amount of time to 'update' the grid with checkboxes if needed.
obj.setTimeout(function() {
for (var x=0; x< this.getRowCount();x++)
{
if (this.getCellText(COL, x) == "test value")
this.setCellTemplate(new AW.Templates.Checkbox, COL, x);
}
}, 100);
or something like that. Replace COL with the column number you are testing against, and change the test itself to meet your requirements. I was doing that 'off-the-cuff' so it may need some editing/polishing. But that should be faster then what you were trying, or at least it will 'appear' faster to the user and as we all know, that is the most important thing.
Jim Hunter (www.FriendsOfAW.com)
March 3,
Thanks for the reply. You're solution is almost there -- the response time is snappier, but for some reason the grid doesn't render the checkboxes in the rows in the current view, though it does render those outside it just fine (the bottom row in my view shows the checkbox, for some reason). I've noticed this strange behavior before, when I was experimenting with other possible solutions to this checkbox problem. Any idea why this is?
Jesse
March 3,
Issue a refresh() after you assign all of the checkboxes. I had thought about that after I submitted the response. Refresh should display them, and that is a gird.refresh() not a cell refresh.
Jim Hunter (www.FriendsOfAW.com)
March 3,
Perfect, that did it. There's still a 3s delay between initial display and the refresh, but that's to be expected under the circumstances. Thanks!
Btw, any speculation as to why IE is hit so much harder than Firefox when setting the cell templates individually?
Jesse
March 3,
Jesse,
here is one more way of doing this - I guess this is what you mean in your original question (how to use a dynamic function instead of template). The problem is when you put a function instead of a template - this function still has to return a template (unless it is a plain html), so the template must be defined elsewhere (and configured properly). So this is actually a bit complicated.
I hope this will be a faster method but I did not check, frankly.
var obj = new AW.UI.Grid;
obj.setSize(800, 250);
obj.setCellText(function(i, j){return j + "-" + i});
obj.setHeaderText("header");
obj.setColumnCount(10);
obj.setRowCount(100);
function configureCellTemplate(cell){
cell.setAttribute("aw", "cell");
cell.setAttribute("title", "");
cell.setClass("grid", "cell");
cell.setClass("column", function(){return this.$0});
cell.setClass("cells", function(){return this.getControlProperty("state") || "normal"});
cell.mapModel("control", "cell");
cell.getStateProperty = function(p){return this.$owner.getRowProperty(p, this.$1)};
cell.setStateProperty = function(p, v){this.$owner.setRowProperty(p, v, this.$1)};
};
obj.onCellNormalTemplateChanged = configureCellTemplate;
obj.onCellCheckboxTemplateChanged = configureCellTemplate;
obj.onCellTemplateChanged = function(){return true};
obj.defineTemplate("cellNormal", new AW.Templates.Text);
obj.defineTemplate("cellCheckbox", new AW.Templates.Checkbox);
obj.setCellTemplate(function(col, row){
if (col == 1 && row % 2) {
return this.getCellCheckboxTemplate(col, row);
}
else {
return this.getCellNormalTemplate(col, row);
}
});
document.write(obj);
Alex (ActiveWidgets)
March 3,
Alex
I am interesting in using the above, but I'm unsure how to set a conditional in the "obj.setCellTemplate(function(col, row){" part.
In my case I need the checkbox to appear in a column where another column has certain value; in other words I need "row" in your line "if (col == 1 && row % 2) {" to return rows only when this condition is true.
Any help on how to do this would be greatly appreciated.
Thanks as always
Will
Will
July 5,
Will, you can try this way,
(any row that contains 'x3-xx' in column 2 shows a checkbox in col 1)
if ( col == 1 && this.getCellText( 2 , row).indexOf('3-') > -1 ) {
Carlos
July 5,
Yes, Carlos that worked.
Many thanks.
Will
Will
July 6,
I'm trying to follow Alex's example above and the middle section of code might as well be Greek to me. I try finding references in the documentation to some of these calls but there's no search capability other than the forum and it's difficult to try and understand what's happening and how to change it.
What I want to do is have the checkboxes unchecked or checked initially (not the mixed) based on the text value in the cell and have the checkbox be the only item in the cell, replacing the text. Or maybe have a hidden column that contains the value to check so that the cell that's going to get the checkbox is empty initially.
How would I change the example to accomplish what I need? Thanks in advance.
Jeff C.
November 10,