Devops Training
Devops Training

Reputation: 231

How to apply toggling / styles on a particular clicked card only in vue.js?

I developed one page DisplayBooks.vue which is responsible for displaying books the response is coming from backend API based on that data it will displayed in my UI page , in my UI page each card contains Two buttons(ADD TO BAG & ADDED TO BAG) when ever user click on any card ADD TO BAG button at that time it will hide ADDTOBAG and displays ADDED TO BAG button on a particular clicked card only , please help me to acheive this thing.

DisplayBooks.vue

<template>
<div class="carddisplay-section">
    <div v-for="book in books" :key="book.id" class="card book">
        <div class="image-section">
            <div class="image-container">
                <img  v-bind:src="book.file" />
            </div>
        </div>
        <div class="title-section">
            {{book.name}}
        </div>
        <div class="author-section">
            by {{book.author}}
        </div>
        <div class="price-section">
            Rs. {{book.price}}<label class="default">(2000)</label>
            <button v-if="flag" class="btn-grp" type="submit" @click="handlesubmit();Togglebtn();">close</button>
        </div>
        <div class="buttons">
            <div class="button-groups">
                <button type="button"  class="AddBag">Add to Bag</button>
                
            </div>
            <div  class="AddedBag">
                <button class="big-btn">Added to Bag</button>
            </div>
        </div>
    </div>

</div>
</template>

<script>
import service from '../service/User'

export default {
    data() {
        return {
           
            flag: true,
            state: true,
            clickedCard: '',
            books: [{
                id: 0,
                file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
                name: 'Dont Make me think',
                author: 'Sai',
                price: '1500'
            }, ]
        }
    },
    methods: {
       
        
        flip() {
            this.state = !this.state;
        },
        Togglebtn() {
            this.flag = !this.flag;
        },
        handlesubmit() {
            service.userDisplayBooks().then(response => {
                this.books.push(...response.data);     
            })
        },
    }
}
</script>

<style lang="scss" scoped>
    @import "@/styles/DisplayBooks.scss";
</style>

DisplayBooks.scss

@import "colors";
.carddisplay-section {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    align-content: space-around;
    gap: 10px;
}
.card:hover{
    box-shadow:0.6px 0.6px 0.6px 0.6px rgb(173, 206, 206);
}
.card {
    margin-top: 55px;
    margin-left: 110px;
    background:$pink;
    // width: 235px;
    // height: 275px;
    width: 235px;
height: 315px;
    background: $pale_white 0% 0% no-repeat padding-box;
    border: 1px solid $border_clr;
    border-radius: 3px;
    opacity: 1;
}

.image-section {
    width: 233px;
    height: 172px;
    background: #F5F5F5 0% 0% no-repeat padding-box;
    border-radius: 2px 2px 0px 0px;
    opacity: 1;
}

img{
    margin-left: 67px;
    margin-top: 17px;
    width: 105px;
    height: 135px;
    opacity: 1;
    border:none;
}

.title-section {
    text-align: left;
    font: normal normal normal 14px/19px Roboto;
    letter-spacing: 0.2px;
    color: $light_black;
    opacity: 1;
    margin-left: 20px;
    margin-top: 3px;
    width: 130px;
    height: 19px;
    text-transform: capitalize;
}

.author-section {
    text-align: left;
    font: normal normal normal 13px/13px Roboto;
    letter-spacing: 0px;
    color: $light_grey;
    opacity: 1;
    width: 123px;
    height: 13px;
    margin-left: 20px;
    margin-top: 7px;
}

.price-section {
    text-align: left;
    font: normal normal bold 12px/16px Roboto;
    letter-spacing: 0px;
    color: $light_black;
    opacity: 1;
    margin-left: 20px;
    height: 16px;
    margin-top: 26px;
    display: flex;
    justify-content: flex-start;

}

label {
    text-decoration-line: line-through;
    font: normal normal normal 10px/13px Roboto;
    letter-spacing: 0px;
    color: $light_grey;
    opacity: 1;
    width: 36px;
    height: 13px;
    margin-top: 2.5px;
    margin-left: 1em;
}

button[type="submit"] {
    border: none;
    padding-left: 65px;
    background: none;
    font-size: 15;
}
.button-groups{
    display:flex;
    margin-top:8px;
}
.AddBag{
    background: #A03037 0% 0% no-repeat padding-box;
    border-radius: 2px;
    opacity: 1;
    width: 93px;
    height: 29px;
    margin-left:20px;
    color: #FFFFFF;
    text-transform: uppercase;
    opacity: 1;
    font-size: small;
}
.wishlist{
    margin-left:4px;
    color: #FFFFFF;
    text-transform: uppercase;
    opacity: 1;
    font-size: small;
    border: 1px solid #7c7a7a;
    border-radius: 2px;
    opacity: 1;
    color: #0A0102;
    width:93px;
}
.big-btn{
    width: 191px;
height: 29px;
margin-left:20px;
background: #3371B5 0% 0% no-repeat padding-box;
border-radius: 2px;
opacity: 1;
color:#FFFFFF;
}
   

Upvotes: 1

Views: 59

Answers (1)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Add another array which will contain the books ids added by clicking on the button ADD To BAG then use v-if/v-else to make a conditional rendering :

    data() {
        return {
           
            flag: true,
            state: true,
            clickedCard: '',
            addedBooks:[],
            books: [....]
        }
    },

