This is the single page application with vue.js and it does some simple calculation and i am trying to implement this calculation in django but it is not giving me the result I want.
Here I made the array in the vue.js dynamic and this is displaying me only the image of the product perfectly but not product.name
and product.sell_price
and also @click.prevent="addToCart(product)"
this function is not working ?? How can i solve it ?
vue.js
<script src="{% static 'js/vue.js' %}"></script>
<script type="text/javascript" src="{% static '/js/vue-resource.js' %}"></script>
<script>
new Vue({
el: '#posApp',
data: {
total: 0,
discount: 0,
products: [
{% for product in products %}
{
"id": {{product.id}},
"name": "{{product.name}}",
"image": "/media/{{product.image}}",
"price": {{product.sell_price}}
},
{% endfor %}
],
cart: [],
search: ""
},
methods: {
addToCart: function(product){
var found = false;
for (var i = 0; i < this.cart.length; i++){
if (this.cart[i].id === product.id){
this.cart[i].quantity++;
found = true;
}
}
if (!found) {
this.cart.push({
id: product.id,
name: product.name,
sell_price: product.sell_price,
quantity: 1
});
}
this.total += product.sell_price;
},
inc: function(item){
item.quantity++;
this.total += item.sell_price;
},
dec: function(item){
item.quantity--;
this.total -= item.sell_price;
if (item.quantity <= 0){
var i = this.cart.indexOf(item);
this.cart.splice(i, 1);
}
},
removeFromCart: function(item){
this.cart.splice(this.cart.indexOf(item), 1);
this.total = this.total - (item.sell_price * item.quantity);
},
clearCart: function(){
this.cart = [];
this.total = 0;
this.discount = 0;
},
payment: function(){
this.cart = [];
this.total = 0;
this.discount = 0;
alert('Transaction Completed');
}
},
computed: {
filteredProducts(){
// var lowerTitle = product.title.toLowerCase();
return this.products.filter((product) => {
return product.name.toLowerCase().match(this.search);
});
}
}
});
</script>
html
<div class="col-md-3" v-for="product in filteredProducts" :key="product.id"> <!-- Inner-Col .// -->
<a href="#" @click.prevent="addToCart(product)">
<div class="box box-default pos-product-card"> <!-- /.box -->
<img class="card-img-top img-responsive" :src="product.image" alt="Card image cap">
<div class="box-body"> <!-- /.box-body -->
<h4 class="box-title">{{ product.name }}</h4>
<!-- <p class="box-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> -->
<button class="btn btn-info"><i class="fas fa-shopping-cart"></i></button>
</div> <!-- /.box-body -->
</div> <!-- /.box -->
</a>
</div>
{% for category in categories %}
<div class="tab-pane fade" id="category-{{category.id}}">
<div class="row"> <!-- Inner-Row .// -->
{% for product in category.product_set.all %}
<div class="col-md-3" v-for="product in filteredProducts" :key="product.id"> <!-- Inner-Col .// -->
<a href="#" @click.prevent="addToCart(product)">
<div class="box box-default pos-product-card"> <!-- /.box -->
<img class="card-img-top img-responsive" :src="product.image" alt="Card image cap">
<div class="box-body"> <!-- /.box-body -->
<h4 class="box-title">{{ product.name }}</h4>
<!-- <p class="box-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> -->
<button class="btn btn-info"><i class="fas fa-shopping-cart"></i></button>
</div> <!-- /.box-body -->
</div> <!-- /.box -->
</a>
</div>
{% endfor %}
<table class="table table-hover text-center">
<!-- <thead class="thead-dark"> -->
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Rate</th>
<th>Subtotal</th>
<th> </th>
</tr>
<!-- </thead> -->
<tr v-for="item in cart" :key="{{item.id}}">
<td><a href="#">{{ item.name }}</a></td>
<td><button class="btn btn-flat btn-xs btn-info p-1 mx-1" @click="inc(item.id)">+</button>[[ item.quantity ]]<button class="btn btn-flat p-1 mx-1 btn-xs btn-info" @click="dec(item.id)">-</button></td>
<td><span class="text-muted">{{ item.sell_price }}</span> </td>
<td>Rs {{ item.sell_price * item.quantity }}</td>
<td><button class="btn btn-xs btn-outline-primary" @click="removeFromCart(item)"><i class="fas fa-trash-alt"></i></button></td>
</tr>
</table>
</div>
<div class="no-item-msg" v-if="cart.length === 0">No items in the cart.</div>
</div>
<table class="table">
<tr>
<td>Total Items</td>
<td>{{ cart.length }}</td>
</tr>
<tr>
<td>Total Amount</td>
<td>{{ total }}</td>
</tr>
<tr>
<td><span class="height-control">Discount (In Amount)</span></td>
<td><input type="number" v-model="discount" class="form-control"></td>
</tr>
<tr class="bg-dark">
<td>TO PAY</td>
<td>{{ total-discount }}</td>
</tr>
There are few points for you to consider:
Seems like you have syntax collision in your html, because Django and Vue.js use same {{
and }}
to put variable. But, as Django will process your html before Vue, it will replace
<h4 class="box-title">{{ product.name }}</h4>
by what it will find in context (Django tepmlate context on server side). You may check source or your page in browser, and probably you will see at that line:
<h4 class="box-title"></h4>
Because it will not find python product
variable (and you actually meant js(vue) variable).
Solution: use another Vue delimiters. See https://vuejs.org/v2/api/#delimiters. For example use [[
instead of {{
in Vue: an option to your Vue instance delimiters: ['[[', ']]'],
and change that line (and other where you mean Vue variables) to
<h4 class="box-title">[[ product.name ]]</h4>
In Vue data you have not product.sell_price variable, as when you doing
{% for product in products %}
{
"id": {{product.id}},
"name": "{{product.name}}",
"image": "/media/{{product.image}}",
"price": {{product.sell_price}}
},
{% endfor %}
you will have product.price
, not product.sell_price
in Vue. Or you have to
change line above to "sell_price": {{product.sell_price}}
Soon you will face troubles with item
variable. As you have item
in django context, not in Vue data. You should add items to Vue data as you did for products
.
In general consider change of your approach from mixing django template and Vue code to:
OR
Good luck.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With