0

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
  },
4
  • You're looking to something like in my answer here Commented Nov 19, 2020 at 20:36
  • Hi there , I tried to put an index into the params but I don't know how to use the method in the correct way (updated answer). Thanks! Commented Nov 19, 2020 at 20:54
  • what do you mean by text? is it a data property? Commented Nov 19, 2020 at 20:58
  • Sorry it was only for testing purposes, fixed question Commented Nov 19, 2020 at 20:59

1 Answer 1

1

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);
     }
  },
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot Zugor, I'm trying to implement this in my Rails app
You are welcome. May be you can accept the answer if it's a correct answer for you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.