Search code examples
javascriptvue.jsvuejs2vue-componentquasar

Render q-table within another row q-table as a child


The goal is to render lists within items in another list; for example a list of chapters with the respective titles.

This is usually done relatively easily with q-list.

However, I need to do this with q-tables.

I tried the following solution, but I am having some difficulties with v-for.

<div id="q-app">
  <div class="q-pa-md">
    <q-table
      :data="data"
      :columns="columns"
      row-key="name"
    >

      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-btn size="sm" color="accent" round dense @click="props.expand = !props.expand" :icon="props.expand ? 'remove' : 'add'" />
          </q-td>
          <q-td
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.value }}
          </q-td>
        </q-tr>
        
        <q-tr 
            :props="props"
            v-show="props.expand" 
            v-for="item in data"
          >  
            <q-table                                      
               hide-header
               hide-bottom
               :data="item.childs"
               :columns="columnsChilds"
               style="background:yellow"> 
          </q-table>    
        </q-tr>
      </template>
    </q-table>
  </div>
 </div>

CODE PEN https://codepen.io/ijose/pen/eYzawpx

Thanks.

EDITED: Data is received at the client side as follows

data:[
0:{
  name:'yogurt',
  childs:[
      0:{name:'one},
      1:{name:'two}
  ]
},
1:{
  name:'yogurt two',
  childs:[
      0:{name:'three},
      1:{name:'four}
  ]
},
]

Solution

  • The nested child data is an array with just one object and a duplicated property name. It should be an array of objects:

    data: [{
      name: 'Frozen Yogurt',
      childs: [
        { name: 'one' },
        { name: 'two' },
        { name: 'three' }
      ]
    }, {
      name: 'Ice cream sandwich',
      childs: [
        { name: 'four' },
        { name: 'five' },
      ]
    }, {
      name: 'Eclair',
    }]
    

    Since the q-table takes an array of data, you don't need a v-for on the inner table (same as the outer). Remove the v-for and set the data to the current outer row's childs object:

    <q-tr :props="props" v-show="props.expand">  
        <q-table                             
            hide-header
            hide-bottom
            :data="props.row.childs"
            :columns="columnsChilds"
            style="background:yellow; min-width:300px"> 
        </q-table>    
    </q-tr>