triplethreat77
triplethreat77

Reputation: 1296

Handsontable change colors of cells/rows/columns with color picker?

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

Answers (1)

McCroskey
McCroskey

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.

JSFiddle

Upvotes: 1

Related Questions