Guide on adding dual horizontal scroll bars to a v-data-table (Vue / vuetify)

Currently, I am working on Vue / Vuetify and experimenting with the v-data-table component. While creating a table, I noticed that it has a horizontal scroll bar at the bottom. https://i.stack.imgur.com/noOzN.png

My goal now is to implement two horizontal scroll bars - one at the bottom (the default one) and another at the top of the table. Both scroll bars should allow users to navigate through the information displayed in the v-data-table (Edited Screenshot)

https://i.stack.imgur.com/Lt4d1.png

I have searched for information on this topic but only found resources related to vanilla JS and HTML, not specific to Vue / Vuetify.

Here is the code snippet I am currently using:


<template>
  <v-container>

     <v-data-table
    :headers="headers"
    :items="desserts"
    :items-per-page="5"
    class="elevation-1"
  ></v-data-table>

  </v-container>
</template>

<script>
  export default {
    name: 'HelloWorld',

    data () {
      return {
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'start',
            sortable: false,
            value: 'name',
            width: 300
          },
          { text: 'Calories', value: 'calories', width: 300},
          { text: 'Fat (g)', value: 'fat', width: 300 },
          { text: 'Carbs (g)', value: 'carbs', width: 300 },
          { text: 'Protein (g)', value: 'protein', width: 300 },
          { text: 'Iron (%)', value: 'iron', width: 300 },
        ],
        desserts: [
          // Desserts data here...
        ],
      }
    },
  }
</script>

Answer №1

I successfully obtained a solution.

The next step is to create three CSS methods: one for the scrollbar path size, another for the scrollbar size, and a third one to make the scrollbar visible and functional.

Within the export default section of the component, we add the mounted section and insert a method that ensures the top scrollbar's position mirrors that of the bottom scrollbar, and vice versa.

To reference the top scrollbar, I utilize the wrapper2 tag. For the v-data-table scrollbar, two references are necessary: one for the identifying tag and another for the v-data-table component itself.

In the HTML code, all that's required is to establish a connection between the scrollbar and the v-data-table.

https://i.stack.imgur.com/HHfL5.png

This is the updated code:

<template>
  <v-container>
    
    <v-col>
        <!-- We use this wrapper to display the second scrollbar above the table -->
        <div id="wrapper2">
          <div id="div2" class="width-scroll" >
          </div>
        </div>
    </v-col>
    
<v-col>
     <v-data-table
    :headers="headers"
    :items="desserts"
    :items-per-page="5"
    class="elevation-1 table-reference"
  ></v-data-table>
</v-col>

  </v-container>
</template>

<script>
  export default {
    name: 'HelloWorld',

    data () {
      return {
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'start',
            sortable: false,
            value: 'name',
            width: 300
          },
          { text: 'Calories', value: 'calories', width: 300},
          { text: 'Fat (g)', value: 'fat', width: 300 },
          { text: 'Carbs (g)', value: 'carbs', width: 300 },
          { text: 'Protein (g)', value: 'protein', width: 300 },
          { text: 'Iron (%)', value: 'iron', width: 300 },
        ],
        desserts: [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
            iron: '1%',
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
            iron: '1%',
          },
          {
            name: 'Eclair',
            calories: 262,
            fat: 16.0,
            carbs: 23,
            protein: 6.0,
            iron: '7%',
          },
          {
            name: 'Cupcake',
            calories: 305,
            fat: 3.7,
            carbs: 67,
            protein: 4.3,
            iron: '8%',
          },
          {
            name: 'Gingerbread',
            calories: 356,
            fat: 16.0,
            carbs: 49,
            protein: 3.9,
            iron: '16%',
          },
          {
            name: 'Jelly bean',
            calories: 375,
            fat: 0.0,
            carbs: 94,
            protein: 0.0,
            iron: '0%',
          },
          {
            name: 'Lollipop',
            calories: 392,
            fat: 0.2,
            carbs: 98,
            protein: 0,
            iron: '2%',
          },
          {
            name: 'Honeycomb',
            calories: 408,
            fat: 3.2,
            carbs: 87,
            protein: 6.5,
            iron: '45%',
          },
          {
            name: 'Donut',
            calories: 452,
            fat: 25.0,
            carbs: 51,
            protein: 4.9,
            iron: '22%',
          },
          {
            name: 'KitKat',
            calories: 518,
            fat: 26.0,
            carbs: 65,
            protein: 7,
            iron: '6%',
          },
        ],
      }
    },
    
    mounted(){
      let wrapper_1 = document.querySelector('.table-reference .v-data-table__wrapper');
      let wrapper_2 = document.querySelector('#wrapper2');
      wrapper_1.onscroll = function() {
        wrapper_2.scrollLeft = wrapper_1.scrollLeft;
      };
        
      wrapper_2.onscroll = function() {
        wrapper_1.scrollLeft = wrapper_2.scrollLeft;
      };
    },

  }
</script>

<style>

/* This defines the size of the scrollbar path */
#wrapper2{
      width: 100%;
      overflow-x: scroll; 
      overflow-y:hidden;
  }

/* This div enables scrolling and displays the scrollbar */
  #div2 {
      height: 1px;
      overflow: scroll;
  }

  /* This sets the size of the scrollbar */
  .width-scroll{
    width:1800px;
  }

