Dynamic cell loading in Vue using Vuetify's datatable functionality

<template>
  <v-data-table
    :headers="headers"
    :items="records"
    :items-per-page="5"
    show-select
    loading
    item-key="id"
    class="elevation-1"
  >
    <template v-slot:top>
      <div>
        <table-tabs></table-tabs>
        <v-text-field
          append-icon="mdi-close"
          class="mx-4"
          flat
          hide-details
          label="Search"
          prepend-inner-icon="mdi-magnify"
          solo-inverted
        ></v-text-field>
      </div>
    </template>
    <template v-slot:item.id="{ item }">
      <product-instance-cell v-bind:item="item" :data="item"></product-instance-cell>
    </template>
    <template v-slot:item.boxCode="{ item }">
      <serial-cell v-bind:boxCode="item.boxCode" :serial="item.boxCode"></serial-cell>
    </template>
    <template v-if="hasField('manager')" v-slot:item.manager="{ item }">
      <user-cell v-bind:user="item.manager" :user="item.manager"></user-cell>
    </template>
    <template v-slot:item.customer="{ item }">
      <customer-cell v-bind:customer="item.customer" :customer="item.customer"></customer-cell>
    </template>
    <template v-slot:item.updatedAt="{ item }">
      <date-cell v-bind:updatedAt="item.updatedAt" :date="item.updatedAt"></date-cell>
    </template>
  </v-data-table>

I must pass the field's name and cell component below the template to create custom cells for specific models and fields.

   <template v-slot:item.id="{ item }">
      <product-instance-cell v-bind:item="item" :data="item"></product-instance-cell>
    </template>

However, I want to dynamically load the cells because my table does not have a specific model usage. The table can display 5 different types of models Array<T> and I have a "table spec" that contains all the necessary information to create the table, such as header cell names, sorting logic, maximum row count, and cell component names by model and field.

Dealing with the data table header that does not require another template is easy, and the entire template code above works for only one model. For a super dynamic table with spec data, I am looking to create a solution. How can I achieve this?

I am open to other Vue's philosophical approaches, even if they are not specific solutions for this particular case.

Answer №1

Today, I tackled a similar challenge by creating a highly dynamic table that customizes its rendering for each model, but with certain common columns, referred to as v-slot:item.<name>.

For this purpose, I have a shared headers JSON object containing all the properties that the table should render for every model. Here is an example snippet:

"headers": [
    { "text": "Date / Time", "value": "date", "filterable": true, "sortable": true, "type": "text-date", "align": "left", "format": "YYYY-MM-DD HH:MM" },
    { "text": "Upload Type", "value": "upload_type", "filterable": true, "sortable": false, "type": "text", "align": "center" },
    { "text": "Elements", "value": "elements", "filterable": true, "sortable": false, "type": "text" },
    { "text": "Received and Validated", "value": "status", "filterable": true, "sortable": false, "type": "chip", "style": [{ "color": "red", "value": "ERROR" }, { "color": "green", "value": "OK" }] },
    { "text": "Log", "value": "log", "filterable": false, "sortable": false, "type": "icon", "icon": "mdi-magnify", "event": "click", "action": "openDialog" },
    { "text": "Uploaded File", "value": "uploaded_file", "filterable": false, "sortable": false, "type": "icon", "icon": "mdi-file", "event": "click", "action": "downloadJSONFileFromJSONData", "url": "xxxxxxxx", "filename": "YYYY-MM-DD-filename.json" }
]

To render all the columns with the same header type like icon or text, chip, etc., I treated them uniformly.

To achieve this without explicitly naming each header, I implemented computed properties that filter the header slots based on their types:

computed: {
  computedHeaders: function () {
    // Filters the headers of type Icon
    return this.headers.filter(header => header.type === 'icon');
  }
}

This approach allows me to render all the slots sharing something in common but with different naming conventions:

<template v-for="(head, i) in computedHeaders" v-slot:[`item.${head.value}`]="{ item }">
 <v-icon
    :key="i"
    v-text="head.icon"
  >
  </v-icon>
</template>

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

Observing rxjs Observable - loop through the results and exit when a certain condition is met / encountering an issue with reading property 'subscribe' of an undefined value

I'm fairly new to working with rxjs and I've been struggling to find the right operator for what I want to achieve. Here's my scenario - I have an array that needs to be populated with results from another observable. Once this array has en ...

The AJAX response is incorrect due to a PHP request, leading to the reloading

Whenever the 'signup' button is clicked, a function in my code initiates an HTML switch. The issue I am facing arises when I test for incorrect email or password during sign up. While I can successfully verify the data, it still loads the previou ...

