Search code examples
vue.jsvue-cli

how to get v-for loop data from outside of loop also in vue.js


I have a table which show product name and quantity and price and total price. I had written logic of total cost as formula cost *quantity. i have a button outside of table which is by default hidden by using v-if directive how can i make that button active if only at least one product quantity is greater than zero. By default i had given 0 as quantity because it will vary according to user. I have array of products in v-for loop i iterated as v-for="p in products" so quantity will be p.quantity. how can i use that p.quantity also from outside of loop

## Html table ##
<table class="table table-striped">
          <thead>
            <tr>
              <td>S.No#</td>
              <td>Product</td>
              <td>Cost</td>
              <td>Quantity</td>
              <td>Total</td>
            </tr>
          </thead>
          <tbody>
            <tr v-for="p in products">
              <td>1</td>
              <td>{{p.item}}</td>
              <td>{{p.cost}}</td>
              <td><input type="number" class="form-control qty-box" name="" v-model='p.qt'  min="0"></td>
              <td>{{p.cost*p.quantity}}</td>
            </tr>
          </tbody>
        </table>
        <div class="row">
          <div class="col-md-12">
            <center v-if="btn"><button class="btn btn-success">Confirm</button></center>
          </div>
        </div>
## Vue-cli Code ##
<script>
export default {
  name: 'app',
  data () {
    return {
      btn:false,
      counter:8,
      qty:0,
      proTotal:'',
      products:[
          {'item':'timber','cost':250,'id':1, 'quantity ':0},
          {'item':'wood','cost':240,'id':2, 'quantity ':0},
          {'item':'primer','cost':120,'id':3, 'quantity ':0},
          {'item':'plywood','cost':360,'id':4, 'quantity ':0},
          {'item':'marker','cost':220,'id':5, 'quantity ':0},
          {'item':'roughwood','cost':480,'id':6, 'quantity ':0},
      ],
      msg: 'Counter',
    }
  },
  mounted:function(){
    this.bill();
  },
  methods:{
    bill(){
      this.qty = this.p.quantity;
      if(this.qty>0){
        btn:true;
      }
    }
  }
}
</script>

Solution

  • That's a good use case for computed properties:

    computed: {
        showButton() {
          var showButton = false;
          this.products.forEach(product => {
            if (product.quantity > 0) {
              showButton = true;
            }
          });
          return showButton;
        }
      }
    

    Also, you have to add number to v-model so it's not stored as string.

    Your whole code would look like this:

    <template>
      <div id="about">
    
        <table class="table table-striped">
          <thead>
            <tr>
              <td>S.No#</td>
              <td>Product</td>
              <td>Cost</td>
              <td>Quantity</td>
              <td>Total</td>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(p, index) in products" :key="index">
              <td>1</td>
              <td>{{p.item}}</td>
              <td>{{p.cost}}</td>
              <td><input type="number" class="form-control qty-box" name="" v-model.number='p.quantity' min="0"></td>
              <td>{{p.cost*p.quantity}}</td>
            </tr>
          </tbody>
        </table>
        <div class="row">
          <div class="col-md-12">
            <p v-if="showButton">
              <button class="btn btn-success">Confirm</button>
            </p>
          </div>
        </div>
    
      </div>
    </template>
    
    <script>
    export default {
      name: "app",
      data() {
        return {
          btn: false,
          counter: 8,
          qty: 0,
          proTotal: "",
          products: [
            { item: "timber", cost: 250, id: 1, quantity: 0 },
            { item: "wood", cost: 240, id: 2, quantity: 0 },
            { item: "primer", cost: 120, id: 3, quantity: 0 },
            { item: "plywood", cost: 360, id: 4, quantity: 0 },
            { item: "marker", cost: 220, id: 5, quantity: 0 },
            { item: "roughwood", cost: 480, id: 6, quantity: 0 }
          ],
          msg: "Counter"
        };
      },
      computed: {
        showButton() {
          var showButton = false;
          this.products.forEach(product => {
            if (product.quantity > 0) {
              showButton = true;
            }
          });
          return showButton;
        }
      }
    };
    </script>