Skip to content

feat!: switch to column hidden property and always keep all columns - #1299

Merged
ghiscoding merged 2 commits into
next-v6from
feat/hidden-columns
Sep 16, 2026
Merged

ghiscoding merged 2 commits into
next-v6from
feat/hidden-columns

Conversation

@ghiscoding

@ghiscoding ghiscoding commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Changes

This is a breaking change replicated from Slickgrid-Universal PR #2281 and its applicable regression fixes.

Column visibility now uses the hidden property while the grid always retains the complete column definitions list.

Breaking changes

  • grid.getColumns() now returns all columns, including hidden columns.

  • Use grid.getVisibleColumns() when only visible columns are required.

  • grid.setColumns() now expects the complete column list.

  • Column visibility should be changed with:

    grid.updateColumnById('columnId', { hidden: true });
    grid.updateColumns();
  • Column Picker, Column Menu, grouping, selection, state persistence, and Excel copy behavior were updated for hidden columns.

  • Colspan and rowspan rendering/navigation were updated to account for hidden columns.

Regression fixes

This also includes the applicable follow-up fixes from:

Migration example

Before:

grid.setColumns(visibleColumns);

After:

grid.updateColumnById('columnId', { hidden: true });
grid.updateColumns();

Use grid.getVisibleColumns() instead of filtering the result of getColumns() manually.

Validation

  • Production build completed successfully.
  • Updated affected examples and Cypress tests.
  • Cypress UI validation was performed separately.

This follows the original migration rationale: retain the full column list and use hidden for visibility. Below is the original PR description

This is a breaking change and will be scheduled for the next major version, Q1 of 2026

Description

For years, I had to use a Shared Service to keep references for both shared.allColumns and shared.visibleColumns, for translating locales also used by Column Picker and Grid Menu to keep track of which columns to hide/show, we then call grid.setColumns() to update the columns in the grid... but this as side effects since SlickGrid never kept the entire column definitions list, on the other end if we just start using a hidden property on the column(s) to hide some of them, then we would be able to keep the full reference at all time to these columns. We can then just use grid.getVisibleColumns() which behind the scene is simply doing a columns.filter(c => !c.hidden).

With this change, I still keep a reference to shared.allColumns because that can be useful when we need to reset to the original column positions. For example if we reordered the columns to different positions and we want to reset to the original columns like Example 11 with Saved Views (Grid State)

Note that we already had the hidden column property that Ben (6pac) added in SlickGrid, but it was a bit incomplete, not fully tested and not used by the Column Picker/Grid Menu... this PR now takes full advantage of this approach. With the hidden approach, it's better to "go all-in" because there side effects related to this approach (see below)

Advantages

We no longer have to keep a reference of the visible columns because we can now simply use grid.getVisibleColumns(), which again is simply just a filter that returns a list of columns that doesn't have the hidden property. Another advantage is that we can translate the locales a lot easier with the new code because we keep all the columns (with the previous code, I had to keep reference to all columns, but also keep the order of the columns and visible columns, translate them and then reapply the columns with grid.setColumns()). The other advantage is that the internal code is much more simple because we just need to change the hidden flag instead of using the Shared Service.

Before After
grid.setColumns(visibleCols) grid.updateColumnById('gender', { hidden: true }); and grid.updateColumns();
sharedService.allColumns grid.getColumns()
sharedService.visibleColumns or grid.getColumns() grid.getVisibleColumns()

Disadvantages or Side effects

There are some side effects related to this new approach of using hidden column property, more specifically with colspan and rowspan. With the previous code, if we had spanning then the hiding a column would simply move over the same spanning to the next column. However with the new code, hiding the column will keep its spanning(s) but will be hidden as well, the other columns spanning(s) will remain on the same column indexes. I think in the end, the new code is actually much more predictable and so I'm inclined to say that the new behavior is better and more predictable (see below).

There's also another side effect which I think is also ok which is that since we would keep all columns but just toggle their hidden properties, then a frozenColumn would also follow and stays with the same column forever. Prior to this PR, with the old code, I had to keep a ref of the column ID and recalculate the frozenColumn index. So with the new code, I can get rid of the code that was recalculating the frozen column index, it's less code and also more predictable

Notes

The hidden column property means that the cell won't be rendered in the DOM (it's simply skipped), but its column index still exists. For example if we have 3 columns and the middle one is hidden, then the first cell class is slick-cell l0 r0 and then the last cell is also shown with slick-cell l2 r2 (notice that l1 r1 isn't displayed but its indexed is kept). This introduced some challenges with colspan/rowspan, more specifically the keyboard arrow navigation because of these ghost index when the column is hidden but their index are still preserved. So anyway, that's why it took me over a month to figure out how to fix them and find all these new side effect bugs that we didn't see before because we previously wipe the array with setColumns() and we didn't previously have blank holes in the middle, so it's a bit of a challenge now but still is the correct approach I think.

Another note is that with Grid Presets if we were to provide a list of columns that had less columns than the original list, it meant that the ones missing were considered hidden columns. However with the new approach, we have columns with potentially hidden props, but I think it can be useful to support both approaches. So with the Grid Presets, I now support both approaches, the user can still use the old approach (less columns equals to hidden columns) and the new approach (all columns but some with hidden flag). Supporting both is great because that means that if the user had any old Grid States saved (to use as Grid Presets when loading a grid), then it would still work.

Conclusion

I think that the hidden is really what SlickGrid should have used from the start, I find it to be the correct way of handling visibility while always keeping the columns reference (for example it's a lot easier to deal with translations). Perhaps it wasn't obvious that this was useful before the Column Picker/Grid Menu were later added to the project, but now that we have them, using hidden makes more sense. The end goal now would be to push the user to stop using setColumns() but now start using the new function updateColumnById('id', { hidden: true }) and then updateColumns() (not setColumns() since that would erase the reference to the full columns ref)

Left Side: previous code ➡ Right Side: new code
firefox_9zWxTm3Qvz

@ghiscoding
ghiscoding requested a review from 6pac September 15, 2026 06:01
@ghiscoding

Copy link
Copy Markdown
Collaborator Author

first v6 PR, notice that we're merging to the new branch next-v6

@6pac

6pac commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Honestly I thought all this was done a year or more ago. As long as it's all consistent, this is no problem at all.

@ghiscoding

Copy link
Copy Markdown
Collaborator Author

@6pac yes and no, you did bring this up, but it wasn't working correctly because you can't mix both together you have to go all-in for it to work correctly. This is especially true for the Column Picker/Grid Menu, if you look at those 2 then you'll see a lot of code drop but that wouldn't be possible until you go all-in... Also what I mean by all-in is to change the behavior of grid.getColumns() and grid.setColumns(), with this PR it now always include all columns including hidden columns and that is a breaking change (hence v6) and I've already done this breaking change in my own repo because it simplifies the code a lot and is closer to what most users would expect to get

@6pac

6pac commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Good by me. Happy to merge?

@ghiscoding
ghiscoding merged commit c37b4ee into next-v6 Sep 16, 2026
4 checks passed
@ghiscoding
ghiscoding deleted the feat/hidden-columns branch September 16, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants