Handsontable:在运行时更新单元格渲染器
Posted
技术标签:
【中文标题】Handsontable:在运行时更新单元格渲染器【英文标题】:Handsontable: Updating a cell renderer at runtime 【发布时间】: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
【参考方案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 );
【讨论】:
以上是关于Handsontable:在运行时更新单元格渲染器的主要内容,如果未能解决你的问题,请参考以下文章
自定义单元格渲染器操作未在 handsontable 中触发
渲染器使单元格相对于其他单元格值只读后的 JQuery handsontable - 不起作用