Creating a dynamic table in VuetifyJS by populating it with data in real-time

Dealing with a dynamically changing table columns can be tricky. This means that hardcoding the template for the table like this example won't work:

<template>
  <v-data-table
    :headers="headers"
    :items="items"
    hide-actions
    class="elevation-1"
  >
    <template slot="items" slot-scope="props">
      **<td>{{ props.item.name }}</td>
      <td class="text-xs-right">{{ props.item.calories }}</td>
      <td class="text-xs-right">{{ props.item.fat }}</td>
      <td class="text-xs-right">{{ props.item.carbs }}</td>
      <td class="text-xs-right">{{ props.item.protein }}</td>
      <td class="text-xs-right">{{ props.item.iron }}</td>**
    </template>
  </v-data-table>
</template>

When receiving code as part of the response, it becomes challenging to figure out how to proceed with forwarding the communication.

Answer №1

After carefully examining the question, I stumbled upon an innovative solution to prevent hardcoding the data structure in the markup. By utilizing the content of the headers, you can dynamically generate the item template through a v-for loop like the snippet below:

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="desserts"
      hide-actions
      class="elevation-1"
    >
      <template slot="items" slot-scope="myprops">
        <td v-for="header in headers">
        {{ myprops.item[header.value] }}
        </td>
      </template>
    </v-data-table>
  </v-app>
</div>

Answer №2

Although this question is dated, I encountered the same issue and chanced upon this page. I was able to resolve my problem by adjusting Bart's code to align with the most recent syntax in Vue 2.

<v-data-table :headers="headers"
 :items="myDataObject"
 class="elevation-24">
    <template v-slot:body="props">
      <tr v-for="index in props.items">
        <td v-for="header in headers" class="text-left font-weight-black">
          {{ index[header.value]}}
        </td>
      </tr>
    </template>
</v-data-table>

Answer №3

Try out this method that I have successfully used before. To understand how it works, delve into the concept of dynamic components in Vue.js.

Beware: It may seem overwhelming to configure each data-bound item individually, but it could prove beneficial if dealing with multiple data tables. Stay persistent and don't give up!

To customize the headers, utilize the headers scoped-slot. Refer to the documentation for detailed information here. Explore the scoped slots tab to understand your customization options.

For configuring columns, employ dynamic components. As a suggestion, decide on the component based on the type of column in your data table - for instance, return <td>text</td> for text columns. The choice is yours when it comes to configuration.

<v-data-table
  v-model="tableRowsSelected" 
  :items="tableItems"
  :headers="tableHeaders"
  :pagination.sync="tablePagination" 
  :rows-per-page-items="tablePaginationDropdown"
  item-key="name" 
  class="elevation-1"
> 
   <template v-if="tableHeaders" slot="headers" slot-scope="row">
    <tr>
      <th
        v-for="header in row.headers"
        :key="header.text"
        :class="['column sortable', tablePagination.descending ? 'desc' : 'asc', header.value === tablePagination.sortBy ? 'active' : '']"
        @click="changeSort(header.value)"
      >
        <v-icon small>arrow_upward</v-icon>
        {{ header.text }}
      </th>
    </tr>
  </template>
  <template template slot="items" slot-scope="row">
      <tr>
        <component v-for="header in Object.keys(row.item)" :key="header" :is="getComponentByColumnType(header, row.item)"></component>
      </tr>
  </template>

