Achieving a scrolling body with a fixed header in a Vue b-table

Currently, I have implemented a b-table element on a webpage to display data from a database. The table is paginated, but feedback suggests that users prefer all information displayed in a single scrolling view. However, the issue arises when I attempt to scroll the entire table within a containing div, as it also moves the column headers out of view. My goal is to find a solution where only the table body scrolls while keeping the column headers stationary, all without resorting to complex Javascript manipulation.

In the component reference for the bootstrap-vue table component, there is mention of a property called tbody-class, which appears to offer a way to define a custom class for the tbody element. Unfortunately, the page does not provide clear instructions on how to utilize this feature, and my attempts at using it have yielded no success:

<b-table 
    tbody-class="my-class"   <- Adds prop to table but not tbody
    :tbody-class="my-class"  <- Seems to be completely ignored
>

An apparent solution to a similar problem was mentioned in this issue thread, though details on the actual resolution are lacking. It references an upcoming update that should address the issue, yet neither the subsequent version's patch notes nor documentation acknowledge this addition (unless referring to the previous properties). Additionally, suggestions about applying styles through CSS selectors indirectly were ineffective in my case, as evidenced by inspecting the tbody element in Chrome.

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

The Vue version being used is 2.2.6.

Answer №1

Starting from version 2.0.0-rc.28, an optional prop sticky-header has been included to enable 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d0a6a5b590e2fee6fee1e1">[email protected]</a>/dist/vue.min.js"></script>
  <script src="//unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e2c21213a3d3a3c2f3e63383b2b0e7c607e607e">[email protected]</a>/dist/bootstrap-vue.js"></script>

  <link type="text/css" rel="stylesheet" href="//unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284a47475c5b5c5a4958681c061b0619">[email protected]</a>/dist/css/bootstrap.min.css" />
  <link type="text/css" rel="stylesheet" href="//unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a2c0cdcdd6d1d6d0c3d28fd4d7c7e2908c928c92">[email protected]</a>/dist/bootstrap-vue.min.css" />
</header>

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

</html>

Answer №2

In search of a solution to scroll only the table body while keeping the column headers fixed, I aim to achieve this within the element's boundaries without resorting to complex JavaScript modifications.

To demonstrate how this can be accomplished, I have created an example repository which includes a hidden scrollbar as well.

While there may be alternative methods to achieve the same effect, here is what worked for me.

<!-- wrap table in container with class. -->
    <b-container fluid class="table-container">
      <b-table
        :items="items" 
        :fields="fields" 
        caption-top
      >
      </b-table>
    </b-container>

Below is the CSS code snippet that hides the scrollbar.

.table-container {
     height: calc(100vh - 450px);
}
 .table-container table {
     display: flex;
     flex-flow: column;
     height: 100%;
     width: 100%;
}
 .table-container table thead {
     flex: 0 0 auto;
     width: 100%;
}
  (Additional CSS property declarations omitted for brevity) 
 ...
 .table-container tr:nth-child(even) {
     background-color: rgba(168, 168, 239, 1);
}

/* START Adjustments for width and scrollbar hidden */
 .table-container th.table-action, .table-container td.table-action {
     width: 5.8vw;
}
 (More adjustments included in the original text) 

An alternative approach for a fixed header with limitations can also be implemented (reference):

Various techniques can be utilized for this purpose, but consistent functionality across different browsers cannot always be guaranteed:

Consider creating a class called my-table-scroll

table.my-table-scroll,
 (Further CSS rules provided in the original content) 
 ...

To implement this, apply the specified class to your b-table component.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with Bootstrap CSS not rendering properly in Chrome and Firefox

After creating a simple "Hello World" web page and including Bootstrap CSS from a CDN, I noticed that it's only working properly in Microsoft Edge. Both Google Chrome and Mozilla Firefox are not displaying the correct output. I would greatly apprecia ...

Can someone please show me the process of iterating through an array in vuejs?

