9.购物车的选择和购物车商品数量的调整

一、购物车的选择

要实现购物车中商品的选择,包括商品的单选和所有商品的全选。
第一步实现商品全选的函数:

1.创建checkAll 函数——实现商品的全选

这个函数的作用是选中或取消选中购物车中的所有商品。
当用户点击页面顶部的全选复选框时,会触发这个函数。
函数接收一个参数 checked,这个参数表示全选复选框的选中状态(true 表示选中,false 表示未选中)。
函数内部通过 document.querySelectorAll(“.my-box”) 获取页面上所有的商品复选框,并将它们的选中状态设置为与全选复选框一致。

    const checkAll = (checked) => {
        const boxes = document.querySelectorAll(".my-box");
        for (let i = 0; i < boxes.length; i++) {
            boxes[i].checked = checked;
        }
    }

函数解释:

  1. 参数checked是代表商品选择状态的布尔值变量,ture表示商品全选,false表示不全选。
  2. 其后我们通过类选择器找到所有匹配的元素,也就是选择所有带有 my-box 类的复选框元素。,并将document.querySelectorAll的NodeList类型的返回值放在boxes对象中。
    在每一个商品卡片都有一个复选框:
        <td class="ps-4" >
          <input style="transform: scale(1.5);" class="form-check-input my-box"
          onclick="checkSingle()"
                 type="checkbox" value="${item.meal_id}">
        </td>

