LWC lightning data table with fixed columns.

Sarang Deshpande
5 min readJul 11, 2023

Hey all the cloudy devs!

Lightning Data table is a great tool added by Salesforce that takes care of most of the things required to show data in a tabular format. But as there is limitation to all the ‘out-of-the-box’ tools anywhere, this also has some limitations when it comes to any custom implementation on top of what is provided.

Fixed column is one of those requirements that is often demanded and is difficult to implement given shadow DOM restrictions and certain event handling restrictions by lightning framework. There have been many discussions on our favorite SFSE regarding the same, but all of these have been concluded without satisfactory solution. This article aims to explain one possible solution to implement fixed column, although with certain known limitations.

Do you want something like this ?

Read On.

Idea

The idea to implement fixed column data table is to have 2 data tables, 1st one being ‘sticky’ and arrange the UI and Javascript so that they work synchronously as a single table.

Code

The entire code base(though a small one :P ) can be found here. Starting with the topmost component :

fixedColumnedDatatable.html

<template>
<div class="slds-box autoOverflow heightLimit">
<div class="slds-grid">
<div class="slds-col fixedPosition">
<c-fc_-custom-datatable key-field="id"
columns={columnFirstTable} data={dataFirstTable}
hide-checkbox-column
default-sort-direction={defaultSortDirection}
sorted-direction={sortDirection}
sorted-by={sortedBy} onsort={onHandleSort}>
</c-fc_-custom-datatable>
</div>
<div class="slds-col">
<lightning-datatable
key-field="id"
columns={columnsSecondTable}
data={dataSecondTable}
hide-checkbox-column
default-sort-direction={defaultSortDirection}
sorted-direction={sortDirection}
sorted-by={sortedBy}
onsort={onHandleSort}></lightning-datatable>
</div>
</div>
</div>
</template>

Here we define the 2 Datatables out of which first one is going to be the ‘fixed’ one. This first datatable is a custom datatable implemented in a way so that it’s cell styling can be adjusted to match the adjoining datatable cells. Please note that we can not override standard cell height for standard datatables, hence we have to use custom datatable. More on this later.

In following code snippet, ‘fixedPossition’ css class is the code that does the ‘trick’ for us, i.e. fixing the 1st datatable. You can see the details about fixing a markup(called ‘sticky’) or making it ‘non-scrollable’ in this article.

fixedColumnedDatatable.css

.slds-box{
padding:0;
}
.fixedPosition{
position: sticky;
z-index: 10;
left:0;
}
.autoOverflow{
overflow:auto;
}
.containerClass{
display:inline-flex;
}
.heightLimit{
max-height: 20rem;;
}

Here, position: sticky makes the div sticky w.r.t. scrolling view frame.
z-index : 10 increases the z-index so that other columns can slide underneath the initial columns.
left : 0 makes the div stick to left, in other words 0 margin/padding to left of this div.

After this code made the markup in 1st div 'sticky', we are done with most of the work and only left with some styling and regular Javascript functions to define the functionality of the datatable. If you are adept with custom datatable already you can skip these sections.

Why Use custom Datatable?

Using custom datatable allowed me to make the cell customized the way I want. For ex, we might want this cell to be a picklist or a button which is not possible using standard LWC DT. But all we want here is a css customizable cell, hence the custom datatable has a simple html template. Custom Datatable html looks like:

fc_CustomDatatable

Nothing here!

To implement a custom data table there are many blogs and also LWC recipes that you can refer. Here is the link to standard documentation for the same.

To explain briefly, a custom data table does not have any markup in the html. The markup is imported using a separate html file in the same old component. As per the code in js file, we are importing fc_customCell.html file which defines the markup for this cell.

fc_customDatatable.js

This is boilerplate code for defining custom types in custom datatable. We define a custom type of ‘cell’ which has:
- template : A html file that defines actual html code (Ex, picklist, a button, a lookup or in our case, just a stylized cell or div). See fc_customCellTemplate.html.
- typeAttributes : defines attributes that might need to be passed to the template LWC component that we create in some time.

fc_customCell.html

This fc_CustomCell.html has a template that defines a simple HTML div on which we apply custom style.

fc_customCellTemplate.html

Here you see the ‘value’ that we passed earlier from fc_CustomCell.html and defined as attributes in fc_CustomDatatable. Need not worry about this, it is not used in our case. This attribute can be used , for example, to dynamically pass any value from parent and to perform any JS logic in child component. For example, pass colour of the button from parent component as dynamic style, or pass a css class name to apply it dynamically on the cell in the div.

fc_customCellTemplate.css

Basically, what all this code is doing is some styling for our case.

Conclusion

The basic idea of fixed column inline scrollable Lightning datatable is simple, have 2 datatables, make one of the datatables sticky and manage the css and Javascript logic between the 2 datatables. Generally, the columns and data for the 2 datatables will be similar because effectively this is same datatable. Hence, managing the logic should not be complex. The master data and column properties of datatable need to split into 2 and whatever logic had to be performed on the master properties earlier has to be applied twice on these 2 sets of properties. A simple utility function that accepts column and/or data property can do the work :)

--

--