[Vuejs]-How to calculate values inside dynamic created elements

0๐Ÿ‘

โœ…

new Vue({
  el: "#app",
  data() {
    return {
      tableDatas: []
    };
  },
  methods: {
    btnOnClick(v) {
      this.tableDatas.push({
        itemname: "item",
        quantity: 1,
        sellingprice: 55,
        amount: 0
      });
    }
  },
  computed: {
    calculate() {
      return (
        this.tableDatas
        .map(tableData => {
          return tableData.amount = (
            parseFloat(tableData.quantity) *
            parseFloat(tableData.sellingprice)
          );
        })
        .reduce((total, current) => total + current, 0) || 0
      );
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button type="button" @click="btnOnClick">Add</button>
  <table class="table table-striped table-hover table-bordered mainTable" id="Table">
    <thead>
      <tr>
        <th class="itemName">Item Name</th>
        <th>Quantity</th>
        <th>Selling Price</th>
        <th>Amount</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(tableData, k) in tableDatas" :key="k">
        <td>
          <input class="form-control" readonly v-model="tableData.itemname" />
        </td>
        <td>
          <input class="form-control text-right" type="number" min="0" step="1" v-model="tableData.quantity" />
        </td>
        <td>
          <input class="form-control text-right" type="number" min="0" step=".5" v-model="tableData.sellingprice" />
        </td>
        <td>
          <input readonly class="form-control text-right" type="number" min="0" step="1" v-model="tableData.amount" />
        </td>
      </tr>
    </tbody>
  </table>
  <div>
    <label>Total Row's Amount</label>
    <input type="text" disabled :value="calculate">
  </div>
</div>

Edit:

I let my imagination run wild and I did it also with components:

Vue.component("form-row", {
  template: "#row-template",
  props: {
    itemname: String,
    quantity: Number,
    sellingprice: Number,
    amount: Number
  },
  computed: {
    quantitySynced: {
      get() {
        return this.quantity;
      },
      set(v) {
        this.$emit("update:quantity", +v);
      }
    },
    sellingpriceSynced: {
      get() {
        return this.sellingprice;
      },
      set(v) {
        this.$emit("update:sellingprice", +v);
      }
    },
    amountSynced() {
      this.$emit("update:amount", parseFloat(this.quantity) * parseFloat(this.sellingprice));
      return this.amount
    }
  }
});

new Vue({
  el: "#app",
  data() {
    return {
      tableDatas: []
    };
  },
  methods: {
    btnOnClick(v) {
      this.tableDatas.push({
        itemname: "item",
        quantity: 1,
        sellingprice: 55,
        amount: 55
      });
    }
  },
  computed: {
    calculate() {
      return (
        this.tableDatas.reduce((total, {amount}) => total + amount, 0) || 0
      );
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button type="button" @click="btnOnClick">Add</button>
  <table class="table table-striped table-hover table-bordered mainTable" id="Table">
    <thead>
      <tr>
        <th class="itemName">Item Name</th>
        <th>Quantity</th>
        <th>Selling Price</th>
        <th>Amount</th>
      </tr>
    </thead>
    <tbody>
      <form-row v-for="(row, key) in tableDatas" :key="key" v-bind.sync="row"></form-row>
    </tbody>
  </table>
  <div>
    <label>Total Row's Amount</label>
    <input type="text" disabled :value="calculate">
  </div>
</div>

<script type="text/x-template" id="row-template">
  <tr>
    <td>
      <input class="form-control" readonly :value="itemname" />
    </td>
    <td>
      <input class="form-control text-right" type="number" min="0" step="1" v-model="quantitySynced" />
    </td>
    <td>
      <input class="form-control text-right" type="number" min="0" step=".5" v-model="sellingpriceSynced" />
    </td>
    <td>
      <input readonly class="form-control text-right" type="number" min="0" step="1" :value="amountSynced" />
    </td>
  </tr>
</script>

Leave a comment