Applying styles/classnames to column's header when hovering a cell

Tags: #<Tag:0x00007f8b19caf2c8> #<Tag:0x00007f8b19caf188>

Hello guys.

I am trying to implement a functionality which seemed quite trivial to me at the first glance, however, after trying to implement it, i’ve faced with some obstacles which i am not able to solve after reading multiple issues at github and the docs.

Story: when i hover over a table cell, i want to add a classname to all of the column’s rows i am hovering over. It was quite simple to implement with the normal cells (using afterOnCellMouseOver, afterOnCellMouseOut hooks), however, directly applying a class to a column header is not working (it seems to me that the hnTable is erasing all the styles/classes on the headers after the initial render of the table since after logging the TD immediately after i add a class to it, i can see the classname in the console).

So…Is there a direct way to apply a class/style to a specific col header given that i have the row-col coordinates?

Here is the code for applying class name to cells of a particular col on hower…the same approach not working to the header…

 const afterOnCellMouseOver: Handsontable.GridSettings["afterOnCellMouseOver"] = (...args) => {
      const localHotInstance = hotInstance;

      if (!localHotInstance) return;

      const { col } = args[1];

      const rowCount = localHotInstance.countRows();

      for (let row = 0; row < rowCount; row++) {
        const cell = localHotInstance.getCell(row, col);
        if (!cell) continue;

        cell.classList.add(HN_TABLE_HOVERED_CELL_CLASS_NAME);
      }

      if (settings.value.afterOnCellMouseOver) {
        settings.value.afterOnCellMouseOver(...args);
      }
    };

    const afterOnCellMouseOut: Handsontable.GridSettings["afterOnCellMouseOut"] = (...args) => {
      const localHotInstance = hotInstance;

      if (!localHotInstance) return;

      const { col } = args[1];

      const rowCount = localHotInstance.countRows();

      for (let row = 0; row < rowCount; row++) {
        const cell = localHotInstance.getCell(row, col);
        if (!cell) continue;

        cell.classList.remove(HN_TABLE_HOVERED_CELL_CLASS_NAME);
      }

      if (settings.value.afterOnCellMouseOut) {
        settings.value.afterOnCellMouseOut(...args);
      }
    };

Appreciate the help!

Hi @hangor1939

Thank you for contacting us. Let me clarify, are your requirements to highlight the current columns that you are hovering over along with the column header? Or is this the solution you are looking for? https://jsfiddle.net/handsoncode/5bhty2d8/

Exactly, in your example you’re highlighting the hovered row… I am looking for the opposite - highlighting the column - which is working fine by directly applying class names to specific cells given that i know the col index… However, doing the same with the col header is not working.

Imagine that the fiddle you’ve provided is highlighting the whole column including the header. And the problem is - how do i highlight the header the same way i do with the plain cells.

@hangor1939

I’m sorry, wrong example was pasted. I meant that situation: https://jsfiddle.net/handsoncode/p2bgur7x/

Yeah, this example represents what i would like to achieve, however, the main problem is to also highlight the header (‘Car’, ‘Year’, etc…) cells. I’ve already implemented the same functionality as in the fiddle, but highlighting the header cell is just not working…

Any thoughts…?

@hangor1939

It does not work for headers as the setCellMeta() method you have in the hook runs only for TDs (cells), not headers. In this case for headers you’d need to run updateSettings() > afterGetColHeader method and then attach CSS classes for THs. But that might cause some performance drops if the user is rapidly changing the columns’ indexes.

Thank you for the clarification, will try this approach and see how bad are the performance drops.
Appreciate.

One more thing. Why directly adding classnames to the headers not working? Is HnTable overiding them dynamically on every render?

Headers are rebuilt with each render, that’s why you need to use a dedicated hook afterGetColHeader to attach some custom logic/styling to the element when it’s recreated. You can also use the colHeaders option if that works better for you.

Thanks, now it’s clear!
So i guess doing some stuff with headers on hover is not the best option due to perf issues…
Cheers