【问题标题】:jQuery not finding class after AJAX responseAJAX响应后jQuery没有找到类
【发布时间】: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


【解决方案1】:

您可以尝试通过使用event.preventDefault(); 并在按下按钮时通过 Jquery 执行表单提交来防止按钮的默认行为。检查.submit()

【讨论】:

  • 这已经在前几行的 JS.html 代码中,但由于某种原因,一旦调用 refreshCheckout 函数并替换 checkout.html 中的表单,它就不会被触发。 .form-product-ajax 是这种新形式,只是替换后似乎 JavaScript 没有找到它?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
相关资源
最近更新 更多