How I can use one js code of a django template for different content
I am working on a web application using Django I have faced one problem in that and that's I wrote one html template in Django and in that template I also has been written the code of js for that template. I want to use that js code for all the different kinds of content that is represented using that template in the front of the user.but that js code is not working for all kinds of content similarly.
Problem in brief
I am making a commerical web application for a Project like amazon.in and flipkart.com and I have writen a template for a product view page for all kinds of Product that is shown using that template. I has been made a button in that product view page template. Button is Add to Cart and I have written JavaScript code in that template for add to Cart button to store the product in the cart when the user click the button. I made my cart using LocalStorage and i will store the products in it. but the problem is when I initialzed my site and click on the product and goes to the product view page and click to the Add to Cart and after click on it the js code will be executed successfully!! and the product will be stored in localStorage of the browser. but When I goes back to the Products list page and click on the another Product and goes to its Product view page and then I click the Add to Cart Button it will do nothing and show some kind of error which is about Uncaught Type Error and the product is not listed in the cart. but when I clear my cart (localStorage) by using localStorage.clear() and when it is empty the product is listed in the localStorage after clicking on the Add to Cart Button. and when one Product is listed in it. it show same error again for other one. so How I can solve it and gets my desired result.
if you know that how it will be solved so please share with and help me out and please let know also what kind of mistake i am doing in that.
My product view template code is here with js code embaded
{% extends 'MenuCategory/Navigation_bar.html' %}
{% block title %} {{Category.Item_Category}} {% endblock %}
{% block style %}
{% endblock %}
{% block head %}
{% endblock %}
{% block body %}
<div class="container-fluid mt-3">
<div class="list-group">
{% for item in Content %}
<a href="#" class="list-group-item list-group-item-action" aria-current="true">
<div class="row">
<div class="col-1 d-flex align-items-center">
<img src="/media/{{item.Item_Image}}" class="rounded img-fluid" width="150px" height="150px">
</div>
<div class="col-8">
<div class="d-flex w-100 row">
<h5 id="nameby{{Category.Item_Category}}Product{{item.Item_ID}}" class="mb-1">{{item.Item_Name}}</h5>
<div class="d-flex w-100 row">
<p class="mb-1">{{item.Item_Description}}</p>
</div>
<div class="d-flex w-100 row">
<small id="PriceOf{{Category.Item_Category}}Product{{item.Item_ID}}">{{item.Item_Price}}</small>
</div>
</div>
</div>
<div class=" col-3 d-flex justify-content-end align-items-center mr-2">
<span id="btnspan{{Category.Item_Category}}Product{{item.Item_ID}}" class="AddBtn">
<button id="{{Category.Item_Category}}Product{{item.Item_ID}}" class="btn btn-primary {{Category.Item_Category}}CartButton">Add to Cart</button>
</span>
</div>
</div>
</a>
{% endfor %}
</div>
</div>
{% endblock %}
{% block script %}
document.getElementById("NavbarMainHeading").innerHTML="{{Category.Item_Category}}";
function updateCart(Cart) {
for (let item in Cart) {
console.log(item)
document.getElementById('btnspan' + item).innerHTML = `<button id="minus${item}" class="btn btn-primary minus">-</button><span id="val${item}">${Cart[item][0]}</span><button id="plus${item}" class="btn btn-primary plus">+</button>`
}
localStorage.setItem('Cart', JSON.stringify(Cart))
console.log(localStorage.getItem('Cart'))
}
if (localStorage.getItem('Cart') == null) {
var Cart = {};
} else {
Cart = JSON.parse(localStorage.getItem('Cart'))
updateCart(Cart)
}
let btns = document.getElementsByClassName('{{Category.Item_Category}}CartButton');
btns = Array.from(btns);
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
var idstr = this.id.toString();
if (Cart[idstr] != undefined) {
Cart[idstr][0] = Cart[idstr][0] + 1;
} else {
name = document.getElementById("nameby" + idstr).innerHTML;
price = document.getElementById("PriceOf" + idstr).innerHTML;
quantity = 1;
Cart[idstr] = [quantity, name, parseInt(price)];
}
updateCart(Cart)
})
}
{% endblock %}
My urls.py code is here
from django.urls import path,include
from . import views
urlpatterns = [
# path('admin/', admin.site.urls),
path('',views.CategoryPage,name='MenuCategoryPage'),
path('Category/<str:Variety_Name>',views.Category_Items,name='CategoryItems')
My views.py of Django code is here
from django.shortcuts import render
from django.http import HttpResponse
from .models import Varieties,CategoryItems
def Category_Items(request,Variety_Name):
print(f"variety name {Variety_Name}")
post=CategoryItems.objects.filter(Item_Category=Variety_Name)
Category=None
print(len(post))
if len(post) >= 1:
Category=post[0]
content={'Content':post,'Category':Category}
return render(request,'MenuCategory/Product_List.html',content)
My models.py code is here
from django.db import models
# Create your models here.
class Varieties(models.Model):
VarietyID=models.AutoField(primary_key=True)
Variety_Name=models.CharField(max_length=50,default='Variety name should be within 50 characters.')
Variety_Image=models.ImageField(default='')
def __str__(self):
return self.Variety_Name
class CategoryItems(models.Model):
Item_ID=models.AutoField(primary_key=True)
Item_Category=models.CharField(max_length=50,default="Variety Name and Category Name must be same.")
Item_SubCategory=models.CharField(max_length=50,default="SubCategory Name")
Item_Image=models.ImageField(default='')
Item_Name=models.CharField(max_length=50,default='Ex: Paneer Pratha')
Item_Price=models.IntegerField()
Item_Description=models.CharField(max_length=1000,default='Write Something about speciality of the Product.')
def __str__(self):
return f"{self.Item_Name} - {self.Item_Category}"
Error that occur in Console when I want to add an item in the cart when localStorage already have one item in it

But When localStorage is Empty the item is Stored in it Successfully

The Problem that I found in this code is that when we call updateCart function with Cart parameter which is an object. When we itreate it in the updateCart function by the using of for loop. At that time we took a variable called item in it as
for (let item in Cart) {
console.log(item)
document.getElementById('btnspan' + item).innerHTML = `<button id="minus${item}" class="btn btn-primary minus">-</button><span id="val${item}">${Cart[item][0]}</span><button id="plus${item}" class="btn btn-primary plus">+</button>`
}
So, in this item is the key name of the Cart object. when you see the for loop which is outer side of the function which has been used for the attachment of EventHandler for the buttons Add to Cart. the for loop is :
let btns = document.getElementsByClassName('{{Category.Item_Category}}CartButton');
btns = Array.from(btns);
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener('click', function() {
var idstr = this.id.toString();
if (Cart[idstr] != undefined) {
Cart[idstr][0] = Cart[idstr][0] + 1;
} else {
name = document.getElementById("nameby" + idstr).innerHTML;
price = document.getElementById("PriceOf" + idstr).innerHTML;
quantity = 1;
Cart[idstr] = [quantity, name, parseInt(price)];
}
updateCart(Cart)
})
}
if you see this, you will notice that the variable idstr which is declared inside the for loop. It is used for storing the value of id of button which is clicked at a time.At the last inside the for loop in the else section fetch the details of item by the using of idstr variable and after that we will store these details in the Cart object as a array along with that object key name is idstr which is the id of the button that was clicked.Then we will pass Cart object as an argument to the function updateCart
So Every time When you Change the Content of the template the id of the button will also Change because the id of the button is {{Category.Item_Category}}Product{{item.Item_ID}} which is dynamically change for every new category page.
So we have to put one if statement in the for loop of updateCart function before of Changing the button "Add to Cart" to another one. just like that:
function updateCart(Cart) {
for (let item in Cart) {
if("{{Category.Item_Category}}" == `${item}`.slice(0,"{{Category.Item_Category}}".length)){
document.getElementById('btnspan' + item).innerHTML = `<button id="minus${item}" class="btn btn-primary minus">-</button><span id="val${item}">${Cart[item][0]}</span><button id="plus${item}" class="btn btn-primary plus">+</button>`
}
}
localStorage.setItem('Cart', JSON.stringify(Cart))
console.log(localStorage.getItem('Cart'))
}
In the if statement which we add in the for loop we made a comparison of Categories name
As you see in the question that button id is containing the Category Name of the items and the items are also divided by the Category So for Every Category the Template page will be one with the same id of buttons and of other elements. So we made a Comparison between the Category Name of the item. By the help of this Comparison the buttons are changed if the Category name are same from both side and rest of the elements/buttons are skiped automatically. in this way there are no error are occur and code runs smoothly.
I hope this Answer will help you!!
Added If Statement are:
if("{{Category.Item_Category}}" == `${item}`.slice(0,"{{Category.Item_Category}}".length))