4

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.

renathy
  • 5,125
  • 20
  • 85
  • 149

4 Answers4

6

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

Sst
  • 69
  • 1
  • 2
  • 1
    I'm curious why `0.1` and not just simple zero? – Stewart Jan 05 '18 at 23:01
  • This was the best solution for me because it leaves the column in the dom but hides it properly without a hacky JS solution. HandsonTable PRO has a hidden columns plugin but I only use the Community Edition so this was perfect for me! – Melloware Jul 20 '18 at 15:06
4

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.

Community
  • 1
  • 1
ZekeDroid
  • 7,089
  • 5
  • 33
  • 59
  • 1
    This doesn't hide header columns. – renathy Mar 02 '15 at 09:01
  • Moreover your code (nor jsfiddle exampel, nor my code that I wrote based on yours) doesn't work in IE (I tried IE 10). – renathy Mar 02 '15 at 11:25
  • let's see, for header columns it's a single cell so you can find it easily, with jQuery for example. And as far as IE support goes...it's a pretty trivial solution that I found after two seconds of googling. I'll edit the jSfiddle and my response to include these things. – ZekeDroid Mar 02 '15 at 14:08
  • Unfourtunately I am still not able to hide header columns. We have upgrated to the last handsontable version and if I add th hiding by selector in renderer, they still appear. I do not understand this: "do this once at the beginning of the script, save a map from column index to , and then work off of that." – renathy Mar 03 '15 at 12:19
  • Events when user navigates with arrows - this is also a problem, but I cannot start investigating it while I have not done header hiding. – renathy Mar 03 '15 at 12:30
  • Check now the new fiddle – ZekeDroid Mar 03 '15 at 20:41
  • Ok, thank you. I will use it. However, to implement this I would have to rewrite much of my code. The problem is that for some columns I use custom renderer and I "compute" those columns (col3 = col1 + col2). So for col3 I use custom renderer that take data from col-1 and col-2. In your fiddle, if I "hide" col1 and col2 I cannot compute col3. I need rewrite logic to have all data in my starting array and without using "computed" columns. I do not need sorting in this case. We use handsontable in our application and are happy with it. – renathy Mar 04 '15 at 07:49
  • i have a table which has headers and stretchall property set to true. I am hiding a specific col using the renderer function but is there anyway to hide the col header without taking space – Richie Fredicson Sep 29 '15 at 16:15
  • No which is why I recommend the "New Technique" of updating the `columns` object. – ZekeDroid Jan 27 '16 at 15:20
0

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

                                }, 
Infant Rosario
  • 149
  • 1
  • 4
0
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.

Eliotjse
  • 123
  • 1
  • 15