Create an intricate table design using CSS grid and incorporate nested vue v-for loops for dynamic content rendering

I have data that is nested and I want to display it in a tabular format. Here is an example of the data; in the actual application, there could be dozens of entries in rows.

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

  data () {
    return {
      results: [
        { a: 'AAA', rows: { BBB: 'CCC' } },
        { a: 'D', rows: { E: 'F', G: 'H' } },
        { a: 'Tom, Dick & Harry', rows: { x: 'y' } },
      ],
    }
  },
}
</script>

Please note: the inner values ('CCC', 'F', 'H', 'y') may end up being further nested arrays or objects.

I attempted to create a grid layout using v-for loops:

<template>
<div style="width:100%">
  <div v-for="(res,key) in results" :key="key" class="results">
    <div class="A">{{res.a}}</div>
    <div v-for="(c,b) in res.rows" :key="b">
      <div class="B">{{b}}</div>
      <div class="C">{{c}}</div>
    </div>
  </div>
</div>
</template>
<style scoped>
.results {display:grid;grid-template-columns: 1fr 1fr;}
.A {font-weight:bold;grid-column:1/3;}
.B {grid-column:1;padding:0.5rem;}
.C {grid-column:2;padding:0.5rem;}
</style>

(Note: the more logical grid-column:1/2, to span two columns, doesn't seem to work...)

This grid layout does not show the correct structure, so I have included a traditional table layout at the end to demonstrate what I am aiming for.

https://i.sstatic.net/lPKbx.png

Is this issue due to a simple bug? Or is there a better approach to combining vue and grid layouts? Keep in mind that I might need to implement a third v-for loop as mentioned earlier.

Just for reference, here is the HTML code for the table:


  <table border="1" cellspacing=0 style="width:100%;">
    <tr>
      <td colspan="2"><b>AAA</b></td>
    </tr>
    <tr>
      <td>BBB</td>
      <td>CCC</td>
    </tr>
    <tr>
      <td colspan="2"><b>D</b></td>
    </tr>
    <tr>
      <td>E</td>
      <td>F</td>
    </tr>
    <tr>
      <td>G</td>
      <td>H</td>
    </tr>
    <tr>
      <td colspan="2"><b>Tom, Dick & Harry</b></td>
    </tr>
    <tr>
      <td>x</td>
      <td>y</td>
    </tr>
  </table>

Answer №1

By chance, I stumbled upon a solution for effectively handling vue v-for loops without generating DOM elements, which happened to be exactly what I needed in this case.

To elaborate on the issue that led to an incorrect layout: CSS grids require applying the layout to the child elements of the grid container. Unfortunately, there is no flexibility in this regard, with no option to exclude a div from the layout.

The workaround involved switching the inner <div v-for=""> to

<template v-for="">

<template>
<div style="width:100%">
  <div v-for="(res,key) in results" :key="key" class="results">
    <div class="A">{{res.a}}</div>
    <template v-for="(c,b) in res.rows">
      <div class="B" :key="b">{{b}}</div>
      <div class="C" :key="'_'+b">{{c}}</div>
    </template>
  </div>
</div>
</template>

The only downside is that you cannot assign the :key directly to the <template> tag as it does not get rendered. Therefore, every child element within the <template> must have a unique :key. In the provided example, a workaround was implemented to address this issue.

In my specific application, I omitted those two :key definitions and used

<!-- eslint-disable vue/require-v-for-key -->
to suppress eslint warnings. From what I understand, replacing the entirety of res should not pose any issues if it changes. However, it is advisable to use :key wherever necessary if uncertain.

Answer №2

Consider using arrays instead of objects:

new Vue({
  el: '#demo',
  data () {
    return {
      results: [
        { a: 'AAA', rows: [{id:'BBB'}, {id:'CCC', more: [{id: '1'}, {id: '2'}]}] },
        { a: 'D', rows: [{id:'E'}, {id:'F', more: [{id: '1'}, {id: '2'}]}, {id:'G'}, {id:'H', more: [{id: '1'}, {id: '2'}]}] },
        { a: 'Tom, Dick & Harry', rows: [{id:'x'}, {id:'y', more: [{id: '1'}, {id: '2'}]}] },
      ],
    }
  },
})


Vue.config.productionTip = false
Vue.config.devtools = false
.results {display:grid;grid-template-columns: 1fr 1fr;}
.A {font-weight:bold;grid-column:1/3;}
.B {grid-column:1;padding:0.5rem;}
.C {grid-column:2;padding:0.5rem;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">

<div style="width:100%">
  <div v-for="(res,key) in results" :key="key" class="results">
    <div class="A">{{res.a}}</div>
    <div v-for="(c,b) in res.rows" :key="b">
      <div class="B">{{c.id}}</div>
      <div v-for="(z,i) in c.more" :key="i">
        <div class="C">{{z.id}}</div>
      </div>
    </div>
  </div>
</div>
      
</div>

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

Vue: The past event target value is returning an empty string when I attempt to paste for the first time

When I paste a string into my input field, it initially appears empty. However, if I paste the same string again, it shows me the previously pasted value. How can I capture the first paste value instead? <template> <v-app> <h3> ...

Diverse Values within the Inner Border

Is it possible to create an inner border with unique values for each side? For instance: Top: 20px Right: 80px Bottom: 40px Left: 10px Can you provide an example of how this can be achieved? Thank you! :) ...

What is the best way to shorten string values that exceed a certain length?

Here is an array list I have: $myarray = array( array( 'name' => 'File name 1 - type.zip', 'size' => '600KB', ), array( 'name' => 'File name 2 - type.pdf&a ...

Endless rotation with stunning magnification feature

My goal is to create a responsive carousel with auto-play infinite loop functionality, where the center item always occupies 70% of the viewport width. Currently, I have achieved a similar result using the Slick library: https://codepen.io/anon/pen/pBvQB ...

Revolving mechanism within React.js

I am currently developing a lottery application using React.js that features a spinning wheel in SVG format. Users can spin the wheel and it smoothly stops at a random position generated by my application. https://i.stack.imgur.com/I7oFb.png To use the w ...

Confusion between Codeigniter's URL and base_url() function

$config['base_url'] = 'localhost/project'; <link href="<?= base_url(); ?>/css/bootstrap.min.css" rel="stylesheet"> An issue arises with the CSS not loading on the view due to a double '/' in the URL. This occur ...

XSLT causing a colon conflict in Vue.js component creation process

I have been working on converting XML to a Vue.js template, but I am facing difficulty when trying to create a v-tooltip component from Vuetify. The XSLT code snippet provided below is supposed to generate the desired output: <xsl:element name="v- ...

"Trouble with the functionality of Animate.css fliptext when triggered by button click

I want to implement a flip animation on text when a button is clicked. I am using the 'flipInY' animation from animate.css library, but it's not working as expected. The desired animation can be seen in the example provided in this link: He ...

Using parameters in NativeScript-Vue

I'm having trouble passing parameters to another route in Nativescript. Every time I try, it shows up as undefined. I am using the nativescript-vue-navigator. On my current screen, I have this function call: this.$navigator.navigate('/map' ...

Ways to implement changes to a variable using an external file while the application is running in production

Currently working on a web page built using .Net Core 2.1 and Vue. I am looking for guidance on how to maintain a config file similar to Net Core's appsettings.json while making changes to a specific variable when the web application is in production ...

Filtering a combination column in Vue using Good Table

I am customizing a vue-good-table by creating composite columns and limiting the number of displayed columns. However, I ran into an issue with the filter function which takes the column name as an argument. This limits my ability to filter based on multip ...

How to successfully submit an array using Vue.js

Having an issue with a form that allows users to enter multiple inputs of the same field as an array. However, encountering two errors when trying to submit the form. Error 1 : The value always returns as 'undefined', possibly due to incorrect a ...

Setting table row styles for odd and even rows, based on user clicks of an <input type="file"> button

I'm currently working on a feature that allows users to upload files to a page using an button. Each file is displayed in a table as a new row. I am looking for a way to set the background color differently for odd and even rows. As of now, I am usin ...

The text in my image is positioned away from the top

Hi there, I am new to exploring HTML and CSS and I have been trying to display some images and text on a webpage. My goal was to have the text appear next to the image, which is working fine. However, I am encountering an issue where the text aligns itself ...

Effective ways to sort material cards in Angular

Can someone guide me on how to implement a search bar in my Angular application to filter cards by name? Here is the link to my Stackblitz project for reference: https://stackblitz.com/edit/stackoverflowcom-a-60857864-6433166-dpaump Below is a snippet fro ...

Adjust the background color of a cell depending on its value - Implementing with VueJs and Vuetify

I am currently extracting data from a JSON file. My goal is to change the cell color to green if the value is "OK" and to red if the value is "KO". Currently, I have implemented a v-simple-table as shown below: <td :class="OK? 'primary' : &apo ...

The vertical navigation sub-menu is designed to overlap the div container for a

I'm having an issue with my sidepanel vertical navigation where sub-menus are not being displayed properly due to a div container. The width of the div container [side-panel-links] is causing the sub-menus and children of the sub-menus to be cut off. ...

Ways to adjust the text size in jqGrid?

The current theme is ui-lightness. How can I adjust the font size within the grid? Your suggestions are appreciated. Many thanks. ...

Webkit browsers do not properly clip content with rounded corners when using position:relative

In webkit browsers like Chrome, rounded corners do not properly cut off content when using position:relative; Check out this demonstration. Here is the HTML: <div class="outer"> <div class="inner"> </div> <div> And here ...

Chrome browser hover malfunction issue

The menu plugin I am using on my website opens submenus when hovering over main items. While it works fine on the Firefox browser, on Chrome the submenu does not appear in the desired location (Please see attached screenshot). What's even stranger is ...