Reputation: 5260
When vuetify datatable height is greater than the window height, when we scroll the page, I want the header row sticky till the datatable scroll is over
The behaviour should be similar to this https://output.jsbin.com/zuzuqe/1/
also like the datatable they used https://www.worldometers.info/coronavirus/
I've also tried
th {
position:sticky;
top: 0;
background-color: white;
}
The position sticky is relative to the datatable and not to the window
Can anyone suggest me some idea or codepen on how to implement the same using Vuetify datatable
Upvotes: 5
Views: 5486
Reputation: 301
A combination of previous answers worked for me:
Unsetting overflow on the table wrapper as suggested by loomchild:
:deep(div.v-table__wrapper) {
overflow: unset
}
And adding fixed-header to the component, as suggested by Enkhtulga (no need to set position/top on thead in this case, this prop takes care of it):
<v-data-table fixed-header>
Upvotes: 0
Reputation: 778
Your code is OK, since you correctly apply stickiness to <th>
element. However, the issue is that Vuetify.js data table wrapper has overflow. It can be removed by /deep/
selector:
.v-data-table /deep/ .v-data-table__wrapper {
overflow: unset;
}
Here's a complete working example: https://codesandbox.io/s/sticky-vuetify-table-header-3o0km
I wrote a little article explaining my solution to this problem: https://medium.com/@jareklipski/sticky-table-header-in-vuetify-js-fab39988dc3
Upvotes: 1
Reputation: 503
You can do that with a Vue Component Float Thead vue component
EDIT :
This is vue directive usable with vuetify v-simple-table
Use :
<v-simple-table v-simple-table-sticky></v-simple-table>
Directive :
function stickyScrollHandler(el) {
return () => {
const getOffsetTop = function(element) {
let offsetTop = 0;
while (element) {
offsetTop += element.offsetTop;
element = element.offsetParent;
}
return offsetTop;
}
const table = el.querySelector("table");
const tableHeader = el.querySelector(".adx-table_sticky_header");
let tableHeaderFloat = el.querySelector(".adx-table_sticky--float");
const pos = getOffsetTop(table) - window.scrollY;
if (pos < 0) {
if (!tableHeaderFloat) {
const clone = tableHeader.cloneNode(true);
clone.classList.remove('.table_sticky_header');
tableHeaderFloat = document.createElement('table');
tableHeaderFloat.appendChild(clone);
tableHeaderFloat.classList.add("adx-table_sticky--float");
table.parentNode.appendChild(tableHeaderFloat);
tableHeader.style.opacity = 0;
}
if (Math.abs(pos) < table.offsetHeight - tableHeaderFloat.offsetHeight) {
tableHeaderFloat.style.position = "absolute";
tableHeaderFloat.style.top = Math.abs(pos) + "px";
}
} else {
if (tableHeaderFloat) {
tableHeaderFloat.remove();
}
tableHeader.style.opacity = 1;
}
}
}
Vue.directive("simple-table-sticky", {
bind: function(el, binding, vnode) {
el.querySelector("table thead").classList.add("adx-table_sticky_header");
el.style.position = "relative"
window.addEventListener('scroll', stickyScrollHandler(el));
},
unbind: function(el) {
window.removeEventListener('scroll', stickyScrollHandler(el));
}
});
Upvotes: 1
Reputation: 579
There is fixed-header
props in data table
UI component of Vuetify
. Checkout it -> https://vuetifyjs.com/en/components/data-tables/#api
Upvotes: 1