[Vuejs]-Why the child table(toggle-table) is repeating whenever clicked on the row of the parent table?

3πŸ‘

βœ…

  var app = new Vue({
  el: "#app",
  data(){
    return {
    opened:[],
    stateGDP: [
        { State: "Rajasthan", "1999-00": "2547", "2000-01": "3679",Id:"23" },
        { State: "Orissa", "1999-00": "38714", "2000-01": "38814",Id:"24" }
      ],
      DistrictGDP: [
        {
          State: "Rajasthan",
          District: "Jaipur",
          "1999-00": "2547",
          "2000-01": "3679",
          Id:"23"
        },
        {
          State: "Rajasthan",
          District: "Jodhpur",
          "1999-00": "2557",
          "2000-01": "3639",
          Id:"23"
        },
        {
          State: "Orissa",
          District: "Bhubaneswar",
          "1999-00": "1983",
          "2000-01": "2068",
          Id:"24"
        },
        {
          State: "Orissa",
          District: "Puri",
          "1999-00": "1923",
          "2000-01": "2008",
          Id:"24"
        }
      ]
      }
    },
  methods:{
    toggle:function(Id) {
    const index = this.opened.indexOf(Id);
    if (index > -1) {
      this.opened.splice(index, 1)
    } else {
      this.opened.push(Id)
    }

 },
    getRows(id) {
      return this.DistrictGDP.filter(district => district.Id === id);
    }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js">. 
</script>
<div id="app">
  <div class="table">
    <table class="table-fill">
      <thead>
        <tr>
          <th class="text-center">State/UT</th>
          <th class="text-center">1999-00</th>
          <th class="text-center">2000-01</th>
        </tr>
      </thead>
      <template v-for="row in stateGDP" :class="{ opened: opened.includes(row.Id) }">
        <tr @click="toggle(row.Id)" style="background-color: #D3D3D3">
          <td>{{ row.State }}</td>
          <td>{{ row["1999-00"] }}</td>
          <td>{{ row["2000-01"] }}</td>
        </tr>
        <template
          v-if="opened.includes(row.Id)"
        >
          <thead>
            <tr>
              <th class="text-center">District</th>
              <th class="text-center">1999-00</th>
              <th class="text-center">2000-01</th>
            </tr>
          </thead>
        <tr v-for="(district, index) in getRows(row.Id)">
          <td colspan="1">{{district.District}}</td>
          <td colspan="1">{{district['1999-00']}}</td>
          <td colspan="1">{{district['2000-01']}}</td>
        </tr>
        </template>
      </template>
    </table>
  </div>
</div>

   

Now the explanation, in order to get the rows that you want to show on click, you are doing a v-for loop, and recreating the header and the whole nested table the same amount of times that the DistrictGDP exist with the same Id that stateGDP (two times in this case).

I removed that v-for (the second one in the whole code) and for render the nested table rows I added a method, getRows, this method filters the required rows based in the row.Id, that way the table doesn’t need to compare if the id in the DistrictGDP is the same in the stateGDP.

Please, if I’m not being clear, let me know.

Leave a comment