Django Ajax - Update table after submitting form - javascript

Good evening,
inside my page there are two areas - one in which the form with the new data is submitted and a second one where all the entries should be displayed inside a table..
I'm still new to javascript, so I'm asking myself, wether it's possible to update the table with the new data after pressing the submit button (and without refreshing the whole page)!?
models.py
class AjaxTable(models.Model):
first_name = models.CharField(max_length=25, null=False, blank=False)
last_name = models.CharField(max_length=25, null=False, blank=False)
age = models.IntegerField(default=0, validators=[MinValueValidator(1), MaxValueValidator(100)])
def __str__(self):
return f"{self.first_name} {self.last_name}"
views.py
def javascript_ajax_table_update(request):
qs_table = AjaxTable.objects.all()
form = AjaxTableForm()
data = {}
if request.is_ajax():
form = AjaxTableForm(request.POST, request.FILES)
if form.is_valid():
form.save()
data['first'] = form.cleaned_data.get('first_name')
data['last'] = form.cleaned_data.get('last_name')
data['age'] = form.cleaned_data.get('age')
data['status'] = 'ok'
return JsonResponse(data)
context = {'formset': form, 'qs_table': qs_table}
return render(request, 'app_django_javascript/create/django_javascript_ajax_table_update.html', context)
forms.py
class AjaxTableForm(ModelForm):
class Meta:
model = AjaxTable
fields = '__all__'
template.html
<div class="grid-container">
<div class="cnt-create">
<div class="card">
<div class="card-body">
<form action="" method="post" autocomplete="off" id="post-form" name="post-form">
{% csrf_token %}
<div class="div-post-input-flex">
<div class="div-post-input">
<label>First Name</label><br>
{{ formset.first_name }}
</div>
<div class="div-post-input">
<label>Last Name</label><br>
{{ formset.last_name }}
</div>
<div class="div-post-input">
<label>Age</label><br>
{{ formset.age }}
</div>
</div>
<div class="div-post-input">
<button class="btn btn-success" type="submit">
Save
</button>
</div>
</form>
</div>
</div>
</div>
<div class="cnt-view">
<div class="card">
<div class="card-body">
<table class="table table-hover" id="ajax-table">
<thead>
<tr>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Age</th>
</tr>
</thead>
<tbody>
{% for item in qs_table %}
<tr>
<td>{{ item.first_name }}</td>
<td>{{ item.last_name }}</td>
<td>{{ item.age }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
script
const form = document.getElementById('post-form')
const first_name = document.getElementById('id_first_name')
const last_name = document.getElementById('id_last_name')
const age = document.getElementById('id_age')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
const url = ""
form.addEventListener('submit', e=>{
e.preventDefault()
const fd = new FormData()
fd.append('csrfmiddlewaretoken', csrf[0].value)
fd.append('first_name', first_name.value)
fd.append('last_name', last_name.value)
fd.append('age', age.value)
$.ajax({
type: 'POST',
url: url,
enctype: 'multipart/form-data',
data: fd,
success: function(response){
console.log(response)
setTimeout(()=>{
first_name.value = ""
last_name.value = ""
age.value = 0
}, 1000)
},
error: function(response){
console.log(response)
},
cache: false,
contentType: false,
processData: false,
})
})

Related

Why is my javascript/flask speech recognition code posting the results as None and not appending the input box?

I have a flask app that uses js speech recognition to append user's answers to an HTML input box. The inputs are then sent and appended to the next page's list. Currently, the list is appended "None" and there are no errors in the console. I've been using this and this to no avail and also have referenced this and this
Here's the Main.py code:
from flask import render_template, Flask, request
import os
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer as SIA
import nltk
import io
import os
from nltk.corpus import stopwords
app = Flask(__name__, static_folder = 'static')
# # set the stopwords to be the english version
# stop_words = set(stopwords.words("english"))
# # vader sentiment analyzer for analyzing the sentiment of the text
# sid = SIA()
# # patient.name?
#app.route("/", methods=["GET", "POST"])
def home():
user = request.values.get('name')
location = request.values.get('location')
state = request.values.get('state')
# if request.method == "POST":
# with mic as source:
# holder = []
# for x in info:
# audio_data = r.listen(source)
# r.adjust_for_ambient_noise(source)
# text = r.recognize_google(audio_data, language = 'en-IN')
# holder.append(text.lower())
# if x == "state":
# ss = sid.polarity_scores(holder)
# if ss == "neg":
# x.append(str("sad"))
# else:
# x.append(str("not sad"))
# else:
# filtered_words = [words for words in holder if not words in stop_words] # this filters out the stopwords
# x.append(filtered_words.lower())
# return redirect(url_for('care', user = user))
return render_template('index.html', user = user, location=location, state=state)
#app.route("/care", methods=["POST"])
def care():
user = request.values.get('name')
location = request.values.get('location')
state = request.values.get('state')
return render_template('list.html', user = user, location=location, state=state)
if __name__ == "__main__":
#app.run(debug=True)
app.run(debug=True, threaded=True)
Index.html:
{% extends "base.html" %}
{% block content %}
<!---------Therapist Section--------->
<section id="therapist">
<div class="container" id="therapist_container">
<div id="button">
<button type="button" class="btn btn-primary" onclick="record" id="therapist-button" data-toggle="modal" data-target="#myModal">Talk with Delphi</button>
</div>
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="vid1Title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-body">
<video width="100%" id="video1">
<source src="./static/movie.mp4" type="video/mp4">
</video>
<form class="texts" action="/care" id="careid" name="care" method="POST">
<input type="text" id="name" placeholder="what's your name?">
<input type="text" id="location" placeholder="Where are you?">
<input type="text" id="state" placeholder="how can I help?">
<input id="buttonInput" class="btn btn-success form-control" type="submit" value="Send">
</form>
</div>
</div>
</div>
</div>
<script>
$('#myModal').on('shown.bs.modal', function () {
$('#video1')[0].play();
})
$('#myModal').on('hidden.bs.modal', function () {
$('#video1')[0].pause();
})
video = document.getElementById('video1');
// window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
function record() {
var recognition = new webkitSpeechRecognition() || SpeechRecognition();
recognition.interimResults = true;
recognition.lang = "en-US";
recognition.onresult = function(event) {
console.log(event);
document.getElementById("name").value = event.results[0][0].transcript;
}
recognition.start();
recognition.addEventListener("end", () =>{
recognition.start
recognition.onresult = function(event) {
// console.log(event);
document.getElementById("location").value = event.results[0][0].transcript;
}
})
recognition.addEventListener("end", () =>{
recognition.start
recognition.onresult = function(event) {
// console.log(event);
document.getElementById("state").value = event.results[0][0].transcript;
}
recognition.addEventListener("end", () => {
window.location.pathname = '/care';
document.care.submit();
});
})
}
// video.addEventListener('ended',function(){
// window.location.pathname = '/care';
// document.care.submit();
// })
</script>
</div>
</section>
{% endblock content %}
List.html:
{% extends "base.html" %}
{% block content %}
<!----LIST------>
<section id="care_list">
<div class="container" id="care_list_container">
<h1 class="jumbotron text-center" id="care_list_title">{{ user }} Care Record</h1>
<div class="container">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">Session #</th>
<th scope="col">Length</th>
<th scope="col">Location</th>
<th scope="col">State</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>{{ length }}</td>
<td>{{ location }}</td>
<td>{{ state }}</td>
</tr>
<tr>
<th scope="row">2</th>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2"></td>
<td></td>
</tr>
</tbody>
</table>
<ul class="list-group list-group-flush" id="care_list">
<li class="list-group-item">Please email tom#vrifyhealth.com for help.</li>
</ul>
</div>
</section>
{% endblock content %}
Here's the screenshot of the output and the console:

Passing selected dropdown string value from table in view to controller

I'm working on ASP.NET Core web application where I have a table in my view that displays all requests. each record with drop-down populated with all analysts successfully from my database, So the manager can assign the analyst from drop-down then approve the request.
My questions:
Can I implement this using form for each record instead using JavaScript, I mean using only asp tags?
If that should done using JavaScript, Here is my attempt to implement this.
The following code is working only if the Analyst id is integer, but in my case the analyst id is string, so whenever I try to execute this, I got either "null" or "Zero" for the analyst id in the controller. Here is my ViewModel
public class RequestViewModel
{
public IEnumerable<Request> Requests { get; set; }
public IEnumerable<ApplicationUser> AnalystList { get; set; }
public Institution Institution { get; set; }
public string selectedAnalyst { get; set; }
}
Here is my controller
public async Task<IActionResult> ApproveRequest(int id, int Analystid)
{
Request Req = await _db.Request
.Include(c => c.Institution)
.FirstOrDefaultAsync(c => c.Id == id);
if (Req.Type == SD.TypeRegister)
{
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
Req.Institution.Seats = Req.Seats; // new
Req.Institution.AnalystId = Analystid.ToString(); //Here I want to get the id as string
}
else if (Req.Type == SD.TypeSeat)
{
Req.Institution.Seats += Req.Seats;
}
else if (Req.Type == SD.TypeSubscription)
{
Req.Institution.Seats = Req.Seats;
Req.Institution.Status = SD.StatusApproved;
Req.Institution.ApprovalDate = DateTime.Now;
}
Req.isDone = true;
await _db.SaveChangesAsync();
return await CreateApproval(id, SD.StatusApproved);
}
Here is my View
#model TestApplication.Models.ViewModels.RequestViewModel
#using TestApplication.Extensions
#{
ViewData["Title"] = "Index";
}
<div class="tab-pane fade show active" id="Register" role="tabpanel" aria-labelledby="Register-tab">
Registration Requests
<div>
#if (Model.Requests.Count() > 0)
{
<table class="table table-striped">
<tr class="table-secondary">
<th>
Institution Name
</th>
<th>
Date
</th>
<th>
Actual seat
</th>
<th>
Seats
</th>
<th>
New Seat
</th>
<th>
Choose Analyst
</th>
<th>
Accept / Reject
</th>
<th>
Details
</th>
<th>
</th>
</tr>
#foreach (var item in Model.Requests)
{
#if (item.Type == "Register" && item.Institution.Status == "Pending") #*need one*#
{
<tr>
<td>
#Html.DisplayFor(m => item.Institution.Name)
</td>
<td>
#Html.DisplayFor(m => item.Date)
</td>
<td>
#Html.DisplayFor(m => item.Institution.Seats)
</td>
<td>
#Html.DisplayFor(m => item.ActualSeats)
</td>
<td>
#Html.DisplayFor(m => item.Seats)
</td>
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" asp-items=" Model.AnalystList.ToSelectListItem(Model.selectedAnalyst)" class="form-control">
<option selected value="">--- Choose ---</option>
</select>
</td>
<td>
<a class="btn btn-info" asp-controller="Request" asp-action="ApproveRequest" asp-route-id="#item.Id"> accept </a>
<a class="btn btn-info" asp-controller="Request" asp-action="RejectRequest" asp-route-id="#item.Id"> Reject </a>
</td>
<td>
<button type="submit" class="btn btn-success anchorDetail" data-target="#modal-#item.Institution.Id" data-toggle="modal">
View Details
</button>
</td>
<td>
<div class="modal fade" id="modal-#item.Institution.Id" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog-centered modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-success text-light justify-content-center">
<h5 class="modal-title">Request Details</h5>
</div>
<div class="modal-body justify-content-center" id="MyModalContent">
#await Html.PartialAsync("_RequestDetails", item)
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">إغلاق</button>
</div>
</div>
</div>
</div>
</td>
</tr>
}
}
</table>
}
else
{
<p>No Institutions Exists...</p>
}
</div>
</div>
#section scripts
{
<script>
function accept(id) {
var aid = $('#selectedAnalyst_' + id).val()
location.href = "/Request/ApproveRequest?id=" + id + "&Analystid=" + aid
}
var PostBackURL = '/Request/RequestDetails';
$(function () {
$(".anchorDetail").click(function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
$.ajax({
type: "GET",
url: PostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
cache: false,
datatype: "json",
success: function (data) {
$('#MyModalContent').html(data);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
})
</script>
}
<div class="modal fade" id="MyModal" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel">
<div id='MyModalContent'></div>
</div>
If you want to pass #item.id and $('#selectedAnalyst_' + id).val() to controller with form,you can do like this.Here is a demo worked(put form outside dropdownlist and button):
<form method="post"
asp-controller="Request"
asp-action="ApproveRequest"
asp-route-id="#item.Id">
<td>
<select id="selectedAnalyst_#item.Id" asp-for="selectedAnalyst" class="form-control">
<option selected value="">--- Choose ---</option>
<option selected value="1">1</option>
<option selected value="2">2</option>
<option selected value="3">3</option>
</select>
</td>
<td>
<button type="submit">Accept</button>
</td>
</form>
Controller(change Analystid to selectedAnalyst,so that you can bind asp-for="selectedAnalyst",and if you want to get string parameter,you can change it to string selectedAnalyst):
public IActionResult ApproveRequest(int id,string selectedAnalyst)
{
return Ok();
}
result:

No response for the first click - JavaScript & Django

I am new to Django and working on a eCommerce website and trying to improve cart functions.
I follow the course to use JavaScript to update the items in the cart like below code.
If I clicked the "add" or "remove" button on other page(like product list), it works fine.
However, when I tried to lick "remove" button on the cart page (where I can see all the products in the cart), it worked fine as the very first time, the item removed from the cart.
Afterward, I clicked the button, the page just refreshed. Then I clicked another time, it worked again. So it's like after the first item removed, I have to click two times to remove the item I want.
Below are my JavaScript Code, views.py, and my cart_home.html. Hope anyone could help get through this, I've been stuck for a week....
JavaScript
<script type="text/javascript">
$(document).ready(function(){
var productForm = $(".form-product-ajax") // id:#form-product-ajax
productForm.submit(function(event){
event.preventDefault();
console.log("Form is not sending");
var thisForm =$(this);
var actionEndpoint = thisForm.attr('data-endpoint');
var httpMethod = thisForm.attr('method');
var formData = thisForm.serialize();
$.ajax({
url: actionEndpoint,
method: httpMethod,
data: formData,
success: function (data) {
console.log("success");
console.log(data);
console.log("Added:",data.productAdded);
console.log("Removed:",data.productRemoved);
var submitSpan = thisForm.find(".submit-span")
if (data.productAdded) {
submitSpan.html('<button class="btn btn-danger btn-sm " type="submit" name="remove">Remove</button>')
} else {
submitSpan.html('<button class="btn btn-success btn-sm" type="submit" name="Add">Add to Cart</button>')
}
var navbarCount = $(".navbar-cart-count")
navbarCount.text(data.cartItemCount)
var currentPath = window.location.href
if (currentPath.indexOf("cart") != -1) {
refreshCart()
}
},
error: function (errorData) {
console.log("error");
console.log(errorData);
}
})
})
function refreshCart() {
console.log("in current cart");
var cartTable = $(".cart-table")
var cartBody = cartTable.find(".cart-body")
var productRows = cartBody.find(".cart-products")
var currentUrl = window.location.href
var refreshCartUrl ='api/carts'
var refreshCartMethod="GET";
var data={};
$.ajax({
url: refreshCartUrl,
method: refreshCartMethod,
data:data,
success:function(data) {
var hiddenCartItemRemoveForm = $(".cart-item-remove-form")
if (data.products.length>0) {
productRows.html("")
i = data.products.length
$.each(data.products,function (index,value) {
console.log(value);
var newCartItemRemove = hiddenCartItemRemoveForm.clone()
newCartItemRemove.css("display","none")
newCartItemRemove.find(".cart-item-product-id").val(value.id)
cartBody.prepend("<tr><th scope=\"row\">" + i +"</th><td><a href='" +value.url + "'>" + value.name +"</a>" + newCartItemRemove.html() + "</td><td>" + value.price + "</td></tr>")
i --
})
cartBody.find(".cart-subtotal").text(data.subtotal);
cartBody.find(".cart-tax").text(data.tax);
cartBody.find(".cart-total").text(data.total);
}else {
window.location.href = currentUrl;
}
},
error:function(errorData) {
console.log("error");
console.log(errorData);
}
})
}
})
</script>
Cart_home.html
{% extends "base.html" %}
{% block content %}
<h1>Cart</h1>
{% if cart.products.exists %}
<table class="table cart-table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Prodcut Name</th>
<th scope="col">Product Price</th>
</tr>
</thead>
<tbody class="cart-body">
{% for product in cart.products.all %}
<tr class='cart-products'>
<th scope="row">{{forloop.counter}}
<td>{{product.name}}
{% include "carts/snippets/remove-product.html" with product_id=product.id%} </th>
</td>
<td>${{product.price}}</td>
</tr>
{% endfor %}
<tr>
<th colspan='2'></th>
<td> <b>Subtotal : $</b><span class="cart-subtotal">{{cart.subtotal}}</span> </td>
</tr>
<tr>
<th colspan='2'></th>
<td> Tax : $<span class="cart-tax" >{{cart.tax}} </span></td>
</tr>
<tr>
<th colspan='2'></th>
<td> <b>Total : $</b><span class="cart-total">{{cart.total}} </span> </td>
</tr>
<tr>
<th colspan='2'></th>
<td> <a class="btn btn-success" href="{% url 'carts:checkout' %}">Checkout</a> </td>
</tr>
</tbody>
</table>
<div class="cart-item-remove-form" style='display:none'>
{% include "carts/snippets/remove-product.html" with product_id=product.id%}
</div>
{% else %}
<p class="lead">There is no porduct in your cart now! </p>
<p> <a class="btn btn-secondary" href="{% url 'products:list' %}">Go to check!</a> </p>
{% endif %}
{% endblock content %}
views.py
def cart_detail_api_view(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
products = [{
"ud":x.id,
"url":x.get_absolute_url(),
"name":x.name,
"price":x.price,
}
for x in cart_obj.products.all()]
cart_data ={"products":products,"subtotal":cart_obj.subtotal,"total":cart_obj.total,"tax":cart_obj.tax()}
return JsonResponse(cart_data)
def cart_update(request):
product_id = request.POST.get('product_id')
if product_id:
try:
product_obj = Product.objects.get(id=product_id)
except Product.DoesNotExist:
print("Show message to user, product does not exist")
raise("Producr does not exist")
return redirect("carts:home")
else:
cart_obj, new_obj = Cart.objects.new_or_get(request)
if product_obj in cart_obj.products.all():
cart_obj.products.remove(product_obj)
product_added = False
else:
cart_obj.products.add(product_obj) # cart_obj.products.add(1)
product_added = True
request.session['cart_items'] = cart_obj.products.count()
if request.is_ajax(): #Asynchronous JavaScript Anx XML / JSON(JaveScrtip Object Notation)
print("Ajax request")
json_data = {
"productAdded":product_added,
"productRemoved":not product_added,
"cartItemCount":cart_obj.products.count()
}
return JsonResponse(json_data)
return redirect("carts:home")

Django Send output with Ajax but Javascript doesn't work

I want to query the database and show the result don't refresh the page. So I use the Ajax! But when I append or paste the html code, the javascript isn't work. The style of my table is so ugly.
This is table html part that output will be here (ID=output) :
<div class='fresh-table' id="output">
<div class='toolbar'>
<button type='button' id='alertBtn' class='btn btn-info'>Add To Cart</button>
</div>
<table id='fresh-table' class='table'>
<thead>
<th data-field='state' data-checkbox='true'></th>
<th data-field='id' data-sortable='true'>id</th>
<th data-field='name' data-sortable='true'>candidate</th>
<th data-field='salary' data-sortable='true'>salary</th>
<th data-field='gpa' data-sortable='true'>gpa</th>
<th data-field='position'>position</th>
<th data-field='actions' class='td-actions text-right' data-formatter='operateFormatter' data-events='operateEvents'>Actions</th>
</thead>
<tbody>
{% for candidate in Candidate %}
<tr data-val='{{candidate.id_number}}'>
<td></td>
<td><a href='/filter/{{candidate.id_number}}/' style='color: #ff9800; font-weight: 400;'>{{candidate.id_number}}</a></td>
<td>{{ candidate.name_title }} {{candidate.firstname}} &nbsp&nbsp {{candidate.lastname}}</td>
<td>{{candidate.salary}}</td>
<td>{{candidate.nowEdu_gpa}}</td>
<td>{{candidate.position}}</td>
<td></td>
</tr>
{% endfor%}
</tbody>
</table>
</div>
This is Ajax in template:
$.ajax({
type: 'POST',
url: 'testajax/',
dataType: "json",
async: true,
data: {
filter_option: json_filter_option,
operator_position: json_operator_position,
filter_position: json_filter_position,
csrfmiddlewaretoken: "{{ csrf_token }}"
},
success: function(json) {
console.log(json.message)
html = "<div class='toolbar'> <button type='button' id='alertBtn' class='btn btn-info'>Add To Cart</button></div><table id='fresh-table' class='table'><thead><th data-field='state' data-checkbox='true'></th><th data-field='id' data-sortable='true'>เลขประจำตัวประชาชน</th><th data-field='name' data-sortable='true'>ชื่อผู้สมัคร</th><th data-field='salary' data-sortable='true'>เงินเดือนที่คาดหวัง</th><th data-field='gpa' data-sortable='true'>เกรดเฉลี่ยสะสม</th><th data-field='position'>ตำแหน่งที่สมัคร</th><th data-field='actions' class='td-actions text-right' data-formatter='operateFormatter' data-events='operateEvents'>Actions</th></thead><tbody>";
$.each(json.message, function(index, candidate) {
html += "<tr data-val='" + candidate[0] + "'><td></td><td><a href='/filter/" + candidate[0] + "/' style='color: #ff9800; font-weight: 400;'>" + candidate[0] + "</a></td><td>{{ candidate.name_title }} {{candidate.firstname}} &nbsp&nbsp {{candidate.lastname}}</td><td>{{candidate.salary}}</td><td>{{candidate.nowEdu_gpa}}</td><td>{{candidate.position}}</td><td></td></tr>";
});
html += "</tbody></table>";
$('#output').html(html);
}
})
Please help me. This project is so important for me.
The style of table that I use is from : https://www.creative-tim.com/product/fresh-bootstrap-table
This is my view.py
def test_ajax(request):
if request.method == 'POST':
print("Entryy")
filter_option = json.loads(request.POST.get('filter_option'))
operator_position = json.loads(request.POST.get('operator_position'))
filter_position = json.loads(request.POST.get('filter_position'))
print("filter_option",filter_option)
print("operator_position",operator_position)
print("filter_position",filter_position)
all_candidate = CandidateBasic.objects.all().values_list('id_number')
response_data = {}
try:
response_data['result'] = "Success"
response_data['message'] = list(all_candidate)
print(response_data)
except Exception as e:
response_data['result'] = "Fail"
response_data['message'] = "Fail!"
return HttpResponse(json.dumps(response_data), content_type="application/json")
This might just be a start, but in your AJAX $.each, you populate a lot of data but don't actually do anything with it. All you put into your page HTML is your html, which doesn't appear to have any view context in it. Maybe you want to consider using JsonResponse instead of HttpResponse

Getting existing HTML in TR Body to Clear

I have a Jquery/Ajax call which updates cart details. At the moment I can't get the existing HTML in the cart-body(tablebody) to clear. The actual ajax request works and all items are added to cart but the original HTML entries stay. The particular code is here:
if (data.products.length > 0 ) {
productRows.html("")
$(cartBody).empty()
Jquery Function
function refreshCart() {
console.log("in current cart")
var cartTable = $(".cart-table")
var cartBody = cartTable.find(".cart-body")
var productRows = cartBody.find(".cart-product")
var cartTotal = cartTable.find(".cart-total-sec")
var productQuantity = cartTable.find(".cart-item-quanity")
var currentUrl = window.location.href
var refreshCartUrl = '/api/cart/'
var refreshCartMethod = "GET";
var data = {};
$.ajax({
url: refreshCartUrl,
method: refreshCartMethod,
data: data,
success: function(data) {
console.log("success")
console.log(data)
if (data.products.length > 0 ) {
productRows.html("")
$(cartBody).empty()
$.each(data.products, function(index, value) {
console.log(value)
console.log(data.count)
cartBody.append("<tr><td>" + value.quantity + " x" + "</td><td>"+ value.name + "</td><td>" + "£" + value.price + "</td></tr>")
})
cartTotal.find(".cart-total").text(data.total)
console.log(data.total)
} else {
window.location.href = currentUrl
}
},
error: function(errorData) {
console.log("error")
console.log(errorData)
}
})
}
HTML Form:
<div>
<h4>This is your shopping cart</h4>
<table class="cart-table">
<tr>These are the items in your basket and their respective totals</tr><br>
<tbody class="cart-body">
{% for item in cart.items %}
<form method="POST" action='{% url "shopping-cart-remove" %}'>
{% csrf_token %}
<tr class="cart-product"><span class="cart-item-quanity">{{ item.quantity }}</span> x {{ item.product.name }} = {{ item.subtotal }}</tr>
<input type="hidden" name='id' value='{{ item.product.id }}'>
<span class='remove-span'><button>remove</button><br></span>
</form>
</tbody>
{% endfor %}
<tr class="cart-total-sec"><td class="cart-price">{{ cart.total }}</td></tr>
</div>
Any help is really appreciated.
First you are making mistake, as i can see there's form in table, on refreshing you will lose that form so i guess you should append items in form not in .cart-body.
And for emptying html use cartBody.html(""); and you don't have to use productRows.html("") at all.
The issue as pointed out by Ultrazz008, was that the HTML was incorrectly formatted. For reference:
<table class="cart-table">
<tbody class="cart-body">
<form method="POST" class='form-product-ajax' action='{% url "shopping-cart-remove" %}' data-endpoint='{% url "shopping-cart-remove" %}'>
{% csrf_token %} {% for item in cart.items %}
<tr class=cart-product>
<td>{{ item.quantity}} x {{ item.product.name }} {{ item.subtotal }}
<input type="hidden" name='id' value='{{ item.product.id }}'>
<button class='remove-btn'>remove</button>
</td>
{% endfor %}
</tr>
</form>
</tbody>
<tr class="cart-total-sec">
<td class="cart-price">{{ cart.total }}</td>
</tr>
</table>

Categories