I am trying to create a Vue.js method that loops through an array of objects and returns all the names in that array. However, I am not sure how to achieve this. The method implementation would look something like this: fruits =[ {name: "apple", calori ...

The jQuery click event is failing to trigger

I am facing an issue with some buttons that have specific classes. Here is an example: https://i.sstatic.net/CVIR2.png Each of these buttons contains JSON data stored in a data attribute. I have created a function to detect when a button is clicked and p ...

Utilizing React Refs to Retrieve Value from HTML Select Element

I am currently working on a form that includes the use of an HTML select element. <select className="form-control" id="ntype" required > <option value = "">None</option> <option value = "1">1</option> < ...

Issue with displaying MP4 movies in Angular

I'm trying to display an mp4 video in Angular 9: <video controls (click)="toggleVideo()" preload="none" *ngIf="post.moviePath != null" #videoPlayer> <source [src]="getMovieSanitazePath(post.moviePath ...

Achieve a full-height sidebar design similar to Wordpress using flexbox functionality

Working on a web app that features a tools sidebar with a fixed width requirement amidst fluid content. Explored using flexbox to achieve this, but encountered an issue where the main box only takes the height of the viewport instead of the entire site&ap ...

Load the entire AngularJS webpage using AJAX requests

I'm facing a challenge where I need to integrate an entire legacy page, along with some AngularJS elements, into our new page using AJAX. Initially, all I could see was the raw AngularJS markup: Rank ID {{$index+1}} {{player.playerid}} Afte ...

Looking for a solution to dynamically fill a list in JQuery with data from a JSON file. Any suggestions for troubleshooting?

Currently, I am utilizing a JSON file to fetch Quiz questions. In my approach, each question is being stored in an array as an object. The structure of the question object includes 'text' (the actual question), 'choices' (an array of po ...

Executing functions one after the other in Vue.js

I am encountering a challenge in vuejs when it comes to executing functions/methods sequentially. I have three functions as follows: MethodA: function(){ if(x = 1){ value1 = 2; } if (x ==2){ value2 = 4; } this.Method ...

Is there a way to identify if the parent page has completed loading while within an iframe?

Is there a way to detect properties or events within the iframe that can help determine this? The src of the iframe and the parent page belong to different domains. ...

Troubleshooting Vue template issues with updating values in the composition API

I am facing an issue with a functional component: export default defineComponent({ name: 'MovieOverview', components: { ExpandedMovieInformation, }, setup() { let toggleValue = false; const toggleExpandedMovieInformation = (m ...

Firefox presents a compact box positioned between the images

When attempting to use flags as a way to switch between languages, I encountered an issue in Firefox where a small box appears between the images on the Hebrew site. In Chrome, everything works fine. I implemented the following code: <div class="flags ...

Having trouble with Floating Labels in Bootstrap 5

Having trouble with my floating labels - any advice? https://i.sstatic.net/fk0CG.png Here is the code snippet: <div class="form-floating mb-3"> <input type="text" class="form-control" autofocus id="txtNome" placeholder=" "> <la ...

What causes certain properties of html and body elements to behave in this way?

I'm on a quest for understanding some mysteries. First riddle: Why does the body have a mysterious margin-top? html { height: 100%; background-color: red; } body { height: 100%; margin: 0; background-color: yellow; } <h1>Hello P ...

How to Implement Multi Select Drag and Drop Feature in Angular 4?

Currently, I am implementing Angular 2 Drag-and-Drop from this library to enable the selection of list items using a drag and drop method. However, I have encountered issues with its functionality on touch devices and when attempting to perform multiple it ...

Is there a way to display an asterisk within a select2 dropdown to signify that a field is mandatory?

I'm facing an issue with the Select2 plugin in my form. While all fields are required and marked by an asterisk when empty, the Select2 dropdown ignores this validation attribute. Therefore, I am wondering: Is there a way to display an asterisk image ...

Creating a sleek CSS drop-down navigation menu

I seem to be facing an issue with the side navigation drop down menu. Below are the link and CSS code: <nav id="nav"> <div class="menu-main_nav-container"><ul id="menu-main_nav" class="menu"><li id="menu-item-270" class="menu-it ...

ng-init assign value to a new object

<!DOCTYPE html> <html> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> <body> <div ng-app="myApp" ng-controller="myCtrl2" ng-init="person = new Person('Al ...

Is there a way to modify the background color of a button once it has been clicked, specifically using JavaScript?

I am looking to change the background color of a button that I have clicked on in my code. Do I need to use loops and conditions for this task? I attempted to access the first index, but I am unsure how to change the background color of other buttons. l ...

Using Angular 8 to Pass Form Data to Another Component via a Service

Is there a way to send all the Formgroup data as a Service in Angular to Another Component without using ControlValueAccessor? I want the receiver to automatically receive the value data whenever someone enters information on a form. I am attempting to mo ...