Create a quantity table with Vue.js and PHP.

So for this mini application I created a quantity table. This is great for if you have some kind product order form. The user can select different quantities to purchase from a list of items in the table. They will immediately get to see how the changes in quantity affects the total price of the selected items.

Quantity Table

Using Vue.js to do this was pretty straight forward. We first supplied our data to the vue app instance.

     rows : {
                1 : {
                    'quantity' : 0,
                    'price' : 3.00,
                    'total' : 0,
                    'item' : "HB Pencil"
                },
                2 : {
                    'quantity' : 0,
                    'price' : 3.00,
                    'total' : 0,
                    'item' : "Manilla Envelope"
                },
                3 : {
                    'quantity' : 0,
                    'price' : 150.00,
                    'total' : 0,
                    'item' : "Cross Black Ink Pen"
                },
                4 : {
                    'quantity' : 0,
                    'price' : 10.00,
                    'total' : 0,
                    'item' : "Paper Clips"
                },
            }

Once this is done we can bind our values in HTML. Our row can be shown below.

  <tr v-for="row in rows">
       <th>
        <span v-if="cansubmit">{{ row.quantity }}</span>
        <input v-if="!cansubmit" type="number" v-model="row.quantity">
       </th>
       <td>{{ row.item }} </td>
      <td>{{ row.price }}</td>
       <td>{{ row.quantity * row.price }}</td>
 </tr>

The v-for attribute is on the <tr> element in our table. This is how we create our rows. In the product total column we can do a calculation right inside our curly braces.

  <td>{{ row.quantity * row.price }}</td>

The last column in the table that shows our final total is shown below.

<tr>
    <th colspan="3">Total</th>
       <td >
          {{ total }}
       </td>
</tr>

The variable total is a computed property. We can see that below.

total : function(){
      var total = 0;
      for(var i =1; i <= Object.keys(this.rows).length; i++){
                    total += this.rows[i].price * this.rows[i].quantity;
      }
      return total;
}

The computed property total checks all the items and gets the current row price and quantity values. This is totaled and the final value is returned.

The buttons finish and edit are displayed conditional. They don’t show at the same time.

<button v-if="cansubmit" type="button" @click="edit()" class="btn btn-primary float-left">Edit</button>
<button v-if="!cansubmit" type="button" @click="finish()" class="btn btn-primary float-left">Finish</button>

The v-if property is binded to cansubmit. This is updated if the user press either the edit method or the finish method. This is shown below.

finish : function(){
     this.cansubmit = true;
     this.createFormData();
},
edit : function(){
     this.cansubmit = false;
},

We create data that can be posed simply by turning our JSON object rows into a string.

createFormData : function(){
     this.formdata = JSON.stringify(this.rows);
}    

The variable formdata is binded to a hidden input that is posted with the form when we submit it.

<form  v-if="cansubmit" action="submit.php" method="get">
  <input type="hidden" v-model="formdata" name="data">
  <button type="submit" class="btn btn-primary float-right">Submit</button>
</form>

When we press the finish button the quantity inputs disappear.

Finish view

This is because we have a condition on the inputs. Instead a <span> element displays the quantity. If the edit button is pressed the inputs will return. The quantity row is shown below.

<th>
   <span v-if="cansubmit">{{ row.quantity }}</span>
   <input v-if="!cansubmit" type="number" v-model="row.quantity">
</th>

It uses the same cansubmit variable to adjust the view accordingly.

That’s it. You’ve just made something complicated extremely simple.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s