in the template :

    <div class="buttons">
            <div class="button-groups" v-if="!addedBooks.includes(book.id)">
                <button type="button"  @click="addedBooks.push(book.id)"  class="AddBag">Add to Bag</button>
                
            </div>
            <div  class="AddedBag" v-else>
                <button class="big-btn" @click="addedBooks=addedBooks.filter(id=>id!==book.id)">Added to Bag</button>
            </div>
        </div>

Example

new Vue({
  el: "#app",

  data() {
    return {

      flag: true,
      state: true,
      clickedCard: '',
      addedBooks: [],
      books: [{
          id: 0,
          file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
          name: 'Dont Make me think',
          author: 'Sai',
          price: '1500'
        },
        {
          id: 1,
          file: 'https://images-na.ssl-images-amazon.com/images/I/41MdP5Tn0wL._SX258_BO1,204,203,200_.jpg',
          name: 'Dont Make me think',
          author: 'Sai',
          price: '1500'
        },

      ]
    }
  },
  methods: {


    flip() {
      this.state = !this.state;
    },
    Togglebtn() {
      this.flag = !this.flag;
    },

  }
})
.carddisplay-section {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  align-content: space-around;
  gap: 10px;
}

.card:hover {
  box-shadow: 0.6px 0.6px 0.6px 0.6px rgb(173, 206, 206);
}

.card {
  margin-top: 55px;
  margin-left: 110px;
  background: $pink;
  // width: 235px;
  // height: 275px;
  width: 235px;
  height: 315px;
  background: $pale_white 0% 0% no-repeat padding-box;
  border: 1px solid $border_clr;
  border-radius: 3px;
  opacity: 1;
}

.image-section {
  width: 233px;
  height: 172px;
  background: #F5F5F5 0% 0% no-repeat padding-box;
  border-radius: 2px 2px 0px 0px;
  opacity: 1;
}

img {
  margin-left: 67px;
  margin-top: 17px;
  width: 105px;
  height: 135px;
  opacity: 1;
  border: none;
}

.title-section {
  text-align: left;
  font: normal normal normal 14px/19px Roboto;
  letter-spacing: 0.2px;
  color: $light_black;
  opacity: 1;
  margin-left: 20px;
  margin-top: 3px;
  width: 130px;
  height: 19px;
  text-transform: capitalize;
}

.author-section {
  text-align: left;
  font: normal normal normal 13px/13px Roboto;
  letter-spacing: 0px;
  color: $light_grey;
  opacity: 1;
  width: 123px;
  height: 13px;
  margin-left: 20px;
  margin-top: 7px;
}

.price-section {
  text-align: left;
  font: normal normal bold 12px/16px Roboto;
  letter-spacing: 0px;
  color: $light_black;
  opacity: 1;
  margin-left: 20px;
  height: 16px;
  margin-top: 26px;
  display: flex;
  justify-content: flex-start;
}

label {
  text-decoration-line: line-through;
  font: normal normal normal 10px/13px Roboto;
  letter-spacing: 0px;
  color: $light_grey;
  opacity: 1;
  width: 36px;
  height: 13px;
  margin-top: 2.5px;
  margin-left: 1em;
}

button[type="submit"] {
  border: none;
  padding-left: 65px;
  background: none;
  font-size: 15;
}

.button-groups {
  display: flex;
  margin-top: 8px;
}

.AddBag {
  background: #A03037 0% 0% no-repeat padding-box;
  border-radius: 2px;
  opacity: 1;
  width: 93px;
  height: 29px;
  margin-left: 20px;
  color: #FFFFFF;
  text-transform: uppercase;
  opacity: 1;
  font-size: small;
}

.wishlist {
  margin-left: 4px;
  color: #FFFFFF;
  text-transform: uppercase;
  opacity: 1;
  font-size: small;
  border: 1px solid #7c7a7a;
  border-radius: 2px;
  opacity: 1;
  color: #0A0102;
  width: 93px;
}

.big-btn {
  width: 191px;
  height: 29px;
  margin-left: 20px;
  background: #3371B5 0% 0% no-repeat padding-box;
  border-radius: 2px;
  opacity: 1;
  color: #FFFFFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="carddisplay-section">
    <div v-for="book in books" :key="book.id" class="card book">
      <div class="image-section">
        <div class="image-container">
          <img v-bind:src="book.file" />
        </div>
      </div>
      <div class="title-section">
        {{book.name}}
      </div>
      <div class="author-section">
        by {{book.author}}
      </div>
      <div class="price-section">
        Rs. {{book.price}}<label class="default">(2000)</label>
        <button v-if="flag" class="btn-grp" type="submit" @click="">close</button>
      </div>
      <div class="buttons">
        <div class="button-groups" v-if="!addedBooks.includes(book.id)">
          <button type="button" @click="addedBooks.push(book.id)" class="AddBag">Add to Bag</button>

        </div>
        <div class="AddedBag" v-else>
          <button class="big-btn" @click="addedBooks=addedBooks.filter(id=>id!==book.id)">Added to Bag</button>
        </div>
      </div>
    </div>

  </div>
</div>

Upvotes: 1

Related Questions