Django jquery with ajax.如何使jquery侦听生成的表单的id



我已经创建了基本的购物篮,可以在其中向会话中添加产品。我添加ajax是为了避免每次在我的购物篮中添加内容时都重新加载我的网站。问题是我已经用for循环生成了表单。每个表单都有隐藏的输入,其中包含我想要添加的产品id和数量。我在寻找解决方案时遇到了问题,如何让jquery监听表单的ID(它有产品的ID)。我知道我可以通过做任何事情

$(this).attr('id');

但当我试着按下按钮时,第一个按钮一切都很好。但当我按下生成的另一个时,它不执行ajax,它将进入我的views.py中的第二部分,在那里我检查请求是否不是ajax。它发生在所有>第一个的按钮上。我在下面张贴我的代码:

jquery:

$(document).ready(function () {
//$('#custom_user_form').on('submit', function (event) {
//    event.preventDefault();
//    add_product();
//
//});
$('button[type=submit]').on('click', function (event) {
    event.preventDefault();
    add_product();
});
//$('button[type=submit]').on('click', function(){
//    var post_primary_key = $(this).attr('id').split('-')[2];
//    console.log(post_primary_key)
//    delete_message(post_primary_key);
//});

function add_product() {
    $.ajax({
        url: window.location.pathname+'add_product/',
        type: 'POST',
        datatype: 'json',
        async: false,
        data: {
            product_id: $('#product_id').val(),
            quantity: $('#quantity').val(),
            csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').val()
        },

        success: function (json) {
            $('#quantity').val(0);
            $('#price span').remove();
            $("#price").prepend("<span><strong> <h3>Overall price of all your products in basket: </strong> " + json.price + "$$$</h3>Recently added products: " + json.name + "</span>");
            console.log("success");
        }
    });
};

});

我的生成表单模板:

<tbody>
  {% if products %}
    {% for p in products %}
    <tr>
      <th scope="row">{{ p.id }}</th>
      <td>{{p.name}}</td>
      <td>{{p.price}} $</td>
      <td>{{p.stock}} units</td>
        {% if user.is_authenticated %}
        <form id="custom_user_form" method="post" action="add_product/">
            <td>
                {% csrf_token %}
                {{ add_product_form.as_p }}
                <!-- Provide a button to click to submit the form. -->
                <input id="product_id" type="number" name="product_id" value={{p.id}} hidden="True" />
                <input type="number" id="quantity" name="quantity" value="0" min="0" max="{{p.stock}}"  style="width: 100px"/>
            </td>
            <td>
                <button type="submit"  id = "{{p.id}}" class="btn btn-primary">Add</button>
            </td>
        </form>
        {% endif %}
    </tr>
  {% endfor %}
  </tbody>
</table>

{%endif%}

最后是我的观点.py

def add_to_cart(request, category_id):
if request.is_ajax():
    if request.method == 'POST':
        product_id = request.POST.get('product_id')
        quantity = request.POST.get('quantity')
        price = 0.0
        if not request.session.get('koszyk').get(product_id, None):
            request.session['koszyk'][request.POST.get('product_id')] = 0
        item = ShopProduct.objects.get(id = product_id)
        quantity = float(quantity)
        item_price = float(item.price)
        price += quantity * item_price
        item.stock -= quantity
        item.save()
        request.session['koszyk'][request.POST.get('product_id')] += int(request.POST.get('quantity'))
        request.session['koszyk']['cena'] += price
        new_item = ShopProduct.objects.get(id = product_id)
        name = new_item.name
        print "_"*100
        print name
        price = request.session['koszyk']['cena']
        status = 200
        data = {'status': 200, 'price': price, 'name': name}
        return HttpResponse(json.dumps(data), content_type="application/json")
elif not request.is_ajax() and request.method == 'POST':
    add_product_form = AddProductForm(data=request.POST, request_product_id=request.POST['product_id'])
    price = 0
    print "JEBLEM PIRNTA "*100
    if add_product_form.is_valid():
        if not request.session.get('koszyk').get(request.POST.get('product_id'), None):
            request.session['koszyk'][request.POST.get('product_id')] = 0
        item = ShopProduct.objects.get(id=request.POST.get('product_id'))
        quantity = float(request.POST.get('quantity'))
        item_price = float(item.price)
        price += quantity * item_price
        item.stock -= quantity
        item.save()
        request.session['koszyk'][request.POST.get('product_id')] += add_product_form.cleaned_data['quantity']
        request.session['koszyk']['cena'] += price
        products_list = ShopProduct.objects.all()
    else:
        print add_product_form.errors
        messages.error(request, 'Smth went wrong, check log')
else:
    add_product_form = AddProductForm()
koszyk = request.session['koszyk']
products_list = ShopProduct.objects.all()

return render(request, 'tango/cart.html', {'products_list': products_list}, context_instance=RequestContext(request))

问题是我怎么听那些身份证?

重复的HTML ID是没有意义的,因此要始终从多个产品表单中清除它们,以支持类。

<form class="product_form" method="post" action="add_product/">
    <td>
        {% csrf_token %}
        {{ add_product_form.as_p }}
        <input type="hidden" class="product_id" name="product_id" value={{p.id}} />
        <input type="number" class="quantity" name="quantity" value="0" min="0" max="{{p.stock}}"  style="width: 100px"/>
    </td>
    <td>
        <button type="submit" class="btn btn-primary">Add</button>
    </td>
</form>

现在将您的add_product函数附加为所有表单的提交处理程序。在处理程序中,按类而不是id选择所有内容。

评论中的进一步解释

$(document).ready(function() {
    $('.product_form').on('submit', function(event) {
        event.preventDefault();
        //remember the form element
        var $form = $(this);
        //disable the submit button and remember it for later 
        var $button = $form.find("button[type='submit']").attr('disabled', true);
        //find the product_id, quantity and price fields in the form
        var $price = $form.find(".price");
        var $product_id = $form.find(".product_id");
        var $quantity = $form.find(".quantity");
        //Now do the ajax
        $.ajax({
            url: window.location.pathname + 'add_product/',
            type: 'POST',
            datatype: 'json',
            // async: false,//NO, never use async: false!!!
            data: {
                product_id: $product_id.val(),
                quantity: $quantity.val(),
                csrfmiddlewaretoken: $('input[name="csrfmiddlewaretoken"]').val()
            }
        }).then(function(json) {
            $price.find("span").remove();
            $quantity.val(0);
            $price.prepend("<span><strong> <h3>Overall price of all your products in basket: </strong> " + json.price + "$$$</h3>Recently added products: " + json.name + "</span>");
        }, function() {
            //here give the user some indication that the ajax failed
        }).always(function() {
            $button.attr('disabled', false);
        });
    });
});

这里没有严格的必要,但您应该养成使用promise方法.then().done().fail().always()的习惯,这些方法由$.ajax()返回的对象提供。有关内存信息,请参阅文档

您有多个具有相同id(product_id,quantity)的html元素。所以,当您使用jquery获取值时,会出现不一致。尝试使用单击按钮的相对位置来获取值,所以如果您知道哪个按钮被单击了,您就可以找到相对于您单击的按钮的product_id和quantity元素。

也不要使用submit按钮进行ajax调用,使用inputtype="button"来防止不必要的回发。

Look:Jquery Find Method和属性Equal Selector按名称而不是id 查找元素

最新更新