Search code examples
javascriptvue.jstoggle

Vue.js: Toggle CSS class for dynamical data with method


I have the following code:

<template>
<div id="projects">
  <Header />
  <b-container>
    <div class="row">
      <div :class="colSize" v-for="(data, index) in projects" :key="data._id">
        <b-card :title="data.name" :sub-title="user.jobresponsibilities">
          <p class="card-text">
            {{data.description}}
          </p>
          <b-btn v-b-toggle="'collapse'+index" @click="showCollapse(data)">Toggle Collapse</b-btn>
          <b-collapse :id="'collapse'+index">
            <b-card>
              description
            </b-card>
          </b-collapse>
        </b-card>
      </div>

    </div>
  </b-container>
</div>
</template>

<script>
import Header from '@/components/Header'
export default {
  name: 'dashboard',
  components: {
    Header
  },
  mounted() {},
  methods: {
    showCollapse(data) {
      this.colSize = 'col-8'
    }
  },
  data() {
    return {
      user: this.$store.getters.getUser,
      projects: this.$store.getters.getProject,
      colSize: 'col-4',
      show: false
    }
  }
}
</script>

<style lang="scss">
#projects {
    background-color: rgb(243, 243, 243);
}
</style>

Store.js: https://jsbin.com/kejinihoci/edit?js

enter image description here

What I want to achieve is that when I click on the toggle button, that the column size of the specific is changed (css class) and that it only show the collapsible for this item and not the other.

I tried to add an ID to the v-model to add it to my method but it did not work.


Solution

  • You should do something dynamic like assigning an unique id (id="'collapse'+index") to each collapse and use v-b-toggle directive inside the correspondent button v-b-toggle="'collapse'+index" :

       <b-btn v-b-toggle="'collapse'+index" class="m-1">Toggle Collapse</b-btn>
          <b-collapse id="'collapse'+index" >
            <b-card>
              description
            </b-card>
          </b-collapse>
    

    to make the class changes dynamically you should add a property called descShown to your projects array.

    in getProject action inside your store

            let project = resp.data.project
            project=project.map((p)=>{
                   p.descShown=false;
                   return p;
                   })
            commit('getProject_success', {
              project
            })
    

    inside template:

        <div :class="['col-8':data.descShown,'col-6':!data.descShown}" v-for="(data, index) in projects" :key="data._id">
    
       ...
      <b-btn v-b-toggle="'collapse'+index" @click="showCollapse(index)">
    

    your method should be like :

       showCollapse(index) {
            this.$set(this.projects,index,true);
         }