Discussion
Pegasystems Inc.
US
Last activity: 1 Nov 2021 10:37 EDT
How to freeze the first column and the header of an optimized table
If you are rendering a table with a lot of columns, it is sometimes important to freeze the first column of the table or the header.
This article explains how to implement such functionality using a CSS-only approach and the 'display: sticky' attribute. This approach does not require Javascript and it will only work on modern browsers. For older browsers like IE11, it will use graceful degradation and will not freeze the column and header.
Here is a demo of the functionality using the Templates landing page in Dev Studio.
1/ Configure the table to be a read-only table and optimized
The optimized table has a simpler markup than the legacy table - For this functionality to work, you need to make sure to upgrade your table to use the optimized table.
2/ Add the following CSS snippet to a CSS File attached to your skin
Note: this code snippet uses a section name in the selector to only apply the change to this section. A better approach is to wrap the section containing the table into another section and use a helper class attached to the section include. You can also apply the selectors to a specific table format but beware that creating a new table format will increase significantly the size of the auto-generated CSS file.
The snippet will freeze both 1column and header - remove the unneeded selector if you only need to freeze the header or the column.
div[data-node-id="pzSectionsUsingDTemplate"] #gridBody_right {
position: relative;
max-width: calc(100vw - 80px);
margin: auto;
z-index: 1;
overflow: auto!important;
max-height: 800px;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridBody_right > table {
overflow:auto;
border-left:none!important;
border-top:none!important;
}
/* implement the freeze of the first column */
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr > th:nth-child(2),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr > td:nth-child(2){
background: #FFF;
z-index: 2;
position: sticky!important;
left: 0;
border-left: 1px solid #CBCBCB;
}
/* implement the freeze of the header */
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(1) > th {
background: #FFF;
position: sticky!important;
top: 0;
border-top: 1px solid #CBCBCB;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(1) > th:nth-child(2) {
z-index:3;
}
the max-height and max-width will need to be changed depending on where your table is dropped. The same applies to the border color.
Freezing some of the top rows
it also possible to freeze some of the first rows using some additional CSS - here is some updated CSS that would freeze the first 4 rows - to guarantee that the row height is always the same, we set a white-space:nowrap on these rows.
div[data-node-id="pzSectionsUsingDTemplate"] #gridBody_right {
position: relative;
max-width: calc(100vw - 80px);
margin: auto;
z-index: 1;
overflow: auto!important;
max-height: 800px;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridBody_right > table {
overflow: auto;
border-left: none!important;
border-top: none!important;
}
/* implement the freeze of the first column */
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr > th:nth-child(2),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr > td:nth-child(2) {
background: #FFF;
z-index: 2;
position: sticky!important;
left: 0;
border-left: 1px solid #CBCBCB;
white-space: nowrap;
}
/* implement the freeze of the header */
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(1) > th,
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(2),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(3),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(4),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(5) {
background: #FFF;
position: sticky!important;
top: 0;
border-top: 1px solid #CBCBCB;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(2) > td,
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(3) > td,
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(4) > td,
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(5) > td {
white-space: nowrap!important;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(5) > td {
border-bottom: 1px solid red;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(2),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(2) > td:nth-child(2) {
top: 46px;
z-index: 3;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(3),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(3) > td:nth-child(2) {
top: 65px;
z-index: 3;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(4),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(4) > td:nth-child(2) {
top: 85px;
z-index: 3;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(5),
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(5) > td:nth-child(2) {
top: 105px;
z-index: 3;
}
div[data-node-id="pzSectionsUsingDTemplate"] #gridTableBody > tr:nth-child(1) > th:nth-child(2) {
z-index: 3;
}
Conclusion
This solution allows you to easily add support for a sticky header and footer to your table. If you want a richer example with different column freeze and for a very large table, the recommendation is to use the new React-based table available in Pega 8.5 - These new table implementation can run along with your Pega Infinity application as a dedicated landing page.
for more details
https://www.youtube.com/watch?v=lnYb-Eu-b2A