</style>

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

Changing pages in Django with a single click of a line: A step-by-step guide

As a beginner in Django, I am looking to create views that change when a line in an HTML tag is clicked. The idea is to open a new view named after the hash inside the <code>Hash tag. {% load staticfiles %} <!DOCTYPE html> <html lang="fr"&g ...

Adjusting the vertical dimension of an Angular 17 Material Dropdown Field?

Check out this demo where I'm exploring ways to decrease the height of the select field. Here's the code snippet: <mat-form-field appearance="outline"> <mat-label>Toppings</mat-label> <mat-select [formControl]=& ...

Obtaining solely the words found within HTML documents

In my Python 2.7 project, I have a folder containing multiple HTML pages that I need to extract only words from. My current process involves opening the HTML file, using the Beautiful Soup library to extract text, and then writing it to a new file. However ...

What could be causing my display: table-cell element to not take up the entire available space?

After consideration, I have decided to avoid using a JavaScript solution for my problem. The only way it seems to work consistently is by using setInterval() at regular intervals, which I prefer not to do. I am aware that achieving the same effect with CSS ...

Guide to modifying the behavior of a dynamic dropdown menu

Jquery: $('body').on('change', '.combo', function() { var selectedValue = $(this).val(); if ($(this).find('option').size() > 2) { var newComboBox = $(this).clone(); var thisComboBoxIndex ...

What is the best way to dynamically insert columns into HTML code?

This is an example of my HTML code: <div class="row text-center"> <div class="col h4">We Collaborate With:</div> <div class="col">company1</div> <div class="col">company2</div> ...

Learn how to configure an Angular2 Template Driven form element by implementing two-way binding and integrating template driven form validation techniques

Can anyone help me figure out the correct way to set up an Angular template driven form element for both validation and two-way binding? I've tried using ngModel in different ways, but cannot seem to achieve two-way binding without encountering issues ...

Conceal or reveal buttons using JavaScript

I am struggling with a function that is supposed to hide certain buttons and create a new button. When I click on the newly created button, it should make the previously hidden buttons visible again. However, the function does not seem to work properly. ...

Vue.js provides an interesting object that contains observed data

My axios request looks like this: retrieveData() { Axios.get( '/vue/get-data/', { ...

Center align a font-awesome icon vertically next to a paragraph of text

Is there a way to align a font-awesome icon on the left side of a text paragraph while keeping the text on the right side, even if it's longer and wraps underneath the icon? I've tried various code snippets but haven't found a solution yet. ...

Utilizing global SCSS styles in a Vue project alongside distinct SCSS mixin and variable files

In the process of developing a Vue 3 app with scss, I have encountered a challenge. I have three separate stylesheet files - _mixins.scss, _variables.scss, and base.scss. To ensure that the mixins and variables are accessible in all components without manu ...

Several Divs Positioned on Different Pages with Backgrounds That "Scroll"

Currently utilizing: jQuery Mobile 1.4.5 I am interested in knowing if it is feasible to achieve the following, and if so, how to start working on it. At the moment, there are 4 page divs that utilize swipe for navigation between them with a horizontal t ...

Is it possible to run a query directly from HTML code?

I am trying to retrieve data from my table that includes two columns: Judul, Isi. <head><link type="text/css" rel="stylesheet" href="addnewpage.css"/</head> <body> <?php $k = mysqli_connect("local ...

Verify the login status, display a prompt if the user is not logged in, and proceed with the process upon successful

Utilizing Vuejs along with Vuetify and Vuex, I aim to develop a basic app such as a small todo list. My backend is supported by an Express REST api and for handling HTTP methods, I rely on Axios. In dealing with session management, I have come across two ...

How to set the default value of a select dropdown in PHP

I came across this snippet of code: <td> <select class="versionSelect"> <option value="5" <?php if($item->version === "5") echo "selected='selected'"; ?>>5</option> <option value="6" <?php ...

Display icons within each table cell row

Objective: I want to implement a feature where icons appear when the cursor is inside a td row, allowing users to click on them. These icons will contain links. When the cursor moves to a new td row, the previous row should return to its default state a ...

Switching between play and pause for the video element using a component for the child

Trying to toggle the play/pause of a child video by clicking on a parent div can be challenging, especially when dealing with multiple instances of the same div and video. A normal function may only work for one specific video, as mentioned by @ken. I hav ...

What is the best way to ensure that the search box automatically adjusts its position and size regardless of the screen resolution?

I'm currently working on a responsive website project and facing an issue with the absolute positioning of the search bar on the main page, which is crucial for me. Below is the code snippet: <div class="span4"> <form class="well form ...

Is there a way to display the HTML input date by simply clicking on text or an image?

I need to display a date picker when I click on specific text or an image. I am working with reactjs and utilizing the HTML input type="date", rather than the React-datepicker library. Here is the code snippet: import { useRef } from "r ...

Lightbox Thumbnail feature in Wordpress theme

Looking for some help with customizing code in my WordPress theme. The current setup includes a thumbnail image with two icons on top - one is a lightbox gallery icon that I want to focus on, and the other is a like button. My goal is to remove the lightb ...