【发布时间】:2021-06-09 03:58:31
【问题描述】:
我基本上有一个购物车部分,用户应该能够从购物车中删除商品,然后使用 AJAX 刷新内容。但是,在删除购物车项目后,响应从异步变为同步,我无法确定原因。
对不起,编程新手,所以很多事情可能不是做某事的最佳方式,感谢任何帮助!
Views.py
def checkout_detail_api_view(request):
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.cartItems_set.all()
'# create lists for items to be put in dictionary'
productId_list = []
product_url = []
productName_list = []
location_list = []
img_list = []
checkoutList = {}
for item in items:
'# append into lists'
productId_list.append(item.product_id)
productName_list.append(item.product.title)
product_url.append(item.product.get_absolute_url())
img_list.append(item.product.image.url)
location_list.append(item.product.location)
checkoutList["id"] = productId_list
checkoutList["title"] = productName_list
checkoutList["location"] = location_list
checkoutList["image"] = img_list
checkoutList["url"] = product_url
checkout_data = {"checkoutList": checkoutList}
return JsonResponse(checkout_data)
def cart_update(request):
product_id = request.POST.get('product_id')
customer = request.user.customer
if product_id is not None:
try:
product_title = Product.objects.get(id=product_id)
except BlogPost.DoesNotExist:
print("Show message to user, product is gone?")
'# gets or makes product order'
order, created = Order.objects.get_or_create(customer=customer, complete=False)
'# gets or makes cartItem'
cartItem, created = cartItems.objects.get_or_create(order=order, product=product_obj)
'# gets all items in cart '
items = order.cartItems_set.all()
'# for each item in cart remove quantity, else add quantity'
for item in items:
'# remove (max quantity of 1)'
if int(product_id) == int(item.product_id) and item.quantity >= 1:
cartItem.quantity = 0
product_added = False
'# Add '
elif int(product_id) == int(item.product_id):
cartItem.quantity = 1
product_added = True
cartItem.save()
if cartItem.quantity <= 0:
cartItem.delete()
'#reinitialize cart items after updating above'
items = order.cartItem_set.all()
cartItemCount = items.count()
'# this is not being called on second attempt of removing item from cart'
if request.is_ajax():
json_data = {
"added": product_added,
"removed": not product_added,
"cartItemCount": cartItemCount
}
return JsonResponse(json_data)
'# if request is not ajax redirect page - this is being called and I dont know why'
return redirect("/see-and-do/checkout")
def checkout(request):
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.cartItem_set.all()
cartItems = items.count()
productId_list = []
productName_list = []
location_list = []
for item in items:
'# append into lists'
productId_list.append(item.product_id)
productName_list.append(item.product.title)
location_list.append(item.product.location)
checkoutList = dict(zip(items, location_list))
context = {'checkoutList':checkoutList, 'cartItems': cartItems}
return render(request, 'posts/checkout.html', context)`
checkout.html
{% if cartItems > 0 %}
<div class="table-responsive">
<table class="table cart-table">
<tbody class="cart-body">
{% for cartItem, location in checkoutList.items %}
<tr class="cart-product1">
<td rowspan="2"><img src="{{cartItem.product.image.url}}"></td>
<td><h5><b>{{cartItem.product.title}}</b></h5></td>
<td>
<form class='form-product-ajax' method="POST" action="/see-and-do/checkout/cart-update/" data-endpoint="/see-and-do/checkout/cart-update/" > {% csrf_token %}
<input class='cart-item-product-id' type='hidden' name='product_id' value = '{{ cartItem.product.id}}' />
<button type="submit" id="remove-btn">
<i class="bi bi-dash"> </i>
</button>
</form>
</td>
</tr>
<tr class="cart-product2">
<td><small class="text-muted">{{location}}</small></td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class='lead'>No products added</p>
{% endif %}
js.html
<script>
$(document).ready(function(){
var productForm = $(".form-product-ajax")
productForm.submit(function(event){
event.preventDefault();
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){
var submitSpan = thisForm.find(".submit-span")
if (data.added) {
submitSpan.html(
'<button type="submit" id="remove-btn" style="background-color:#ff3333;"><i class="bi bi-dash"> </i><span class="tooltip-text">Remove item</span></button>'
)
} else {
submitSpan.html(
'<button type="submit" id="add-btn"><i class="bi bi-plus-square"> </i><span class="tooltip-text">Add to your enquiry</span></button>'
)
}
var navbarCount = $(".navbar-cart-count")
navbarCount.text(data.cartItemCount)
var currentPath = window.location.href
if (currentPath.indexOf("checkout") != -1) {
refreshCheckout()
}
},
error:function(errorData){
console.log("error")
console.log(errorData)
}
})
})
function refreshCheckout(){
var cartTable = $(".cart-table")
var cartBody = cartTable.find(".cart-body")
var productRowOne = cartBody.find(".cart-product1")
var productRowTwo = cartBody.find(".cart-product2")
var currentUrl = window.location.href
var refreshCheckoutUrl = '/see-and-do/api/checkout/';
var updateCheckoutMethod = "GET";
var data = {};
$.ajax({
url: refreshCheckoutUrl,
method: updateCheckoutMethod,
data: data,
success: function(data){
if (data.checkoutList.id.length > 0) {
//remove current checkout.html for AJAX response
productRowOne.html(" ")
productRowTwo.html(" ")
$.each(data.checkoutList.id , function(index){
//prepends everything inside the for loop shown in checkout.html
cartBody.prepend("<tr class=\"cart-product1\"><td rowspan=\"2\"><a href ='" + data.checkoutList.url[index] + "'><img src=" + '"' + data.checkoutList.image[index] + '"' + "></a></td><td><h5><b><a href ='" + data.checkoutList.url[index] + "'>" + data.checkoutList.title[index] + "</a></b></h5></td><td><form class=\"form-product-ajax\" method=\"POST\" action=\"/see-and-do/checkout/cart-update/\" data-endpoint=\"/see-and-do/checkout/cart-update/\">" + '{% csrf_token %}' + "<input type=\"hidden\" name=\"product_id\" value =" + '"' + data.checkoutList.id[index] + '"' + "/><button type=\"submit\" id=\"remove-btn\"><i class=\"bi bi-dash\"> </i></button></form></td></tr><tr class=\"cart-product2\"><td><small class=\"text-muted\">" + data.checkoutList.location[index] + "</small></td><td></td></tr>")
})
} else {
window.location.href = currentUrl
}
},
error: function(errorData){
console.log("checkout error")
console.log(errorData)
}
})
}
})
</script>
所以脚本第一次运行时一切正常,但是当我再次单击时,由于响应不是 AJAX,它只是通过 cart_update view.py 重新加载整个页面,但我不明白为什么它不会AJAX,我认为是因为它在响应中添加了“.form-product-ajax”之后没有找到?
-- 编辑--
我使用此表单的其他时间是在产品索引页面中。这就是涉及跨度的地方。
<form class='form-product-ajax' method="POST" action="/see-and-do/checkout/cart-update/" data-endpoint="/see-and-do/checkout/cart-update/"> {% csrf_token %}
<input type='hidden' name='product_id' value = '{{ product.id}}' />
<span class="submit-span">
{% if product.id in productId_list %}
<button type="submit" id="remove-btn">
<i class="bi bi-dash"> </i>
<span class="tooltip-text">Remove item</span>
</button>
{% else %}
<button type="submit" id="add-btn">
<i class="bi bi-plus-square"> </i>
<span class="tooltip-text">Add to your enquiry</span>
</button>
{% endif %}
</span>
</form>
【问题讨论】:
-
嗨,
submit-span在哪里? -
@swati - 我在产品索引页面上使用提交跨度,因此我可以更改表单按钮以添加或删除,但由于我只想在结帐页面上删除,我已将其删除。如果您想查看,我已经编辑了帖子以包含表格。
-
你能像这样更改事件处理程序吗:
$(document).on("submit", ".form-product-ajax", function(event) { //your codes ..})看看是否有效 -
@Swati Legend,让它工作,非常感谢
-
欢迎您.. 只是因为您的表单是动态创建的,所以您需要将其与您的 dom 中已经存在的静态元素绑定:)
标签: javascript jquery json django ajax