There's a very easy way to do this since Handsontable was built with this use case in mind!
You want to use a customRenderer
option of your cells
attribute. It will apply the renderer to all your matching cells and do some fun stuff inside the renderer. Here is how:
Start by defining the renderer:
function customRender(instance, td, row, col, prop, value, cellProperties) {
// change to the type of renderer you need; eg. if this is supposed
// to be a checkbox, use CheckboxRenderer instead of TextRenderer
Handsontable.renderers.TextRenderer.apply(this, arguments);
// get the jquery selector for the td or add the class name using native JS
$(td).addClass("error");
return td;
}
As you see, this will apply the class to every td
that you give this renderer to. Now it's just a matter of giving it to the right cells. You do that by adding the cells
attribute:
var hot = new Handsontable(container, {
data: data,
cells: function(row, col, prop) {
var cellProperties = {};
if (row === 0, col === 0) {
cellProperties.renderer = customRender; // uses function directly
}
}
});
What you end up doing is defining the renderer on whichever cell you want. Now of course this will just add it on render and not dynamically. For that you can use a second method similar to this.
Your click
event could do two things:
1) recalculate the cells
option and update them
This one is easy and follows the example from above. You would want to modify cells
to apply the renderer to whichever cells you want to add the class name to. After that, you just do:
hot.updateSettings({cells: newCellObject});
And that's it.
A second, more interesting option, is to define the custom renderer on EVERY cell. If you do this, then you want to add the logic of which cells to add the class name to inside this renderer function; this is possible because the renderer takes as inputs the row and column positions so you can do the following:
// to do a fast search, use this hack to turn the array into strings
var globalErrorCells = [[1,2]+'', [0,0]+''];
function customRender(instance, td, row, col, prop, value, cellProperties) {
// change to the type of renderer you need; eg. if this is supposed
// to be a checkbox, use CheckboxRenderer instead of TextRenderer
Handsontable.renderers.TextRenderer.apply(this, arguments);
// we check if this cell is in our global array of cells to include
if (globalErrorCells.indexOf([row, col] + '')) {
// get the jquery selector for the td or add the class name using native JS
$(td).addClass("error");
}
return td;
}
And that's it! Every time you want to add a cell to have the class name added to, push the cell coordinates to that global array and handsontable will automatically render it correctly next time you render. Something like this:
// assume we're inside the click
var cell = [1,2]+''
globalErrorCells.push(cell);
hot.render();
And same goes for removing the class name, just search for the cell to remove and get rid of it from the globalErrorCells
array.
I hope that made sense! One last comment. If you're trying to do validation, I would recommend reading the section on validators on the Handsontable page. You can do a similar thing with the cells
option to pass in a validator function. This gets applied on render to all your cells and if it fails the validation, it automatically adds a class to that cell which you can then use CSS to change :D