【问题标题】:Handsontable: Updating a cell renderer at runtimeHandsontable:在运行时更新单元格渲染器
【发布时间】:2016-02-10 15:37:21
【问题描述】:

我正在使用handsontable,如果单元格的值被编辑和更改,我想更改单元格的背景颜色。如果我的数据源是数组数组,我可以轻松做到这一点(参见小提琴:http://jsfiddle.net/chiman24/3o2c3c7m/)。

document.addEventListener("DOMContentLoaded", function() {

    // Row Styles
    var blank = function(instance, td, row, col, prop, value,
        cellProperties) {
        Handsontable.renderers.TextRenderer.apply(this, arguments);
        td.style.backgroundColor = '#ABAAAA'
    };

    var align = function(instance, td, row, col, prop, value,
        cellProperties) {
        Handsontable.renderers.TextRenderer.apply(this, arguments);
        td.style.verticalAlign = 'middle';
        td.style.fontWeight = 'bold';
    };

    var highlight1 = function(instance, td, row, col, prop, value,
        cellProperties) {
        Handsontable.renderers.TextRenderer.apply(this, arguments);
        td.style.backgroundColor = '#BDD7EE';
        td.style.textAlign = 'right';
    };

    var changedBackgroundColor = '#cbd9e4';
    var defaultBackgroundColor = 'white';
    var hasChanged = function(instance, td, row, col, prop, value,
        cellProperties) {
        Handsontable.renderers.TextRenderer.apply(this, arguments);
        td.style.backgroundColor = changedBackgroundColor;
    };
    var noChange = function(instance, td, row, col, prop, value,
        cellProperties) {
        Handsontable.renderers.TextRenderer.apply(this, arguments);
        td.style.backgroundColor = defaultBackgroundColor;
    };

    var data = [
            ["1", "Hear us from heaven", "New Life Worship",
                "Anderson, Jared", "something"
            ],
            ["2", "Spirit Break Out", "Kim Walker", "Walker, Kim",
                "Still Believe"
            ]
        ],
        dataCopy = [
            ["1", "Hear us from heaven", "New Life Worship",
                "Anderson, Jared", "something"
            ],
            ["2", "Spirit Break Out", "Kim Walker", "Walker, Kim",
                "Still Believe"
            ]
        ],
        container = document.getElementById('example1'),
        hot1;


    //Table Row and Col Options
    hot1 = new Handsontable(container, {
        data: data,
        fixedColumnsLeft: 1,
        columnSorting: true,
        colHeaders: ["id", "title", "artist", "author", "album"],
        columns: [{
            type: "text"
        }, {
            type: "text"
        }, {
            type: "text"
        }, {
            type: "text"
        }, {
            type: "text"
        }]
    });

    hot1.addHook('afterChange', afterChange);

    function afterChange(changes, source) {
        if (source == 'edit' || source == 'autofill') {
            $.each(changes, function(index, element) {
                var change = element;
                var rowIndex = change[0];
                var columnIndex = change[1];
                var oldValue = change[2];
                var newValue = change[3];
                var cellChange = {
                    'rowIndex': rowIndex,
                    'columnIndex': columnIndex
                };
                if (oldValue != newValue) {
                    var cellProperties = hot1.getCellMeta(
                        rowIndex, columnIndex);
                    if (newValue != dataCopy[rowIndex][
                            columnIndex
                        ]) {
                        cellProperties.renderer = hasChanged;
                    } else { //data changed back to original value.
                        cellProperties.renderer = noChange;
                    }
                    hot1.render();
                }
            });
        }
    }
});


// noSideScroll class added to fix some containers while side scrolling the table
$(window).scroll(function() {
    $('.noSideScroll').css({
        'left': $(this).scrollLeft()
    });
});

但是,当使用对象数组时,我无法让它工作。 (见小提琴:http://jsfiddle.net/chiman24/24mpavga/)。

var data = [{
        "id": 1,
        "title": "First Loved Me",
        "artist": "Israel and New Breed",
        "author": "Houghton, Israel",
        "album": "Covered:  Alive In Asia"
    }, {
        "id": 2,
        "title": "One Thing Remains",
        "artist": "Israel and New Breed",
        "author": "Houghton, Israel",
        "album": "Covered:  Alive In Asia"
    }],
    dataCopy = [{
        "id": 1,
        "title": "First Loved Me",
        "artist": "Israel and New Breed",
        "author": "Houghton, Israel",
        "album": "Covered:  Alive In Asia"
    }, {
        "id": 2,
        "title": "One Thing Remains",
        "artist": "Israel and New Breed",
        "author": "Houghton, Israel",
        "album": "Covered:  Alive In Asia"
    }],
    container = document.getElementById('example1'),
    hot1;


//Table Row and Col Options
hot1 = new Handsontable(container, {
    data: data,
    fixedColumnsLeft: 1,
    columnSorting: true,
    colHeaders: ["id", "title", "artist", "author", "album"],
    columns: [{
        data: "id"
    }, {
        data: "title"
    }, {
        data: "artist"
    }, {
        data: "author"
    }, {
        data: "album"
    }]
});

hot1.addHook('afterChange', afterChange);

function afterChange(changes, source) {
    if (source == 'edit' || source == 'autofill') {
        $.each(changes, function(index, element) {
            var change = element;
            var rowIndex = change[0];
            var columnIndex = change[1];
            var oldValue = change[2];
            var newValue = change[3];
            var cellChange = {
                'rowIndex': rowIndex,
                'columnIndex': columnIndex
            };
            if (oldValue != newValue) {
                var cellProperties = hot1.getCellMeta(
                    rowIndex, columnIndex);
                if (newValue != dataCopy[rowIndex][
                        columnIndex
                    ]) {
                    cellProperties.renderer = hasChanged;
                } else { //data changed back to original value.
                    cellProperties.renderer = noChange;
                }
                hot1.render();
            }
        });
    }
}

有没有办法做到这一点?我想让它使用一组对象来工作,因为我来自服务器的数据将采用 JSON 格式。我已经搜索了几天的handsontable文档无济于事。任何帮助都感激不尽。谢谢。

【问题讨论】:

  • 非常有趣的问题。您缺少的一件事是您应该在自定义渲染器上返回 td。不幸的是不会改变结果。
  • 作为一种解决方法,您可以保留所有已更改单元格的地图,并使用通用渲染器检查当前单元格是否在此地图中。如果是,设置一种颜色,否则使用默认颜色。
  • @ZekeDroid 感谢您的调查。我注意到使用 {data: "id"}、{data: "title} 等会导致从 "getCellMeta" 返回的 cellProperties 对象出现问题。如图所示使用 "data" 属性时,cellProperties.renderer 为 "未定义”。这可能是一个可操作的错误。
  • 好吧,你应该使用setCellMetaObject 设置它,否则它不会做任何事情。但即使有那一套,有些东西也不起作用。可以发到github问题页面上,可能是bug

标签: handsontable


【解决方案1】:

我从可动手做的 github 论坛获得了一些帮助。

显然,如果数据源是一个对象数组,那么在调用“getCellMeta”时,您必须将列索引作为属性传入,而不是传入数字列索引,如下所示:

hot.getCellMeta(2, hot.propToCol(columnIndex));

这是更新后的demo

【讨论】:

    【解决方案2】:

    改变单元格背景颜色的其他方法是使用单元格选项

    ...
    if (oldValue != newValue){
    
        aCell.push(
            { row: rowIndex, 
              col: hot.propToCol(columnIndex), 
              className: "cssWithBackgroundColor" });
    
        hot.updateSettings({ cell: aCell });
    }
    

    如果用户撤消更改,您可以

    if ( source == 'UndoRedo.undo'){
        aCell.pop();
        hot.updateSettings({ cell: aCell });
    }
    

    【讨论】:

      猜你喜欢
      • 2015-12-15
      • 2015-06-10
      • 2017-07-29
      • 2013-01-11
      • 2015-01-01
      • 2015-10-19
      • 2016-04-26
      • 2015-10-10
      • 2017-09-01
      相关资源
      最近更新 更多