export default {
data () {
 return {
        tableItems: []
 }
 computed: {
  tableHeaders: function () { }
  tablePagination: functin() {}
  // and other properties here or you could simply configure them as part of 
  data.
  },
  method:{
    getComponentByColumnType(header, data) {
     // return the component per your column type here.
    }
  }
}

Answer №4

I'm not sure about your question, but it seems like you're looking to create a Vuetify table.

Here is the template for that:

<template>
  <v-data-table
    :headers="headers"
    :items="items"
    hide-actions
    class="elevation-1"
  >
    <template slot="items" slot-scope="props">
      <td>{{ props.item.name }}</td>
      <td class="text-xs-right">{{ props.item.calories }}</td>
      <td class="text-xs-right">{{ props.item.fat }}</td>
      <td class="text-xs-right">{{ props.item.carbs }}</td>
      <td class="text-xs-right">{{ props.item.protein }}</td>
      <td class="text-xs-right">{{ props.item.iron }}</td>
    </template>
  </v-data-table>
</template>

And here is the accompanying script:

<script>
  export default {
    data () {
      return {
        headers: [
          {
            text: 'Dessert (100g serving)',
            align: 'left',
            sortable: false,
            value: 'name'
          },
          { text: 'Calories', value: 'calories' },
          { text: 'Fat (g)', value: 'fat' },
          { text: 'Carbs (g)', value: 'carbs' },
          { text: 'Protein (g)', value: 'protein' },
          { text: 'Iron (%)', value: 'iron' }
        ],
        items: [
          // Data entries omitted for brevity
        ]
      }
    }
  }
</script>

This content is taken directly from the Vuetify documentation.

If you want to use dynamic headers, simply adjust the headers property accordingly.

I suggest utilizing Vuetify multiple select in conjunction with your table. Populate the multiple select with table columns and let the user select or deselect them. Then in the data-table's :headers, use the corresponding property from the multiple select.

For example, if the multiple select is bound to e6 (property name), then the v-data-table will appear as follows:

<v-data-table
    :headers="e6" /*this changed*/
    :items="items"
    hide-actions
    class="elevation-1"
  >

Answer №5

If you're looking for a solution regarding resizing table columns in vuetify 2, I have created a sample codepen example for reference.

Check out the codepen example here

Sample Code:

HTML

<div id="app">

  <v-app id="inspire">
    <v-container>
      <v-row><v-btn @click="add">ADD</v-btn><v-btn @click="remove">REMOVE</v-btn></v-row>
    <v-data-table
      :headers="headers"
      :items="desserts"

    >
      <template v-slot:body="props">
       <tbody>
        <tr v-for="item in props.items">
          <td v-for="(header, index) in headers">
            <span v-if="index">{{ item.cols[index-1] }}</span>
            <span v-else>{{ item.name }}</span>
          </td>
        </tr>
       </tbody>
      </template>
    </v-data-table>


      </v-container>
  </v-app>
</div>

JS

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      index: 0,
      headers: [
        {
          text: 'Name',
          align: 'start',
          sortable: true,
          value: 'name',
        },
        { text: '1', value: 'calories', align: 'start' },
        { text: '2', value: 'fat', align: 'start' },
        { text: '3', value: 'carbs', align: 'start' },
        { text: '4', value: 'protein', align: 'start' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          cols:[0,0,0,0]
        },
        {
          name: 'Ice cream sandwich',
          cols:[0,0,0,0]
        },
        {
          name: 'Eclair',
          cols:[0,0,0,0]
        },
        {
          name: 'Cupcake',
          cols:[0,0,0,0]
        },
        {
          name: 'Gingerbread',
          cols:[0,0,0,0]
        },
        {
          name: 'Jelly bean',
          cols:[0,0,0,0]
        },
        {
          name: 'Donut',
          cols:[0,0,0,0]
        },
        {
          name: 'KitKat',
          cols:[0,0,0,0]
        },
      ],
    }
  },
  mounted(){
    this.index = this.headers.length
  },
  methods:{
    add(){
      this.desserts.forEach(item => { item.cols.push(0) })
      this.headers.push({text:this.index, value:this.index})
      this.index++
    },
    remove(){
      let header = this.headers.pop()
      this.desserts.forEach(item => { item.cols.pop() })
      this.index--
    },

  }
})

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

Responsive left and right image styling in CSS and HTML

I have designed a landing page with fixed left and right images and content in the middle. It looks fine on desktop view, but on mobile view, the images are overlapping the content. How can I resolve this issue? <div class=" ...

Preserving scroll position when updating a partial page template using Rails and AJAX

When I am utilizing long polling, I encounter an issue where every time I use AJAX to refresh a page partial inside a scrollable div, the contents automatically scroll to the top. Is there any way to load the partial while maintaining the current scroll ...

AJAX error encountered: TypeError - the properties 'arguments', 'callee', and 'caller' are inaccessible in the current context

While conducting an API call on a particular system, I encountered an error. Interestingly, I am able to obtain a response using curl and Postman with the same URL; however, Safari throws this error when employing Angular's $http.get() method. The is ...

What is the best method for storing a third-party image in cache?