在这里from-check-input 是 Bootstrap 框架中的一个类名,它用于样式化 HTML 表单中的复选框(checkbox)和单选按钮(radio button)元素,其后的my-box就是它的类名。代码中 type="checkbox"定义了这是一个复选框。所以checkAll函数回匹配所有my-box的元素,通过遍历统一设置复选框状态,达到全选或全不选的效果。

  1. 目前我们只涉及到了两种选择器:
    类选择器(Class Selector):以点(.)开头,后面跟着类名。它用于选择所有具有指定类的元素。
    ID 选择器(ID Selector):以井号(#)开头,后面跟着 ID 名称。它用于选择具有指定 ID 的单个元素。
  2. 函数的最后然后遍历对象,把所有匹配的元素的选择状态都设置为入参的状态。

2.创建checkSingle 函数——实现商品的单选

这个函数的作用是更新全选复选框的状态,以反映用户对单个商品复选框的操作。
代码逻辑:当用户选中或取消选中任何一个商品复选框时,会触发这个函数。
函数内部首先获取所有商品复选框,然后检查它们是否全部被选中。
如果所有商品复选框都被选中,则全选复选框也被设置为选中状态;如果有任何一个商品复选框未被选中,则全选复选框也被设置为未选中状态。

    const checkSingle = () => {
        document.querySelector(".all-box").checked = document.querySelectorAll(".my-box:checked").length === document.querySelectorAll(".my-box").length;
    }

函数里面就只有一行代码。但是我们将代码分开会比较好理解一点。

  1. document.querySelector(".all-box").checked:
    这行代码使用 document.querySelector 方法选择页面上具有 .all-box 类的复选框元素。
    .checked 属性用于获取或设置该复选框的选中状态。
  2. document.querySelectorAll(".my-box:checked").length:
    这行代码使用 document.querySelectorAll 方法选择页面上所有已经被选中的具有 .my-box 类的复选框元素。
    :checked 是一个伪类选择器,用于选择所有选中状态的复选框。
    .length 属性返回选中的复选框数量。
  3. document.querySelectorAll(".my-box").length:
    这行代码使用 document.querySelectorAll 方法选择页面上所有具有 .my-box 类的复选框元素。
    .length 属性返回所有这些复选框的数量。
  4. document.querySelector(".all-box").checked = document.querySelectorAll(".my-box:checked").length === document.querySelectorAll(".my-box").length;
    这是一个赋值操作,它将 .all-box 类复选框的选中状态设置为两个长度相等的条件。
    如果所有具有 .my-box 类的复选框都被选中(即选中的数量等于总数),那么 .all-box 类复选框也将被设置为选中状态(true)。
    如果不是所有具有 .my-box 类的复选框都被选中,那么 .all-box 类复选框将被设置为未选中状态(false)。
    函数完成后,我们要在HTML相应的板块添加点击事件来调用函数:

全选复选框处,添加点击事件调用checkAll函数:

<th class="ps-4">
		<input style="transform: scale(1.5);" class="form-check-input all-box" onclick="checkAll(this.checked)"
         type="checkbox" value="">
</th>

商品卡片复选框添加点击事件调用checkSingle函数

        <td class="ps-4" >
          <input style="transform: scale(1.5);" class="form-check-input my-box"
          onclick="checkSingle()"
                 type="checkbox" value="${item.meal_id}">
        </td>

注意:HTML 复选框(checkbox)元素本身不自带点击属性,但是它们具有一些内置的行为和事件,所以在上一篇文章,获取购物车清单时用户可以点击复选框来切换它的选中状态。
在这里我们添加onclick属性点击事件来获取选中状态或调用函数。
到这里购物车的选择就做好了,只涉及前端。

二、购物车商品数量的调整

效果实现要求,用户通过商品数量旁的加减号实现商品数量的增加或减少。同时后端数据库中的数据也要及时的做出变化,保证数据一致。

1.前端

要实现通过点击加减号来进行增减商品,我们为商品的加减号处的元素进行修改,添加onclick点击相应事件,调用函数:

          <div class="input-group"  style="width:150px;">
            <span  onclick="changeNum('${item.s_id}','${item.meal_id}','-')"class="fs-4 text-white bg-danger text-center " style="width:40px;cursor:pointer;" >-</span>
            <input readonly id="cartitem_num_${item.s_id}" type="text" class="form-control form-control-sm text-center fs-5 text-danger"  value="${item.s_num}" />
            <span  onclick="changeNum('${item.s_id}','${item.meal_id}','+')"class="fs-4 text-white bg-danger text-center " style="width:40px;cursor:pointer;" >+</span>
          </div>

完成后就需要实现函数像后端传达:

    const changeNum = async (s_id, meal_id, opr) => {
        let s_num = parseInt(document.querySelector(`#cartitem_num_${s_id}`).value);
        s_num = opr == '+' ? (s_num + 1) : (s_num - 1);
        const resp = await fetch(`cart/num?meal_id=${meal_id}&s_num=${s_num}`);
        if (!resp.ok) {
            toast("失败", "更改数量失败!");
            return;
        }
        const result = await resp.json();
        if (!result.success) {
            toast("失败", result.message);
            return;
        }
        if (s_num < 1) {
            const dom = document.querySelector(`#cartitem_tr_${s_id}`);
            dom.remove();
        } else {
            document.querySelector(`#cartitem_num_${s_id}`).value = s_num;
        }
    }

代码解释
1. const changeNum = async (s_id, meal_id, opr) => { ... }:
这里定义了一个名为 changeNum 的异步函数,它接受三个参数:s_id:商品的唯一标识符(通常是数据库中的ID),meal_id:与 s_id 相关联的餐品ID,opr:操作符,用于指示数量是增加(‘+’)还是减少(‘-’)。
2. let s_num = parseInt(document.querySelector(#cartitem_num_${s_id}).value);:代码通过 querySelector 方法和 s_id 来获取对应商品数量输入框的值,parseInt 函数将输入框的值转换为整数。
3. s_num = opr == '+' ? (s_num + 1) : (s_num - 1);:这行代码使用三元运算符来决定是增加还是减少商品数量,如果 opr 是 ‘+’,则数量增加1,如果 opr 是 ‘-’,则数量减少1。
4. const resp = await fetch(cart/num?meal_id=${meal_id}&s_num=${s_num});:用 fetch 函数向服务器发送一个请求,以更新商品的数量,请求的 URL 包含 meal_id 和新的 s_num 值。
5. 下一步检查响应对象的 ok 属性,如果请求失败,则显示一个错误消息。
6. 如果相应欧克那么,再代码解析响应体中的 JSON 数据。
7. 继续检查从服务器返回的结果是否包含 success 属性,如果不成功,则显示错误消息。
8. 对数量经行判断,检查更新后的数量是否小于1。如果是,那么从DOM中移除该商品的行,表示该商品已从购物车中删除。如果不是,那么更新输入框的值为新的数量。

前端就完成了,就要开始后端,处理前端发过来的响应了

2.后端

前端有数据信息包含在响应中,所以我们要建立一个类存放数据

2.1创建ShoppingCartDto类

public class ShoppingCartDto {
    private Long meal_id;
    private Integer s_num;

    public Long getMeal_id() {
        return meal_id;
    }

    public void setMeal_id(Long meal_id) {
        this.meal_id = meal_id;
    }

    public Integer getS_num() {
        return s_num;
    }

    public void setS_num(Integer s_num) {
        this.s_num = s_num;
    }
}

这是一个实体类包含meal_id和s_num属性,以及相应的get、set方法,也就是对应的从前端传过来的数据。

2.2在CartServlet类中添加修改购物车餐品数量功能

此前我们在这个类中实现了购物车清单的功能,现在我们要在这个类中再添加一个修改购物车商品数量的功能。
首先是熟悉的配方熟悉的配料:
第一步,增加注解中的路径,以调用不同的方法:

@WebServlet({
        "/cart/list",
        "/cart/num"
})

第二步,在switch分支结构中新增case板块:

            case "/cart/num":
                cartNum(req,resp);
                break;

第三步,实现函数:

    private void cartNum(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        User user =(User) req.getSession().getAttribute("CurrUser");
        if(user==null){
            MyWeb.printJson(resp,R.err("请先登录"));
            return;
        }
        ShoppingCartDto cartDto =MyWeb.getBeanFromRequest(ShoppingCartDto.class,req);
        String sql ="delete from t_shoppingcart where u_id= ? and meal_id = ?";
        if(cartDto.getS_num()<1){
            DaoCreater.currentDao().update(sql,user.getU_id(),user,cartDto.getMeal_id());
        }else {
            sql = "update t_shoppingcart set s_num = ? where u_id = ? and meal_id = ?";
            int count = DaoCreater.currentDao().update(sql, cartDto.getS_num(), user.getU_id(), cartDto.getMeal_id());
        }
        MyWeb.printJson(resp,R.OK());
    }

  1. 依旧是先从Session中获取我们的用户信息,若没有,那就让返回响应告诉前端提示用户先登录用户先登录。
  2. 如果有登录的用户那就获取响应中的数据,存在ShoppingCartDto对象中。
  3. 编写sql语句,当数量不足一个,也就是用户将当前商品数量调整为零,那么就去除购物车中的商品,数据去执行删除操作。
  4. 其余情况就更新数据库数据为用户调整的数据,使用if…else…语句判断执行sql语句。
  5. 最后返回成功状态的响应
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个比较复杂的问题,需要分几个步骤来完成。首先,你需要从MySQL数据库中提取商品的价格和数量信息。可以使用如下的MySQL语句: ```sql SELECT price, quantity FROM products WHERE id = 1; ``` 上面的语句中,products 表是存储商品信息的表,id=1 表示需要提取的商品的编号为 1。假设你已经得到了商品的价格和数量信息,将它们保存到 JavaScript 变量 price 和 quantity 中。 接下来,你需要设置购物车商品数量。可以创建一个 input 元素,让用户输入购买数量。假设你将这个元素的 id 设置为 "quantity-input",那么可以使用如下的 JavaScript 代码获取用户输入的数量: ```javascript var quantityInput = document.getElementById('quantity-input'); var quantity = parseInt(quantityInput.value); ``` 上面的代码中,parseInt() 函数用于将用户输入的字符串转换成整数类型。假设用户输入的数量为 3,那么 quantity 变量的值就为 3。 最后,你可以计算购物车商品的总价。可以使用如下的 JavaScript 代码: ```javascript var totalPrice = price * quantity; ``` 上面的代码中,* 运算符用于计算商品的总价。假设商品的价格为 10 元,数量为 3 个,那么 totalPrice 变量的值就为 30 元。 综上所述,你可以使用如下的 JavaScript 代码来提取商品价格,设置商品数量并计算购物车价格总和: ```javascript // 从MySQL数据库中提取商品价格和数量信息 var price = 10; // 假设商品价格为 10 元 var quantity = 3; // 假设购买数量为 3 个 // 获取用户输入的购买数量 var quantityInput = document.getElementById('quantity-input'); var quantity = parseInt(quantityInput.value); // 计算购物车商品的总价 var totalPrice = price * quantity; console.log(totalPrice); // 输出购物车价格总和 ``` 注意,上面的代码仅供参考,实际情况可能会有所不同,需要根据具体情况进行调整
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值