购物车商品数量减实现

实现原理是找到这条商品数据,修改其中的数量,每点击一次减号按钮就自减一,当检查到数量为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>收&nbsp;&nbsp;货&nbsp;&nbsp;人:&nbsp;PEIQI</li>
                      <li>电&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;话:&nbsp;123456789</li>
                      <li>地&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;址:&nbsp;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="#">可预订&gt;</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() 获得匹配元素集合中每个元素紧邻的前一个同胞元素,通过选择器进行筛选是可选的。

最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