Reputation: 1296
I have an example of color change already happening. The issue is that changing the color of a new cell, row, or column will change the color of the previous cell/row/column. The previous cell should keep it's original color, and I need this to happen dynamically with one function (rather than multiple renderers). In the fiddle there are 3 color options, but I'm actually using a color picker with hundreds of options. How can I handle this color change on the fly (right click)?
http://jsfiddle.net/anschwem/hkhk5zbo/17/
var data = [
['', 'Maserati', 'Mazda', 'Mercedes', 'Mini', 'Mitsubishi'],
['2009', 0, 2941, 4303, 354, 5814],
['2010', 3, 2905, 2867, 412, 5284],
['2011', 4, 2517, 4822, 552, 6127],
['2012', 2, 2422, 5399, 776, 4151]
],
celldata = [],
container = document.getElementById('example'),
hot,
sentrow,
sentcol;
var colorRenderer = function (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = $('#color_field').val();
};
var settings = {
data: data,
minSpareRows: 1,
rowHeaders: true,
colHeaders: true,
contextMenu: true,
startRows: 5,
startCols: 5,
//columns: coldata,
cell: celldata,
cells: function (row, col, prop) {
if (row === sentrow) {
this.renderer = colorRenderer;
}
if (col === sentcol) {
this.renderer = colorRenderer;
}
},
};
hot = new Handsontable(example, settings);
hot.updateSettings({
contextMenu: {
callback: function (key, options) {
if (key === 'cellcolor') {
setTimeout(function () {
//timeout is used to make sure the menu collapsed before alert is shown
var row = hot.getSelected()[0];
var col = hot.getSelected()[1];
var item = {};
item.row = row;
item.col = col;
item.renderer = colorRenderer
celldata.push(item)
hot.updateSettings({cell: celldata});
hot.render();
}, 100);
}
if (key === 'rowcolor') {
setTimeout(function () {
//timeout is used to make sure the menu collapsed before alert is shown
var row = hot.getSelected()[0];
sentrow = row;
hot.render();
}, 100);
}
if (key === 'colcolor') {
setTimeout(function () {
//timeout is used to make sure the menu collapsed before alert is shown
var col = hot.getSelected()[1];
sentcol = col;
hot.render();
}, 100);
}
},
items: {
"cellcolor": {
name: 'Cell color'
},
"rowcolor": {
name: 'Row color'
},
"colcolor": {
name: 'Column color'
},
}
}
})
Upvotes: 0
Views: 10664
Reputation: 1161
EDIT: Refactored the code for clarity.
The color was being changed by subsequent calls because your colorRenderer callback was interrogating the dropdown every time it rendered, rather than capturing the value at the time of the cell style creation.
$(document).ready(function () {
var data = [
['', 'Maserati', 'Mazda', 'Mercedes', 'Mini', 'Mitsubishi'],
['2009', 0, 2941, 4303, 354, 5814],
['2010', 3, 2905, 2867, 412, 5284],
['2011', 4, 2517, 4822, 552, 6127],
['2012', 2, 2422, 5399, 776, 4151]
];
var container = document.getElementById('example');
// Put your color picker function here
function getSelectedColor() {
return $('#color_field').val();
}
var TableStyles = function(hot) {
var self = this;
var _cellStyles = [];
var _createStyle = function(row, col, color) {
var _color = color;
var style = {
row: row,
col: col,
renderer: function (instance, td, row, col, prop, value, cellProperties) {
Handsontable.renderers.TextRenderer.apply(this, arguments);
td.style.backgroundColor = _color;
},
color: function(c) { _color = c; }
};
return style;
};
self.getStyles = function() {
return _cellStyles;
};
self.setCellStyle = function(row, col, color, updateTable) {
var _color = color;
if (_cellStyles.length == 0) {
_cellStyles.push(_createStyle(row, col, color));
} else {
var found = _cellStyles.some(function(cell) {
if (cell.row == row && cell.col == col) {
cell.color(color);
return true;
}
});
if (!found) {
_cellStyles.push(_createStyle(row, col, color));
}
}
if (updateTable!=false) {
hot.updateSettings({cell: self.getStyles()});
hot.render();
};
};
self.setRowStyle = function(row, color) {
for (var col=0; col<hot.countCols(); col++)
self.setCellStyle(row, col, color, false);
hot.updateSettings({cell: self.getStyles()});
hot.render();
};
self.setColStyle = function(col, color) {
for (var row=0; row<hot.countCols(); row++)
self.setCellStyle(row, col, color, false);
hot.updateSettings({cell: self.getStyles()});
hot.render();
};
};
var settings = {
data: data,
minSpareRows: 1,
rowHeaders: true,
colHeaders: true,
contextMenu: true,
startRows: 5,
startCols: 5,
cell: []
};
hot = new Handsontable(container, settings);
var styles = new TableStyles(hot);
hot.updateSettings({
contextMenu: {
callback: function (key, options) {
if (key === 'cellcolor') {
setTimeout(function () {
var sel = hot.getSelected();
styles.setCellStyle(sel[0], sel[1], getSelectedColor());
}, 100);
}
if (key === 'rowcolor') {
setTimeout(function () {
//timeout is used to make sure the menu collapsed before alert is shown
var sel = hot.getSelected();
styles.setRowStyle(sel[0], getSelectedColor());
}, 100);
}
if (key === 'colcolor') {
setTimeout(function () {
//timeout is used to make sure the menu collapsed before alert is shown
var sel = hot.getSelected();
styles.setColStyle(sel[1], getSelectedColor());
}, 100);
}
},
items: {
"cellcolor": {
name: 'Cell color'
},
"rowcolor": {
name: 'Row color'
},
"colcolor": {
name: 'Column color'
},
}
}
})
});
The TableStyles object provides a wrapper around the raw cell style array that Handsontable is expecting, so that you cal just call styles.setCellStyle(row, col, color) and it will take care of creating or updating the cell array for you.
Upvotes: 1