Home > Back-end >  How to change the border variant of a selected Bootstrap Vue card when clicked in v-for
How to change the border variant of a selected Bootstrap Vue card when clicked in v-for

Time:04-08

I have my b-card and v-for showing and functioning mostly as desired, the one issue I'm running into is changing the border-variant of a card that is selected. So far I have tried nesting the v-for that was inside the card in a div container and then using a v-if to check and see if a card has been selected. This code changes the border variant in the way I would like, but I only want the selected card to change its border variant. The code working as described above is shown below.

<div v-for="(team, index) in teams" :key="index">
    <b-card
        v-if="selected"
        img-src="https://picsum.photos/600/300/?image=25"
        img-alt=""
        v-model="selected"
        border-variant="success"
        img-bottom
        no-body
        
        body-
        >
            <b-row  align-h="center"> 
                <b-link  @click="functionThatChangesColorAndDoesOtherStuff(stuff)"><b-icon icon="plus-circle" font-scale="2.5"></b-icon></b-link>
            </b-row>
    </b-card>

    <b-card
        v-else
        img-src="https://picsum.photos/600/300/?image=25"
        img-alt=""
        v-model="selected"
        img-bottom
        no-body
        
        body-
        >
            <b-row  align-h="center"> 
                <b-link  @click="functionThatChangesColorAndDoesOtherStuff(stuff)"><b-icon icon="plus-circle" font-scale="2.5"></b-icon></b-link>
            </b-row>
    </b-card>
</div>

The selected property is on my data() and I have a function that we'll call functionThatChangesColorAndDoesOtherStuff() where that selected property gets toggled. The method's code is as shown below

data() {
    return {
        teams: [],
        selected: false
    }
}
 functionThatChangesColorAndDoesOtherStuff(stuff) {
    this.selected = !this.selected
    \\\Business logic below that does business stuff with the stuff
 }

I've also tried utilizing the index in the v-for, but that didn't even get me to the point where the color was changing at all. This makes me think I'm not using it properly and I would like some help with how I can accomplish this effect. I've checked around SO and haven't seen an example similar to my situation which I will reiterate again. I would like to click the plus button and have the selected card's border variant change.

CodePudding user response:

Please take a look at following snippet: you can bind border like: :border-variant="selected === index ? 'success' : 'danger'" , and pass index to function.

new Vue({
  el: '#demo',
  data() {
    return {
      teams: [1,2,3],
      selected: []
    }
  },
  methods: {
    functionThatChangesColorAndDoesOtherStuff(idx) {
      if (this.selected.includes(idx)) {
        this.selected = this.selected.filter(s => s !== idx)
      } else this.selected.push(idx)
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
  <div v-for="(team, index) in teams" :key="index">
    <b-card
      img-src="https://picsum.photos/600/300/?image=25"
      img-alt=""
      v-model="selected"
      :border-variant="selected.includes(index) ? 'success' : 'danger'"
      img-bottom
      no-body
      
      body-
      >
      <b-row  align-h="center"> 
        <b-link  @click="functionThatChangesColorAndDoesOtherStuff(index)"><b-icon icon="plus-circle" font-scale="2.5"></b-icon></b-link>
      </b-row>
    </b-card>
  </div>
</div>

CodePudding user response:

Firstly instead of using v-if and v-else just for a class name use the following

:

The first value has to be a truthy value. The following are your class names that will be applied based on the value.

  • Related