Running my website, I aim to achieve top-notch performance scores using LightHouse. I have successfully cached all the images I created (Cache-Control: public, max-age=31536000). Unfortunately, third-party website images are not cached. How can I cache t ...

Various style sheets are used for the production and staging environments

Is there a way to set up different styles for staging in node environments? Let's say I have the following scss files: scss/style.scss scss/theme.scss scss/green.scss After compiling, it gives me: style.scss Now, I'd like to change the style ...

Is it possible to animate the innerHTML of a div using CSS?

In my HTML file, I have these "cell" divs: <div data-spaces class="cell"></div> When clicked, the innerHTML of these divs changes dynamically from "" to "X". const gridSpaces = document.querySelectorAll("[data-spaces]"); f ...

Unable to perform navigation during page load in a React.js application

I attempted to navigate to a route that should redirect the user back to the homepage when postOperations isn't set in the localStorage. To save time, please review the code snippet focusing on the useEffect and the first component inside return(). im ...

Leveraging trustAsHTML with an array of object elements

I'm facing a challenge in passing an array of objects from an Angular Controller to the ng-repeat directive. The objects within the array have multiple properties, some of which may contain HTML that needs to be displayed using the ng-repeat. I' ...

The onclick button in React is not triggering

I am currently working on a component that processes card clicks and redirects users to a previous route, however, the OnClick function does not seem to be functioning properly. I'm trying to pinpoint where I might be going wrong. function Character ...

Utilizing JavaScript variable modifiers for enhanced functionality

I'm trying to find a way to perform a case-insensitive search for a variable within a string. To achieve this, I'm using the /gi modifier to ignore case sensitivity. However, the challenge arises because identifiers only accept direct strings rat ...

Automatically create CSS properties for left and top using absolute positioning

When looking at these websites as models: On each of them, I noticed that there is a well-organized column of boxes for every post. I attempted to recreate this using various methods, but couldn't achieve the exact layout on my own website. It seems ...

Ways to leverage the power of Reactivity APIs in Vue.js

In my Vue application, I am trying to create a Drop Down Menu by using a variable called "showDropDown". The idea is to use a v-if directive to check if the value of showDropDown is true, and then display the menu accordingly. Additionally, I want to imp ...

Cancellation of event by keypress handler

I found this code snippet: jQuery('#parent').on('keypress', '.textbox', function(e) { var btn = jQuery(this).closest('tr').find('.btn'); if (btn.length) { btn.triggerHandler('click&apo ...

A method for displaying both the next and previous steps without relying on a switch case statement

I have an array list as follows: const data = [ { title: 'Title1', }, { title: 'Title2', }, { title: 'Title3', }, { title: 'Title4', ...

Is there a way to send a post request containing a base64 encoded image?

I am currently developing an image upload component in Vue.js that includes a custom cropping option. The cropped version of the image is saved in my state as a base64 string, like this: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAHgCAYAAAB91L6 ...

Is there a way to enlarge the font size for a complete tag?

I'm having trouble with a project. One of the tasks is to use jQuery or JavaScript to increase the font size of a paragraph. The console statements are incrementing by +1 with every mouse click (the first click adds 1, the second adds 2, and so on). ...

Adjust form elements dynamically depending on the selected option in a dropdown menu using Ruby on Rails

I currently have the following database tables set up: Departments ID| Department_name | Manager_ID Employees ID| Name | Department_ID Salaries ID| Employee_ID | Salary_Amount The departments table holds information about different departments within t ...

Accessing API using Next.js 14

I am facing an issue with the following code which is written in next.js. The error displayed on the console is: GET http://localhost:3000/products/porducts.json 404 (not found) Additionally, I'm encountering this error: Uncaught (in promise) SyntaxE ...

In order to extract a value from a different webpage, I must first make a request to that webpage and extract the XML value from it

I have been working on a project that requires displaying currency exchange rates. To achieve this, I initially tried using AngularJS to call another webpage for the exchange rate values, but I encountered issues as AngularJS can only make JSON/Rest URL ca ...

Mapping fields in Spring to JSON can be tricky, especially when dealing with fields that can be

In my object, there is a String value field which can contain either true or false. The issue arises when Spring/Jackson maps this to value: "true" as a String, causing problems with certain angularjs ng-model mappings that expect a boolean. Is there a way ...