How to get a Vue b-table to scroll the body with a fixed header

Abion47 picture Abion47 · Mar 1, 2018 · Viewed 11.7k times · Source

I've got a b-table element on a page that currently displays a bunch of data from a database. At the moment it is paginated, but feedback has indicated that they would rather have all the information displayed in a single scrolling view. I can do this, but the problem is that if I set a containing div to scroll the whole table, it also scrolls the column headers away. I need to find a way to be able to scroll just the table body while leaving the column headers in place, and I'd prefer to be able to do it within the bounds of the element itself instead of rigging up something with completely separate header and body with a bunch of Javascript rigging in the background.

Under the component reference of the bootstrap-vue table component, it says that there is a property called tbody-class which looks like it's a way to specify a custom class for the tbody (crazily enough). The page doesn't give any indication of how to use it, though, and my experimentation hasn't produced any results:

<b-table 
    tbody-class="my-class"   <- Applies prop to table but not to tbody
    :tbody-class="my-class"  <- Seemingly ignored entirely
>

It sounds like this sort of issue was solved on this issue thread, but it doesn't really detail how it was solved. It mentions that the functionality was added to "the next update", but neither the patch notes of the version released following that comment nor the documentation mentions that addition at all (unless it means the properties I mentioned in the previous paragraph). It does talk about using CSS selectors to apply the style in a roundabout fashion, but I wasn't able to get that to work either. (In the following example, the tbody in the Chrome inspector did not have the applied style.)

.table.my-table > tbody {
    height: 100px;
}

The version of Vue I'm using is 2.2.6.

Answer

Calos picture Calos · Feb 5, 2020

Since v2.0.0-rc.28, optional props sticky-header has been added to support fixed headers.

new Vue({
  el: '#app',
  data: {
    items: [
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' },
      { heading1: 'table cell', heading2: 'table cell', heading3: 'table cell' }
    ],
  }
});
<html>

<header>
  <script src="//unpkg.com/[email protected]/dist/vue.min.js"></script>
  <script src="//unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>

  <link type="text/css" rel="stylesheet" href="//unpkg.com/[email protected]/dist/css/bootstrap.min.css" />
  <link type="text/css" rel="stylesheet" href="//unpkg.com/[email protected]/dist/bootstrap-vue.min.css" />
</header>

<body>
  <div id="app">
    <b-table sticky-header :items="items" head-variant="light"></b-table>
  </div>
</body>

</html>