Gibson
Gibson

Reputation: 2085

Toggle button text on a loop VUE

I have a loop with products, each with a product card. I want to be able to toggle the button when clicked from Add to cart to Remove from cart.

The problem is all of the products buttons toggle at the same time, and I wan't ONLY the individual product card buttons to be toggled referencing each individual product.

In my HTML

      <div v-for="product of products" :key="product.id">
         <span class="btn btn-primary mt-5 modal-toggle-btn"  @click="addGift(product, text, 'index')" v-show="!isAdded">Añadir a la box</span>
         <span class="btn btn-primary mt-5 modal-toggle-btn" @click="removeGift(product, 'index')" v-show="isAdded">Quitar de la box</span>
      </div>

Vue data

isAdded: false

My Vue methods

  addGift(product, index){
     this.campaign.selectedproducts.push({name: product.name });
     this.isAdded = true
  },
  removeGift(product, index){
     this. campaign.selectedproducts.splice(index, 1)
     this.isAdded = false
  },

Upvotes: 0

Views: 426

Answers (1)

Zugor
Zugor

Reputation: 881

My suggestion is to:

  1. Divide the product buttons as an individual component.

  2. Use addedIds as an array to store added product ids instead of isAdded boolean.

  3. Communicate parent and child click events with Vue event handling.

  4. Store clicked product id in to the addedProductId on click events.

  5. Check against addedProductId to make sure a product was added or not in child component.

Example:

ProductButtons.vue (child component)

<template>
  <div>
    <span class="btn btn-primary mt-5 modal-toggle-btn"  @click="addGift" v-show="!isAdded">Añadir a la box</span>
    <span class="btn btn-primary mt-5 modal-toggle-btn" @click="removeGift" v-show="isAdded">Quitar de la box</span>
  </div>
</template>

<script>
export default {
  name: "ProductButtons",
  props: {
    product: { type: Object, required: true },
    addedIds: { type: Array, required: true },
  },
  computed: {
    isAdded() {
      return this.addedIds.indexOf(this.product.id) > -1;
    },
  },
  methods: {
    addGift(){
      this.$emit('addGift', this.product);
    },
    removeGift(product){
      this.$emit('addGift', this.product);
    },
  }
}
</script>

In Your HTML

<template v-for="product of products" :key="product.id">
    <product-buttons :product="product" :addedIds="addedIds" @addGift="addGift" @removeGift="removeGift"></product-buttons>
</template>

Vue data

addedIds: []

Your Vue methods

  addGift(product){
     this.campaign.selectedproducts.push({name: product.name });
     // save product id as an added id
     const index = this.addedIds.indexOf(product.id);
     if (index === -1) {
         this.addedIds.push(product.id);
     }
  },
  removeGift(product){
     this.campaign.selectedproducts.splice(index, 1);
     // remove product id
     const index = this.addedIds.indexOf(product.id);
     if (index > -1) {
         this.addedIds.splice(index, 1);
     }
  },

Upvotes: 1

Related Questions