handsontable:隐藏一些列而不更改数据 array/object
handsontable: hide some columns without changing data array/object
我有一个数据要在网格中显示。我正在使用 handsontable 来显示数据。每个第 3 列计算为前两列的差异(例如,第 3 列呈现为第 1 列和第 2 列的总和;这是由自定义渲染器完成的,采用 i-1
和 i-2
列的总和)。
这是我为 "difference" 列定制的渲染器:
var val1 = instance.getDataAtCell(row, col - 1),
val2 = instance.getDataAtCell(row, col - 2),
args = arguments;
args[5] = val2 - val1;
if (args[5] !== 0) {
$(td).addClass('grid-column-class-nonzero');
}
Handsontable.renderers.NumericRenderer.apply(this, args);
我需要一个 "switch"。此开关将 show/hide 列。如果开关打开,那么我需要显示所有列。如果开关关闭,我只需要显示包含差异的列。
那么,你能建议 - 如何隐藏 hansontable 中的列?
编辑: 我已经按照@ZekeDroid 的建议更新了我的代码。
// on 'switch click' I modify colsToHide global array and do table re-render
$('#my-id').handsontable('render');
这是我的自定义列渲染器,应该 hidden/shown 基于开关:
var colsToHide = [];
var classModel1Renderer = function (instance, td, row, col, prop, value, cellProperties) {
"use strict";
if (colsToHide.indexOf(col) > -1) {
td.hidden = true;
} else {
td.hidden = false;
}
Handsontable.renderers.TextRenderer.apply(this, arguments);
$(td).addClass('grid-column-class-model1');
};
此代码确实 hides/shows 列,但不适用于 header 列。
是的,如果您已经在使用自定义渲染器,那么有一个简单的解决方案。我在 this question here 中发布了解决方案。本质上,您可以拥有一个数组,其中包含您要隐藏的列索引,并在自定义渲染器中(因为它被调用 table 中的每个单元格)如果 col
是一个,则执行 td.hide()
您要隐藏的列。
在 IE 中检查后,发现此解决方案仍然有效。如果有的话,你可以使用 td.style.display = 'none'
和 'auto'
到 hide/display 和 div。但问题不在于隐藏,而是我出于教学目的快速编写的 onkeydown
事件。我相信你可以自己弄清楚那部分,因为它超出了这个问题的范围。
要隐藏列 header,请使用 jQuery 找到您要隐藏的 <th>
。一种方法是要求所有这些,然后对文本使用过滤功能,直到它匹配您想要的 header。这是一个昂贵的 O(n)
解决方案,所以如果我是你,我会在脚本开头执行一次,保存从列索引到 <th>
的映射,然后处理它。
新技术:
查看 this jsFiddle 了解更多信息。你是对的,因为这种方法很混乱而且效率不高,所以我编写了一些不那么混乱但仍然很笨拙的代码。我们可以通过更新 columns
选项来隐藏列,而不是更改渲染。如果您查看新代码,它现在所做的是更新列数组和列 headers。这更接近于真正的列隐藏功能,唯一的缺点是它不会保持排序或重新排列 rows/columns。如果这也是您申请的要求,那么我会密切关注您在 git 项目中提出的问题,并希望一切顺利 :)
让我知道这种新方法是否适合您。
您可以使用 colWidths 将特定列的宽度减小到 0.1 像素。从技术上讲,它仍然是 table 的一部分,并且 .getData() 返回列的数据,但对于人眼来说它是不可见的。如果你得到这么多列,0.1 像素的列堆叠起来是可见的,你仍然可以在逗号后面添加更多的零来再次减少列:)
handsontable.updateSettings({
colWidths: [0.1,0.1,50],
});
此示例将 "hide" 前两列显示为 50 像素的第三列。
PS。为了隐藏第一列我建议宽度为1px,这样第二列的列边框就不会显得不完整
要隐藏 header 列,您可以使用 afterGetColHeader 回调函数并将其隐藏。在我的例子中,我将列名存储为隐藏的单独数组并使用 indexOf 函数检查它
afterGetColHeader:function(col,th){
currentCoulmn = data.headers[col];
if(hiddenColumns.indexOf(currentCoulmn.fieldName) > -1 ){
th.style.display='none';
}
},
hot.addHook('afterGetColHeader', RemoveUnWantedHeader);
function RemoveUnWantedHeader(col, th) {
if (th.textContent == "A" || th.textContent == "B" || th.textContent == "C"
|| th.textContent == "D" || th.textContent == "E"
|| th.textContent == "F" || th.textContent == "G" || th.textContent ==
"H"
|| th.textContent == "I" || th.textContent == "J"
|| th.textContent == "K" || th.textContent == "L" || th.textContent ==
"M"
|| th.textContent == "N" || th.textContent == "O"
|| th.textContent == "P" || th.textContent == "Q" || th.textContent ==
"R"
|| th.textContent == "S" || th.textContent == "T"
|| th.textContent == "U" || th.textContent == "V" || th.textContent ==
"W"
|| th.textContent == "X" || th.textContent == "Y" || th.textContent ==
"Z"
|| th.textContent == "AQ" || th.textContent == "AR" || th.textContent ==
"AS"
|| th.textContent == "AT" || th.textContent == "AU" || th.textContent ==
"AV" || th.textContent == "AW") {
th.style.display = 'none';
}
}
我已经使用 hook 删除了我需要的 headers。我在我的 HandsonTable 中尝试了同样的方法,但它不起作用,所以我使用 addHook 尝试了同样的方法,但效果很好。
afterGetColHeader: 调用header时渲染的函数
RemoveUnWantedHeader:是我自己的回调。可以有自己的条件,可以去掉。
我有一个数据要在网格中显示。我正在使用 handsontable 来显示数据。每个第 3 列计算为前两列的差异(例如,第 3 列呈现为第 1 列和第 2 列的总和;这是由自定义渲染器完成的,采用 i-1
和 i-2
列的总和)。
这是我为 "difference" 列定制的渲染器:
var val1 = instance.getDataAtCell(row, col - 1),
val2 = instance.getDataAtCell(row, col - 2),
args = arguments;
args[5] = val2 - val1;
if (args[5] !== 0) {
$(td).addClass('grid-column-class-nonzero');
}
Handsontable.renderers.NumericRenderer.apply(this, args);
我需要一个 "switch"。此开关将 show/hide 列。如果开关打开,那么我需要显示所有列。如果开关关闭,我只需要显示包含差异的列。 那么,你能建议 - 如何隐藏 hansontable 中的列?
编辑: 我已经按照@ZekeDroid 的建议更新了我的代码。
// on 'switch click' I modify colsToHide global array and do table re-render
$('#my-id').handsontable('render');
这是我的自定义列渲染器,应该 hidden/shown 基于开关:
var colsToHide = [];
var classModel1Renderer = function (instance, td, row, col, prop, value, cellProperties) {
"use strict";
if (colsToHide.indexOf(col) > -1) {
td.hidden = true;
} else {
td.hidden = false;
}
Handsontable.renderers.TextRenderer.apply(this, arguments);
$(td).addClass('grid-column-class-model1');
};
此代码确实 hides/shows 列,但不适用于 header 列。
是的,如果您已经在使用自定义渲染器,那么有一个简单的解决方案。我在 this question here 中发布了解决方案。本质上,您可以拥有一个数组,其中包含您要隐藏的列索引,并在自定义渲染器中(因为它被调用 table 中的每个单元格)如果 col
是一个,则执行 td.hide()
您要隐藏的列。
在 IE 中检查后,发现此解决方案仍然有效。如果有的话,你可以使用 td.style.display = 'none'
和 'auto'
到 hide/display 和 div。但问题不在于隐藏,而是我出于教学目的快速编写的 onkeydown
事件。我相信你可以自己弄清楚那部分,因为它超出了这个问题的范围。
要隐藏列 header,请使用 jQuery 找到您要隐藏的 <th>
。一种方法是要求所有这些,然后对文本使用过滤功能,直到它匹配您想要的 header。这是一个昂贵的 O(n)
解决方案,所以如果我是你,我会在脚本开头执行一次,保存从列索引到 <th>
的映射,然后处理它。
新技术:
查看 this jsFiddle 了解更多信息。你是对的,因为这种方法很混乱而且效率不高,所以我编写了一些不那么混乱但仍然很笨拙的代码。我们可以通过更新 columns
选项来隐藏列,而不是更改渲染。如果您查看新代码,它现在所做的是更新列数组和列 headers。这更接近于真正的列隐藏功能,唯一的缺点是它不会保持排序或重新排列 rows/columns。如果这也是您申请的要求,那么我会密切关注您在 git 项目中提出的问题,并希望一切顺利 :)
让我知道这种新方法是否适合您。
您可以使用 colWidths 将特定列的宽度减小到 0.1 像素。从技术上讲,它仍然是 table 的一部分,并且 .getData() 返回列的数据,但对于人眼来说它是不可见的。如果你得到这么多列,0.1 像素的列堆叠起来是可见的,你仍然可以在逗号后面添加更多的零来再次减少列:)
handsontable.updateSettings({
colWidths: [0.1,0.1,50],
});
此示例将 "hide" 前两列显示为 50 像素的第三列。
PS。为了隐藏第一列我建议宽度为1px,这样第二列的列边框就不会显得不完整
要隐藏 header 列,您可以使用 afterGetColHeader 回调函数并将其隐藏。在我的例子中,我将列名存储为隐藏的单独数组并使用 indexOf 函数检查它
afterGetColHeader:function(col,th){
currentCoulmn = data.headers[col];
if(hiddenColumns.indexOf(currentCoulmn.fieldName) > -1 ){
th.style.display='none';
}
},
hot.addHook('afterGetColHeader', RemoveUnWantedHeader);
function RemoveUnWantedHeader(col, th) {
if (th.textContent == "A" || th.textContent == "B" || th.textContent == "C"
|| th.textContent == "D" || th.textContent == "E"
|| th.textContent == "F" || th.textContent == "G" || th.textContent ==
"H"
|| th.textContent == "I" || th.textContent == "J"
|| th.textContent == "K" || th.textContent == "L" || th.textContent ==
"M"
|| th.textContent == "N" || th.textContent == "O"
|| th.textContent == "P" || th.textContent == "Q" || th.textContent ==
"R"
|| th.textContent == "S" || th.textContent == "T"
|| th.textContent == "U" || th.textContent == "V" || th.textContent ==
"W"
|| th.textContent == "X" || th.textContent == "Y" || th.textContent ==
"Z"
|| th.textContent == "AQ" || th.textContent == "AR" || th.textContent ==
"AS"
|| th.textContent == "AT" || th.textContent == "AU" || th.textContent ==
"AV" || th.textContent == "AW") {
th.style.display = 'none';
}
}
我已经使用 hook 删除了我需要的 headers。我在我的 HandsonTable 中尝试了同样的方法,但它不起作用,所以我使用 addHook 尝试了同样的方法,但效果很好。
afterGetColHeader: 调用header时渲染的函数
RemoveUnWantedHeader:是我自己的回调。可以有自己的条件,可以去掉。