Decode JSON and generate a user-friendly Array

My aim is to extract and organize the JSON data received from an external API into a custom array. However, I am encountering two challenges: I'm struggling to access the value labeled #2 under "Meta Data". If I want to extract the first array n ...

The Jquery animate function is not compatible with the transform property

I am facing an issue with the Jquery animate function. Despite trying various solutions, I have been unable to get it to work. Below is the HTML code that I have used: <!DOCTYPE html> <html lang="en"> <head> <meta cha ...

Using jQuery to alter behavior based on the specific id of an element

In my function, I have set it up to display different alerts based on the id when the button is clicked. However, I am facing an issue where the alert displayed does not change even though the id has been updated. $('#loginBtn').on('click ...

Is there a way to retrieve the ReturnType<T> for all methods within a class, even if the ReturnType<T> and its usage appear to be static?

After extensively reviewing the documentation on typescript at https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypet, I have come across two instances of ReturnType<T> mentioned. However, these instances appear to be statically ...

Updating or adding items to an array using underscore library

A scenario involves an object with incoming data and an array that contains saved data. The goal is to check if the "cnName" from the new data already exists in the "savedData" array. If it does, then the object in "savedData" should be replaced with the n ...

Tips for updating a nested MongoDB object

Looking to implement a reporting feature for my application When making a PUT request in the front end: .put(`http://localhost:3000/api/posts/report`, { params: { id: mongoId, ...

Unraveling strings containing components within a Vue.js template

Can a string with components be parsed into a template in vue.js? For example: "Some text, some <b>bold text</b>, and inserted image from this component <vue-simple-image :src='images/my_image_name.png' />, another text and ht ...

JSON returning issue with date formatting

After converting a date to a string using ToString("d") in C# and then serializing it into JSON for the client, I'm encountering an issue where instead of displaying the formatted date on the page, I see the following literal text: /Date(-62135575200 ...

Bringing in a selection of functions as an object using ES6 imports

functions.js export const setA = () => {...} export const setB = () => {...} export const setC = () => {...} component.js import {setA, setB, setC} from 'functions' export class componentOne extends React.Component { constructor(p ...

What advantages do binary shifts offer in enums?

What do you think about this code snippet? /** * Bitmask of states */ export const enum ViewState { FirstCheck = 1 << 0, // result is 1 ChecksEnabled = 1 << 1, // result is 2 Errored = 1 << 2, // result is 4 ...

Discovering the bottom scroll position in an Angular application

I am working on implementing two buttons on an Angular web page that allow the user to quickly scroll to the top and bottom of the page. However, I want to address a scenario where if the user is already at the very top of the page, the "move up" button sh ...

Tips for excluding test files in next.js when building

I am currently developing a next.js application with tests integrated within the page directory structure. In order to achieve this, I have made necessary configurations in the next.config.js file. const { i18n } = require('./next-i18next.config' ...

Exploring the concept of D3 data binding key accessor

Exploring D3 for the first time, I am working on a basic example to grasp the concept of data binding. My setup includes an array of colors, a function to add a color, and a function to remove a color based on index. However, I'm facing issues with t ...

Executing simultaneous asynchronous queries with Mongoose results in an error: `SyntaxError: Illegal return statement` due to

My goal is to make multiple asynchronous requests to Mongo using Mongoose in parallel. To achieve this, I created a helper function that handles these queries dynamically without knowing the exact number beforehand. While my current implementation works ...

When the class changes, V-for re-renders every component

Currently, I am in the process of changing classes for images based on their index using the moveIndex method and key events. While this works smoothly on computers, it seems to take significantly longer when implemented on TVs. The process runs smoothly w ...

Getting the most out of geometry vertices with Threejs: mastering partial transforms

In my current project, I am working with a mesh that consists of approximately 5k vertices. These vertices have been merged from multiple geometries into a flat array. Initially, I was able to modify individual vertices successfully by setting the flag `ve ...

Using Python Selenium to interact with elements on a web browser and make edits

Is there a way to modify an element in a web browser using Python 2.7 Selenium? Consider this element: <span id="some-random-number">100</span> While you can retrieve the text with: driver.find_element_by_id("some-random-number").text how c ...

How to implement a delay for submenu dropdown in Bootstrap 3

I am trying to implement a delay on a submenu that I have created, rather than the entire bootstrap3 dropdown menu. The goal is to allow users to easily move their cursor to the submenu without it closing unexpectedly. Although the jquery code should still ...