handsontable:隐藏一些列而不更改数据数组/对象

Posted

技术标签:

【中文标题】handsontable:隐藏一些列而不更改数据数组/对象【英文标题】:handsontable: hide some columns without changing data array/object 【发布时间】:2015-05-01 20:16:46 【问题描述】:

我有一个要在网格中显示的数据。我正在使用handsontable 来显示数据。每个第 3 列计算为前两列的差异(例如,第 3 列呈现为第 1 列和第 2 列的总和;这是由自定义渲染器完成的,采用 i-1i-2 列的总和)。

这是我的“差异”列的自定义渲染器:

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);

我需要一个“开关”。此开关将显示/隐藏列。如果开关打开,那么我需要显示所有列。如果开关关闭,我只需要显示包含差异的列。 那么,你能建议 - 如何隐藏 hansontable 中的列吗?

编辑:我已按照@ZekeDroid 的建议更新了我的代码。

 // on 'switch click' I modify colsToHide global array and do table re-render
 $('#my-id').handsontable('render');

这是我的自定义渲染器,用于应基于开关隐藏/显示的列:

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');
;

此代码确实隐藏/显示列,但它不适用于标题列。

【问题讨论】:

【参考方案1】:

是的,如果您已经在使用自定义渲染器,那么有一个简单的解决方案。我在this question here 中发布了解决方案。本质上,您可以拥有一个包含要隐藏的列索引的数组,并在自定义渲染器中(因为它会为表中的每个单元格调用)如果 col 是您想要隐藏的列,则执行 td.hide()

在 IE 中检查后,事实证明这个解决方案仍然有效。如果有什么可以使用td.style.display = 'none''auto' 隐藏/显示div。但问题不在于隐藏,而在于我为教学目的而快速编写的onkeydown 事件。我相信你可以自己弄清楚那部分,因为它超出了这个问题的范围。

要隐藏列标题,请使用 jQuery 找到要隐藏的 <th>。一种方法是询问所有这些,然后对文本使用过滤器功能,直到它与您想要的标题匹配。这是一个昂贵的O(n) 解决方案,所以如果我是你,我会在脚本开头执行一次,将列索引中的映射保存到<th>,然后再解决。

新技术

查看this jsFiddle 了解更多信息。你是对的,这种方法很混乱而且效率不高,所以我编写了一些不那么混乱的代码,但仍然很笨拙。我们可以通过更新columns 选项来隐藏列,而不是更改渲染。如果您查看新代码,它现在所做的是更新列数组和列标题。这更接近于真正的列隐藏功能,唯一的挫折是它不会继续排序或重新排列行/列。如果这也是您的应用程序的要求,那么我会密切关注您在 git 项目中提出的问题,并希望最好:)

让我知道这种新方法是否适合您。

【讨论】:

这不会隐藏标题列。 此外,您的代码(也不是 jsfiddle 示例,也不是我根据您的代码编写的代码)在 IE 中不起作用(我尝试了 IE 10)。 让我们看看,对于标题列,它是一个单元格,因此您可以轻松找到它,例如使用 jQuery。就 IE 支持而言……这是一个非常简单的解决方案,我在谷歌搜索两秒钟后发现。我将编辑 jSfiddle 和我的回复以包含这些内容。 不幸的是,我仍然无法隐藏标题列。我们已经升级到最后一个可操作的版本,如果我在渲染器中通过选择器添加隐藏,它们仍然会出现。我不明白这一点:“在脚本的开头执行一次,将列索引中的映射保存到 ,然后解决这个问题。” 用户使用箭头导航时的事件 - 这也是一个问题,但我无法开始调查它,因为我还没有完成标题隐藏。 【参考方案2】:

您可以使用 colWidths 将特定列的宽度减小到 0.1 像素。从技术上讲,它仍然是表的一部分,并且 .getData() 返回列的数据,但对人眼来说它是不可见的。如果你得到这么多列,0.1 像素的列堆叠起来可见,你仍然可以在逗号后面添加更多的零来再次减少列:)

handsontable.updateSettings(
    colWidths: [0.1,0.1,50],
);

此示例将“隐藏”前两列并以 50 像素显示第三列。

PS。要隐藏第一列,我建议宽度为 1px,这样第二列的列边框不会看起来不完整

【讨论】:

我很好奇为什么0.1 而不仅仅是简单的零? 这对我来说是最好的解决方案,因为它将列保留在 dom 中,但在没有 hacky JS 解决方案的情况下正确隐藏了它。 HandsonTable PRO 有一个隐藏列插件,但我只使用社区版,所以这对我来说是完美的!【参考方案3】:

对于隐藏标题列,您可以使用 afterGetColHeader 回调函数并隐藏它。在我的情况下,我已将列名存储为隐藏的单独数组并使用 indexOf 函数检查它

 afterGetColHeader:function(col,th)
                                    currentCoulmn = data.headers[col];
                                    if(hiddenColumns.indexOf(currentCoulmn.fieldName) > -1 )
                                        th.style.display='none';
                                    

                                , 

【讨论】:

【参考方案4】:
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';
 

我已经使用钩子来删除我需要的标题。我在我的 HandsonTable 中尝试了相同的方法,但它不起作用,所以我使用 addHook 尝试了相同的方法,并像魅力一样工作。

afterGetColHeader: 调用header时渲染的函数。

RemoveUnWantedHeader:这是我自己的回调。可以有自己的条件,也可以去掉。

【讨论】:

以上是关于handsontable:隐藏一些列而不更改数据数组/对象的主要内容,如果未能解决你的问题,请参考以下文章

MySql:将数据添加到列而不删除以前的数据

R Shiny Handsontable 更改单个单元格后自动更新功能

SQL 从多个表中选择列而不重复数据

如何在现有表中添加额外的列而不丢失数据

向H2数据库中的所有表添加列而不手动列出表

在 Power Query 中拆分列而不转换为文本?