chans
chans

Reputation: 5260

Sticky header on scroll in vuetify datatable

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

Answers (4)

Jaimerine
Jaimerine

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

loomchild
loomchild

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

Adrien Leloir
Adrien Leloir

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

Enkhtulga Gantsagaan
Enkhtulga Gantsagaan

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

Related Questions