我已经创建了基本的购物篮,可以在其中向会话中添加产品。我添加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 查找元素