1
votes

I'm using bootstrap-vue table for a project and got stuck on a problem with no documentation.

How can I toggle 1 row details at the time?

There is a complete table example here of a table with data on here

2
You ask a question and link the answer, which would be in the complete example. What is it specifically you don't understand about the example?Hiws
@Hiws show me the answer on the link, please :)Jonathan

2 Answers

4
votes

I'm using the v-model and setting it to a different array, as the v-model on b-table returns the currently shown items, after filtering and pagination. Making it more performance friendly as you're limiting the amount of items you gotta loop through to close.

window.onload = () => {
  new Vue({
    el: '#app',
    data() {
      return {
        items: [
          { id: 1, name: 'Povl', age: 26, gender: 'Male', secret: 'I love kittens' },
          { id: 2, name: 'Charlie', age: 9, gender: 'Female', secret: 'I love cupcakes' },
          { id: 3, name: 'Max', age: 71, gender: 'Male', secret: 'I love puppies' }
        ],
        currentItems: [],
        fields: [
          { key: 'name' }, { key: 'age' }, { key: 'gender' }, { key: 'actions' }
        ]
      }
    },
    methods: {
      //finds a specific item based on the provided ID and toggles details on that item
      toggleDetails(row) {
        if(row._showDetails){
          this.$set(row, '_showDetails', false)
        }else{
          this.currentItems.forEach(item => {
            this.$set(item, '_showDetails', false)
          })

          this.$nextTick(() => {
            this.$set(row, '_showDetails', true)
          })
        }
      }
    }
  })
}
<link href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>

<div id="app">
  <b-container class='pt-3'>
    <b-table :items="items" :fields="fields" v-model="currentItems" bordered fixed>
      <template v-slot:cell(actions)="{ detailsShowing, item }" >
        <!-- Use the built in method from the scoped data to toggle the row details -->
        <b-btn @click="toggleDetails(item)">{{ detailsShowing ? 'Hide' : 'Show'}} secret</b-btn>
      </template>
      <template v-slot:row-details="{ item }">
        <b-card>
          {{ item.secret }}
        </b-card>
      </template>
    </b-table>
  </b-container>
</div>
1
votes

@Hiws answer only works for me when I add @row-clicked listener to b-table.

I couldn't get it to work if is clicked through the actions slot, just like the example given. I changed the if condition as it was returning me an undefined which caused the logic to only run the else part

toggleDetails(row) {
  if (row.detailsShowing) {
    row.toggleDetails()
  } else {
    this.currentItems.forEach(item => {
      this.$set(item, '_showDetails', false)
    })
    this.$nextTick(() => {
      row.toggleDetails()
    })
  }
}