Closed bhkangw closed 1 year ago
I also tried adding p-frozen-column
as a className under DataTable and Column components which states in the docs "Frozen column header" but it did not work as expected
So you want the header row to be sticky? Basically like this how PrimeFaces does it? https://www.primefaces.org/showcase/ui/data/datatable/sticky.xhtml?jfwid=51db7
@melloware yes exactly!
@bhkangw You can easily to this with CSS by setting a header class name like this. If you scroll down the page the headers are always stickied to the top of the page. This is how I do it in my app.
<Column headerClassName="stickyToTopTableHeaders" />
.stickyToTopTableHeaders {
position: sticky;
background-color: #fff;
z-index: 1100;
}
We should add a Showcase example showing this sticky usage.
@bhkangw You can easily to this with CSS by setting a header class name like this. If you scroll down the page the headers are always stickied to the top of the page. This is how I do it in my app.
<Column headerClassName="stickyToTopTableHeaders" /> .stickyToTopTableHeaders { position: sticky; background-color: #fff; z-index: 1100; }
@kbeeveer46 thanks for your reply but I wasn't able to get it working - here's a code sandbox with your suggestions. Let me know if I missed something
@bhkangw You can easily to this with CSS by setting a header class name like this. If you scroll down the page the headers are always stickied to the top of the page. This is how I do it in my app.
<Column headerClassName="stickyToTopTableHeaders" /> .stickyToTopTableHeaders { position: sticky; background-color: #fff; z-index: 1100; }
@kbeeveer46 thanks for your reply but I wasn't able to get it working - here's a code sandbox with your suggestions. Let me know if I missed something
@bhkangw
I don't use menu filterDisplay in my app. I use the row option. So I'm not sure if the menu option will still work well with this CSS. I also don't use responsiveLayout in my app, either. I'm not entirely sure what that does. My tables seem to work fine on mobile and desktop so I never had the need to use that property.
@kbeeveer46 still not working unfortunately. This is what I see in your code sandbox, the header is still not sticky and the table formatting is morphed
@kbeeveer46 still not working unfortunately. This is what I see in your code sandbox, the header is still not sticky and the table formatting is morphed
@bhkangw You are viewing the mobile version of the table. Your monitor resolution + the size of the window is automatically putting the table into mobile mode. Mobile mode doesn't have table headers (they're on the left side of the table and not the top).
Click on the 3rd icon in the top right of your screen shot and it will open that window in full screen mode. Here's what the non-mobile mode looks like and you can see the headers are stickied to the top as I scrolled half way down the page.
Great work @kbeeveer46 i think we definitely need to add a showcase example
Thanks @kbeeveer46 -- was able to get it working!
To anyone viewing this issue, I found the width where the table would collapse to mobile stacked view was unnecessarily wide. So I set breakpoint="240px"
which prevents the stacked view in smaller windows. Code sandbox
Side note: @melloware is there a way to move the DataTable horizontal scrollbar to the top of the table? I tried css workarounds like this but it's not applying as the scrollbar is part of the component. I can also create a separate request!
Hmm I believe that scroll bar is rendered by the browser on overflow and I don't think it's location can be changed but I could be wrong. I have seen it done with hacks like this : https://stackoverflow.com/a/2274892
I took at look at your demo and you don't need to use headerClassName="stickyHeader"
at all. You can do it with just CSS like this.
.p-datatable .p-datatable-thead > tr > th {
position: sticky;
top: 0;
background-color: #fff;
z-index: 1100;
}
See my Code Sandbox: https://codesandbox.io/s/loving-currying-brsqjw?file=/src/demo/DataTableDemo.js
I took at look at your demo and you don't need to use
headerClassName="stickyHeader"
at all. You can do it with just CSS like this..p-datatable .p-datatable-thead > tr > th { position: sticky; top: 0; background-color: #fff; z-index: 1100; }
See my Code Sandbox: https://codesandbox.io/s/loving-currying-brsqjw?file=/src/demo/DataTableDemo.js
Yes, that is correct. I try to avoid editing the Prime React CSS directly because then my changes are overwritten if I ever upgrade to a new version. And in my case, all my tables were different and also have other content above them which also needed to be stickied (I use top: 75px on my headers so they are stickied below that content. I took the 75px out of my last comment and forgot to add 0px back before submitting the comment which is why it didn't work for the other user at first).
There are many different ways to sticky the headers and I think your solution is probably best for users who only have basic requirements. In my case, I needed a bit more control over how each table stickied the headers. That's when using the headerClassName works well.
But you can just put an ID on the table like id="hello"
and then make your CSS custom like...
#hello.p-datatable .p-datatable-thead > tr > th {
position: sticky;
top: 0;
background-color: #fff;
z-index: 1100;
}
To only take effect on that single table. I always prefer CSS to adding anything in code but to each his/her own!
Sorry for the additional pestering but I noticed with these changes the horizontal scrolling now occurs outside of the table contents. So what I'm observing now is the table header no longer "sticks" but scrolls horizontally. This makes the header and any navigation continue scrolling while it should stay fixed.
What use to happen is while the table's contents would scroll horizontally, the header/parent would stay fixed
Any fix to prevent this?
@bhkangw
- Remove responsiveLayout from the table
- Add top: 0 to the CSS (sorry, forgot to add this to my last comment) Here's a working example: https://codesandbox.io/s/charming-snyder-727lco?file=/src/demo/DataTableDemo.js
I don't use menu filterDisplay in my app. I use the row option. So I'm not sure if the menu option will still work well with this CSS. I also don't use responsiveLayout in my app, either. I'm not entirely sure what that does. My tables seem to work fine on mobile and desktop so I never had the need to use that property.
@kbeeveer46 what responsiveLayout="scroll"
does is it allows horizontal scrolling within the contents of the table. By disabling it, the unintended side effect I'm seeing is that is scrolling now occurs on the whole page - leaving parents like the DataTable header component "behind" when scrolling. Is there a workaround that doesn't require removing responsiveLayout
?
I answered in your other ticket. This is not possible with HTML. These two features cannot be combined.
Ok thank you @melloware for the response
Late to the party but I have the same issue. I tried adding CSS below to index.css but it's still not floating.
responsivelayout was set to scroll and I did remove it from the datatable. Also, is it possible to make the footer sticky too ?
.p-datatable .p-datatable-thead > tr > th {
position: sticky;
top: 0;
background-color: #fff;
z-index: 1100;
}
The render portion for the app I am modifying is in index.js
const root = ReactDOM.createRoot(document.getElementById('root'));``
root.render(
<React.StrictMode>
<ReportDashboard />
</React.StrictMode>
);
<div className="card">
<DataTable id='report-table' value={data} ref={dt} header={header} filters={filters} filterDisplay="menu"
globalFilterFields={selectedColumns.map(c=>c.key)} onFilter={(e) => setFilters(e.filters)}
paginator rows={25} resizableColumns columnResizeMode="expand" showGridlines={showGridlines} onValueChange={newData => setFilteredData(newData)}
paginatorTemplate="CurrentPageReport FirstPageLink PrevPageLink PageLinks NextPageLink LastPageLink RowsPerPageDropdown"
currentPageReportTemplate="Showing {first} to {last} of {totalRecords}" rowsPerPageOptions={[10,25,50,100]}
>
{selectedColumns.map( col => {
return <Column {...getColumnProps(col)} />
})}
</DataTable>
<Sidebar visible={modal==='settings'} position="right" className="p-sidebar-md" onHide={() => setModal(null)} >
<h3>Settings</h3>
<div className="col-12">
<label htmlFor="showGridlines" className="mr-2">Show Gridlines</label>
<Checkbox inputId='showGridlines' onChange={e => setShowGridlines(e.checked)} checked={showGridlines}></Checkbox>
</div>
<div className="col-12">
<label htmlFor="datetimeFormat" className="mr-2">Date/time format</label>
<Dropdown value={datetimeFormat} options={datetimeFormats} onChange={(e) => setDatetimeFormat(e.value)} placeholder="Select a format"/>
</div>
</Sidebar>
</div>
</div>
);
}
export default Table
Any help is greatly appreciated. Thanks for your time.
I got it to work by removing the lines below
resizableColumns columnResizeMode="expand"
Any idea how I can make the footer sticky also ?
In PrimeReact 9.2.1 my CSS above won't work because it makes responsiveLayout="scroll"
the default and sticky cannot be used with scrollable tables.
Luckily our app is still on 8.7.2 is there any workaround for that in 9.2.1 ?
Luckily our app is still on 8.7.2 is there any workaround for that in 9.2.1 ?
I would have to spend some time looking at it but I am sure there is a workaround to disable scrollable tables.
@melloware thanks for your time and prompt response, any suggestions for making the footer sticky also ?
@melloware thanks for your time and prompt response, any suggestions for making the footer sticky also ?
When you say "footer" do you mean the paginator? Can you fork my sandbox here and show me what you are trying to do? https://codesandbox.io/s/loving-currying-brsqjw?file=/src/demo/DataTableDemo.js
Yes. Exactly. I would like to make the paginator sticky.
Anyway we could get the header to be sticky with resizeableColumns ?
resizableColumns
probably makes the table scrollable
and see above why the HTML5 spec doesn't allow that.
As for paginator to make it sticky just do this and tweak the top
value to suit your needs.
.p-paginator {
position: sticky;
top: 55px;
z-index: 1101;
}
I forked your sandbox with the footer update in datatabledemo.css but couldn't seem to get it sticky https://codesandbox.io/s/boring-solomon-j5v5go?file=/src/demo/DataTableDemo.css
try this one: https://codesandbox.io/s/loving-currying-brsqjw?file=/src/demo/DataTableDemo.css:965-1057
i made it have a top paginator so you can see it stick.
Working Demo for 9.2.1: https://codesandbox.io/s/flamboyant-dawn-nvd7oc?file=/src/demo/DataTableDemo.css
In addition to @melloware solution, you can also try this style;
...
.stickyTable.p-datatable > .p-datatable-wrapper {
overflow: visible;
}
.stickyTable.p-datatable
> .p-datatable-wrapper
> .p-datatable-table
> .p-datatable-thead {
position: sticky;
top: 75px; /* paginator's height */
z-index: 1100;
}
.p-paginator {
position: sticky;
top: 0px;
height: 75px; /* you can change this line according to your needs */
background-color: #fff;
z-index: 1101;
}
Thank you @melloware and @mertsincan is it possible to float the very top header also where you can select a keyword and country?
How about floating the paginator on the bottom instead ?
const renderHeader = () => {
return (
<div className="flex justify-content-between align-items-center">
<h5 className="m-0">Customers</h5>
<span className="p-input-icon-left">
<i className="pi pi-search" />
<InputText
value={globalFilterValue}
onChange={onGlobalFilterChange}
placeholder="Keyword Search"
/>
</span>
<Dropdown
value={selectedCountry}
options={countries}
onChange={onCountryChange}
optionLabel="name"
filter
showClear
filterBy="name"
placeholder="Select a Country"
/>
</div>
);
};
When I click on the filter icon on a column or the country dropdown, it show up behind the floating headers. Is there a way to have it appear in front of the floating headers so I can actually see it ?
Are we able to move those elements (Customers, keyword search and country dropdown) into the paginator ?
No idea about moving to paginator but you need to mess with the z-index in that CSS. Try dropping it to 100 instead of 1100.
Also, you can try to change z-index and set appendTo="self" to Dropdown component; https://codesandbox.io/s/bitter-pond-5i04c6?file=/src/demo/DataTableDemo.css
Are we able to move those elements (Customers, keyword search and country dropdown) into the paginator ?
I think you can use paginatorTemplate property; https://primereact.org/datatable/#paginator_template
Update for 9.5.0 I had to create this style:
.stickyTable.p-datatable>.p-datatable-wrapper {
overflow: visible;
}
.stickyTable.p-datatable>.p-datatable-wrapper>.p-datatable-table>.p-datatable-thead {
position: sticky;
top: 55px;
z-index: 10;
}
Then use it on the table with className="stickyTable"
Is there any way to do this without overflow: visible;
? My table is quite long and I want to avoid scrolling whole page since it scrolls table settings out of view.
scrollable tables can NOT be sticky. Its not us its how HTML5 sticky works. Scrolling by definition means the header can't be static and sticky.
It seems to be enough to put the datatable in a container that has overflow: auto
to stop it from overflowing on the page. However my TreeSelect header still scrolls out of view in the x axis.
Describe the feature you would like to see added
Sorry if I missed it but I don't see a way to freeze the DataTable header row.
frozenValue
appears to take an array of rows but not sure how it would work with freezing the Header?Describe the solution you'd like
There are ways to freeze columns and rows, but I don't see any documentation on freezing the Header row. I'm guessing it likely already exists but maybe including it in the documentation if it does! If not, perhaps a way to specify the header in
frozenValue
or a separate prop forfreezeHeader