购物车商品数量减实现
实现原理是找到这条商品数据,修改其中的数量,每点击一次减号按钮就自减一,当检查到数量为0时,从购物车表中删去。
cart.html
给标签增加选择器
<section>
<button class="subShopping">-</button>
<span>{{ cart.c_goods_num }}</span>
<button class="addShopping">+</button>
</section>
cart.js
$(function(){
$('.confirm').click(function(){
console.log('change state');
/*修改选中状态*/
var $confirm = $(this);
var $li = $confirm.parents('li');
var cartid = $li.attr('cartid');
/*利用ajax,找到对应标签之后发送给服务器修改状态*/
$.getJSON('/peiqi1/changecartstate/',{'cartid': cartid}, function (data){
console.log(data);
if (data['status']===200){
if(data['c_is_select']){
$confirm.find('span').find('span').html('√');
}else{
$confirm.find('span').find('span').html('');
}
}
})
})
$('.subShopping').click(function (){
var $sub = $(this);
var $li = $sub.parents('li');
var cartid = $li.attr('cartid');
$.getJSON('/peiqi1/subshopping/', {'cartid':cartid}, function(data){
console.log(data);
/*把修改之后的数量传回用户所在的前端页面*/
if (data['status']===200){
if (data['c_goods_num']> 0){
var $span = $sub.next('span');
$span.html(data['c_goods_num']);
}else{
$li.remove();
}
}
})
})
})
添加url
用来减少商品数量
url(r'^subshopping/', views.subshopping, name='sub_shopping'),
views
def subshopping(request):
# 接受cartid
cartid = request.GET.get('cartid')
# 从数据库中查找到对应的
cart_obj = Cart.objects.get(pk=cartid)
data = {
'status': 200,
'msg': 'ok',
}
# 判断数据库中商品数量
if cart_obj.c_goods_num > 1: # 如果数量大于1就减少1
cart_obj.c_goods_num = cart_obj.c_goods_num - 1
cart_obj.save()
data['c_goods_num'] = cart_obj.c_goods_num
else: # 如果数量小于等于1就从数据库中删除
cart_obj.delete()
data['c_goods_num'] = 0
return JsonResponse(data=data)
测试
购物车商品数量增实现
实现原理是找到这条商品数据,修改其中的数量,每点击一次加号按钮就自增一
cart.html
给标签增加选择器
<section>
<button class="subShopping">-</button>
<span>{{ cart.c_goods_num }}</span>
<button class="addShopping">+</button>
</section>
cart.js
不需要像减少那样判断商品数量是否小于0
$('.addShopping').click(function (){
var $add = $(this);
var $li = $add.parents('li');
var cartid = $li.attr('cartid');
$.getJSON('/peiqi1/addshopping/', {'cartid': cartid}, function (data) {
console.log(data);
/*把修改之后的数量传回用户所在的前端页面*/
if (data['status'] === 200) {
$('#total_price').html(data['total_price']); //实时更新价格
var $span = $add.prev('span');
$span.html(data['c_goods_num']);
}
})
})
添加url
用来增加商品数量
url(r'^addshopping/', views.addshopping, name='add_shopping'),
views
def addshopping(request):
# 接受cartid
cartid = request.GET.get('cartid')
# 从数据库中查找到对应的
cart_obj = Cart.objects.get(pk=cartid)
data = {
'status': 200,
'msg': 'ok',
}
# 增加商品数量
cart_obj.c_goods_num = cart_obj.c_goods_num + 1
cart_obj.save()
data['c_goods_num'] = cart_obj.c_goods_num
return JsonResponse(data=data)
测试
购物车全选逻辑
默认状态
全选按钮虚是选中
- 内部所有商品都是选中的
全选按钮未选中
- 内部商品中只要存在未选中的,那么全选就应该是未选中的
点击全选
原状态是选中
- 全选和所有商品都变成未选中
原状态是未选中
- 全选和所有商品都变成选中
点击单个商品
商品由选中变成未选中
- 全选一定变成未选中
商品由未选中变成选中
- 全选的默认状态就是未选中
- 可能变成选中
默认状态
views:
def cart(request): carts = Cart.objects.filter(c_user=request.user) # 判断是不是全部被选中,全部被选中就返回True is_all_select = not carts.filter(c_is_select=False).exists() data = { 'title': '购物车', 'carts': carts, 'is_all_select': is_all_select, } return render(request, 'main/cart.html', context=data)
cart.html:(74至78)
{% extends 'base_main.html' %} {% load static %} {% block ext_css %} {{ block.super }} <link rel="stylesheet" href="{% static 'peiqi1/main/css/cart.css' %}"> {% endblock %} {% block ext_js %} {{ block.super }} <script type="text/javascript" src="{% static 'peiqi1/main/js/cart.js'%}"></script> {% endblock %} {% block content %} <div id="cart"> <h3>Cart</h3> <div class="full"> <section> <ul> <li>收 货 人: PEIQI</li> <li>电 话: 123456789</li> <li>地 址: CHINA</li> </ul> <div class="bill"> <p>闪送超市</p> <p>1元起送,满30免运费,22:00前可送达</p> <a href="">凑单专区</a> </div> <div class="delivery"> <span>收获时间</span> <span>一小时之内送达</span> <a href="#">可预订></a> </div> <div> <div class="delivery"> <span>收货备注</span> <input type="text" placeholder="可输入100字以内的特殊要求"> </div> </div> <ul> {% for cart in carts %} <li class="menuList" cartid="{{ cart.id }}"> <div class="confirm"> <span> {% if cart.c_is_select %} {# 判断购物车中商品是否被选中 #} <span>√</span> {% else %} <span></span> {% endif %} </span> </div> <a href="#"> <img src="{{ cart.c_goods.productimg }}" alt="{{ cart.c_goods.productlongname }}"> <p>{{ cart.c_goods.productlongname }}</p> <p class="presentPrice">{{ cart.c_goods.price}}</p> </a> <section> <button class="subShopping">-</button> <span>{{ cart.c_goods_num }}</span> <button class="addShopping">+</button> </section> </li> {% endfor %} </ul> <div class="payTheBill"> <div class="all_select"> <span> {% if is_all_select %} {# 如果是全选,全选框就勾上 #} <span>√</span> {% else %} <span></span> {% endif %} </span> </div> <p> <span>全选</span> <span>共计:</span> <span>0</span> </p> </div> <a href="#">下单</a> </section> </div> </div> {% endblock %}
点击全选按钮
我们生成两个列表,用来分别存放选中和未选中元素。
在js中添加点击事件:$('.all_select').click(function(){ var $all_select = $(this); // 点击全选按钮,如果有未选中就变成选中的,如果是全选中的就变成所有的都未选中 var select_list = []; var unselect_list = []; $('.confirm').each(function(){ var $confirm = $(this); var cartid = $confirm.parents('li').attr('cartid'); if($confirm.find('span').find('span').html().trim()){ //将选中的加入选中的表 select_list.push(cartid); }else{ //将未选中的加入未选中表 unselect_list.push(cartid); } }) //遍历 console.log(select_list) console.log(unselect_list) }) })
测试:
下面我们要实现当没有选中的列表大于0,就将unselect_list发送给服务器改为选中。
新建urls:
url(r'^allselect/', views.allselect, name='all_select'),
这里要注意服务器不能接收列表,所以需要将列表转换一下,将元素用#号连接起来,发送到服务端时再用split切割开来。
cart.js:
$('.all_select').click(function(){
var $all_select = $(this);
// 点击全选按钮,如果有未选中就变成选中的,如果是全选中的就变成所有的都未选中
var select_list = [];
var unselect_list = [];
$('.confirm').each(function(){
var $confirm = $(this);
var cartid = $confirm.parents('li').attr('cartid');
if($confirm.find('span').find('span').html().trim()){
//将选中的加入选中的表
select_list.push(cartid);
}else{ //将未选中的加入未选中表
unselect_list.push(cartid);
}
}) //遍历
//当没有选中的列表大于0,就将unselect_list发送给服务器改为选中
if(unselect_list.length>0){
$.getJSON('/peiqi1/allselect', {'cart_list': unselect_list.join('#')}, function (data){
console.log(data);
})
}
})
})
views:
def allselect(request):
cart_list = request.GET.get('cart_list')
cart_list = cart_list.split('#')
print(cart_list)
data = {
'status': 200,
}
return JsonResponse(data=data)
测试:
接下来我们将商品状态改为取反的状态:
views:
def allselect(request):
cart_list = request.GET.get('cart_list')
cart_list = cart_list.split('#')
carts = Cart.objects.filter(id__in=cart_list) # 这样查询数据库的次数变少
for cart_obj in carts:
cart_obj.c_is_select = not cart_obj.c_is_select
cart_obj.save()
data = {
'status': 200,
'msg': 'ok',
}
return JsonResponse(data=data)
测试:我们点击全选按钮,然后刷新网页就会发现,未选中的商品也为选中状态。
现在我们要让前端伴随着我们变化
cart.js:
//当没有选中的列表大于0,就将unselect_list发送给服务器改为选中
if(unselect_list.length>0){
$.getJSON('/peiqi1/allselect', {'cart_list': unselect_list.join('#')}, function (data){
console.log(data);
if(data['status']===200){
$('.confirm').find('span').find('span').html('√'); //按下全选,将所有的按钮都改为选中
$all_select.find('span').find('span').html('√');
}
})
}else{
if (select_list.length>0){
$.getJSON('/peiqi1/allselect', {'cart_list': select_list.join('#')}, function (data){
console.log(data);
if(data['status']===200){
$('.confirm').find('span').find('span').html(''); //取消全选,将所有选中改为未选中
$all_select.find('span').find('span').html('');
}
})
}
}
})
判断全选按钮状态
当单个商品选中状态改变时,全选按钮状态也要做判断而改变。
views:
def change_cart_state(request):
# 从ajax获得商品id,但是这里有个隐藏漏洞,这里没有验证这个cart_id是用户已经存在的
cart_id = request.GET.get('cartid')
# 去数据库中匹配对应的商品id
cart_obj = Cart.objects.get(pk=cart_id)
# 将原本选中的状态取反
cart_obj.c_is_select = not cart_obj.c_is_select
# 记得保存,如果不保存,数据库的状态不会改变
cart_obj.save()
# 判断这个商品是否被选中
is_all_select = not Cart.objects.filter(c_user=request.user).filter(c_is_select=False).exists()
data = {
'status': 200,
'msg': 'change ok',
'c_is_select': cart_obj.c_is_select,
'is_all_select': is_all_select,
}
return JsonResponse(data=data)
现在我们要在前端实现全选按钮的状态变化:
$(function(){
$('.confirm').click(function(){
console.log('change state');
/*修改选中状态*/
var $confirm = $(this);
var $li = $confirm.parents('li');
var cartid = $li.attr('cartid');
/*利用ajax,找到对应标签之后发送给服务器修改状态*/
$.getJSON('/peiqi1/changecartstate/',{'cartid': cartid}, function (data){
console.log(data);
if (data['status']===200){
if(data['c_is_select']){
$confirm.find('span').find('span').html('√');
}else{
$confirm.find('span').find('span').html('');
}
if (data['is_all_select']){
$('.all_select span span').html('√');
}else{
$('.all_select span span').html('');
}
}
})
})
测试:略
jQuery补充
问:jquery中变量加$和不加$有什么区别?
- 答:没有区别,只是习惯。 一般在给jquery对象取名的时候在前面加$。 一看就知道是jquery对象。
变量zhuan命名规则中shu起始字符可以是 字母,下划线(_),美元符($),只是很多的js库喜欢使用$作为全局变量标志。
jQuery也不例外.加上$,作为jQuery变量标志更容易进行区分。
在使用jQuery 中,如果一个变量被$();包裹。那么说明这个变量需要包装成jQuery对象才可以使用。
而在jQuery自己的作用域所创建的变量不需要加$();包裹。举一个很简单的例子:比如,一个在js中的this指针。而这个指针需要在jQuery中使用,那么就需要用$();包裹成jQuery中的对象,也就需要这样写:$(this)。
如果是一个变量起名为$xxx,而另一个变量名为xxx。那么这是一种良好的代码习惯。是区分使用jQuery创建的变量和javascript自己创建的变量。
next()方法
next() 方法返回被选元素的后一个同级元素。
同级元素是共享相同父元素的元素。
注意:该方法只返回一个元素。
DOM 树:该方法沿着 DOM 元素的后一个同级元素向前遍历。
prev()方法
prev() 获得匹配元素集合中每个元素紧邻的前一个同胞元素,通过选择器进行筛选是可选的。
此处评论已关闭