handsontable: hide some columns without changing d

2019-05-06 17:57发布

I have a data to show in grid. I am using handsontable to show data. Each 3rd column is computed as difference of previous two (for example, 3rd column is rendered as the sum of 1st and 2nd column; this is done by custom renderer taking sum of i-1 and i-2 columns).

This is my custom renderer for "difference" columns:

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

I need to have a "switch". This switch would show/hide columns. If switch is ON then I need to show all columns. If switch is OFF, I need to show only columns that contains differences. So, can you suggest - how to hide columns in hansontable?

EDIT: I have updated my code as suggested by @ZekeDroid.

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

And this is my custom renderer for columns that should be hidden/shown based on switch:

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

This code indeed hides/shows columns, but it doesn't work for header column.

4条回答
来,给爷笑一个
2楼-- · 2019-05-06 18:25

Yup there is a simple solution if you're using a custom renderer already. I posted the solution in this question here. Essentially, you can have an array with the column indeces you want to hide and in the custom renderer (since it gets called for every cell in your table) do td.hide() if col is a column you want hidden.

After checking in IE, it turns out this solution still works. If anything you can use td.style.display = 'none' and 'auto' to hide/display the div. But the problem is not with the hiding, it's with the onkeydown event that I quickly wrote for teaching purposes. I'm sure you can figure out that part on your own as it is out of the scope of this question.

To hide the column header, use jQuery to find the <th> that you want to hide. One way is to ask for all of them, then use a filter function on the text until it matches the header you want. It's an expensive, O(n) solution so if I were you I'd do this once at the beginning of the script, save a map from column index to <th>, and then work off of that.

New Technique:

Look to this jsFiddle for more info. You were right in that this method is messy and not too efficient so I coded something less messy though still hacky. Instead of changing the rendering, we can hide columns by updating the columns option. If you look the the new code, what it now does is update the columns array, and column headers. This gets closer to a real column hiding feature with the only setback that it doesn't keep sorting or rearranged rows/columns. If this was also a requirement for your application then I'll keep an eye with you on the issue you raised on the git project and hope for the best :)

Let me know if this new method works for you.

查看更多
家丑人穷心不美
3楼-- · 2019-05-06 18:33

You can use colWidths to reduce the width of a specific column to 0.1 pixels. Technically it's still part of the table and .getData() returnes the data of the colum, but to the human eye it's invisible. If you get so many columns, that the 0.1 pixel columns stack up to be visible, you can still add more zeros behind the comma to reduce the columns with again :)

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

This example would "hide" the first two colums and show the third colum with 50 px.

PS. To hide the first column I recommend a width of 1px, so that the column borders of the second column doesn't look incomplete

查看更多
对你真心纯属浪费
4楼-- · 2019-05-06 18:33

For hiding header columns you can use afterGetColHeader callback function and hide it. In my case i have stored the column names to be hidden seperate array and checking it using indexOf function

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

                                }, 
查看更多
We Are One
5楼-- · 2019-05-06 18:51
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';
 }
}

I have used hook to remove the headers I need to. I tried the same inside my HandsonTable it doesn't work so I tried the same using addHook and worked like charm.

afterGetColHeader: It is a function which will be rendered when header is called.

RemoveUnWantedHeader: It is my own callback. You can have your own conditions and can remove.

查看更多
登录 后发表回答