1.商品的全选和全不选
- 获取页面中全选框所在的input,绑定其变change事件
- 获取全选框的状态
- 遍历获取商品对应的CheckBox,设置其选中状态和全选的保持一致
- 同时,当全选框状态发生变化时,结算中商品的总价格和总数目相应的需要改变。就需要计算页面中被选中的商品的总价格和总数目。
- 计算总价格和总数目,需要获取选中的商品的数目和小计,进行类加计算商品的总数目和总价格就,这里可以单独定义一个函数,以便后面复用
- 最后,需要设置被选中的商品的总数目和价格
先贴上计算总件数和总价格的代码(说明:页面中出现的中括号,那个是django的模板注释,不过不影响前端代码。)
<script>
// 计算被选中的商品的总件数和总价格
function update_page_info() {
// 获取所有被选中的商品的checkbox
// 获取所有被选中的商品所在的ul元素,从而获取被选中的商品的数量和价格,计算小计
total_count = 0;
total_price = 0;
$('.cart_list_td').find(':checked').parents('ul').each(function () {
// 获取商品数目和小计
count = $(this).find('.num_show').val();
// 商品价格
amount = $(this).children('.col07').text();
// 累加计算商品总数目和价格
count = parseInt(count);
{# alert(count)#}
amount = parseFloat(amount);
{# alert(amount)#}
total_count += count;
total_price += amount;
});
// 设置被选中的商品总数目和价格
$('.settlements').find('em').text(total_price.toFixed(2));
$('.settlements').find('b').text(total_count)
}
</script>
2.商品的全选和全不选代码
<script>
// 商品的全选和全不选,绑定全选的变化
$('.settlements').find(':checkbox').change(function () {
// 获取全选框的状态
is_checked = $(this).prop('checked');
// 遍历商品对应的checkbox,设置的选中状态和全选的保持一致
$('.cart_list_td').find(':checkbox').each(function () {
$(this).prop('checked', is_checked)
});
// 更新页面信息
update_page_info()
});
<script/>
3.商品对应的checkbox状态发生改变
- 当商品对应的checkbox状态发生改变时候,需要设置全选checkbox的状态
- 获取页面上所有被选中的商品的数目,并获取所有商品数目,判断他们的数目,如果前者小于后者,则设置全选框为未选中
<script>
// 商品对应的checkbox状态发生改变时候,设置全选checkbox的状态
$('.cart_list_td').find(':checkbox').change(function () {
// 获取页面上所有的商品数目
all_len = $('.cart_list_td').length;
{# alert(all_len)#}
// 获取页面上所有被选中的商品的数目
checked_len = $('.cart_list_td').find(':checked').length;
{# alert(checked_len)#}
is_checked = true;
// 判断如果页面上的所有被选中的商品数目小于页面上所有的商品数目,设置全选框架状态
if (checked_len < all_len){
$('.settlements').find(':checkbox').prop('checked', false);
}
else {
$('.settlements').find(':checkbox').prop('checked', true);
}
// 更新页面信息
update_page_info()
});
<script/>
4. 用户点击,购物车中商品数目变化
- 购物车中商品数量的增加,减少,以及用户手动输入套路基本一致,这里总结下当用户点击商品数量增加时的情况,同时说明收两者的变化,同时涉及与后端交互的情况,也会一同提到。
- 用户点击修改购物车中商品,(后端数据库需要相应发生变化,后端需要前端传递的参数包括商品sku id以及商品数量),用户点击增加,绑定标签click事件,获取商品数量(增加或减少1,减少的话需要判断当数量减少为0时候的情况。如果是用户手动输入,则同样需要对用户输入进行校验,如果不合法,可以设置为之前输入的值),获取商品id,使用ajax发向后端发起post请求,携带后端需要的参数。
- 根据回调结果,进行相应判断,如果添加成功,需要重新设置商品数目,并重新计算商品小计(计算商品小计可以单独定义一个函数),判断该商品是否被选中,如果选中,更新页面信息(结算中的商品数目和价格需要跟随变化)
- 发起ajax请求需要注意的是,需要发起同步请求(ajax默认为异步,我们后面的判断依赖于回调的执行结果)
<script>
// 计算商品小计
function update_goods_amount(sku_ul) {
// 需要获取商品数目和价格
// count = $(sku_ul).find('.num_show').val();
// price = $(sku_ul).children('.col05');
count = sku_ul.find('.num_show').val();
price = sku_ul.children('.col05').text();
// 计算商品小计
count = parseInt(count);
price = parseFloat(price);
amount = count * price;
// 设置商品的小计
sku_ul.children('.col07').text(amount.toFixed(2) + '元');
}
// 购物车增加减少逻辑基本相同,抽出共同部分为一个函数
error_update = false;
total = 0;
function update_remote_cart_info(sku_id, count) {
csrf = $('input[name="csrfmiddlewaretoken"]').val();
params = {'sku_id': sku_id, 'csrfmiddlewaretoken': csrf, 'count': count};
// 设置ajax请求为同步()
$.ajaxSettings.async = false;
// post请求 发起ajax请求, /cart/update,参数:sku_id, 商品数目
$.post('/cart/update', params, function (data) {
if (data.res == 4){
// 成功
error_update = false;
total = data.count;
}
else{
// 失败
error_update = true;
alert(data.errmsg)
}
});
// 设置ajax请求为异步
$.ajaxSettings.async = true;
}
// 购物车中商品数量增加,绑定+ 所在a标签点击事件(涉及与后台交互)
$('.add').click(function () {
// 获取商品数量,id,
count = $(this).next().val();
// 给标签增加id属性,在获取
sku_id = $(this).next().attr('sku_id');
count = parseInt(count) + 1;
// 发ajax请求
update_remote_cart_info(sku_id, count);
// 判断是否添加成功
if (error_update == false){
// 重新设置商品数目,点击完了加一之后的值
$(this).next().val(count);
// 计算商品小计
amount = update_goods_amount($(this).parents('ul'));
// 设置商品小计
{# $(this).parents('ul').children('col07').text(amount);#}
// 获取商品对应的checkbox的状态,如果选中,则更新页面信息
is_checked = $(this).parents('ul').find(':checkbox').prop('checked');
if (is_checked){
// 更新页面信息
update_page_info();
}
// 不管是否选中,都更新页面中购物车商品总数目
// $('.total_count').children('em').text(data.count);(已经在post请求外面了,拿不到data,应该在上面定义)
$('.total_count').children('em').text(total);
}
});
// 购物车记录减少
$('.minus').click(function () {
// 获取商品数量,id,
count = $(this).prev().val();
// 给标签增加id属性,在获取
sku_id = $(this).prev().attr('sku_id');
count = parseInt(count) - 1;
// 判断
if (count <= 0){
return
}
// 发请求
update_remote_cart_info(sku_id, count);
// 判断是否减少成功
if (error_update == false){
// 重新设置商品数目,点击完了减一之后的值
$(this).prev().val(count);
// 计算商品小计
amount = update_goods_amount($(this).parents('ul'));
// 设置商品小计
{# $(this).parents('ul').children('col07').text(amount);#}
// 获取商品对应的checkbox的状态,如果选中,则更新页面信息
is_checked = $(this).parents('ul').find(':checkbox').prop('checked');
if (is_checked){
// 更新页面信息
update_page_info();
}
// 不管是否选中,都更新页面中购物车商品总数目
// $('.total_count').children('em').text(data.count);(data已经在post请求外面了,拿不到data,应该在上面定义)
$('.total_count').children('em').text(total);
}
});
// 获取用户鼠标进入时候的商品数量
pre_count = 0;
$('.num_show').focus(function () {
pre_count = $(this).val();
});
// 手动输入购物车商品数量,绑定失去焦点事件
$('.num_show').blur(function () {
// 获取商品数量,id,
count = $(this).val();
// 给标签增加id属性,在获取
sku_id = $(this).attr('sku_id');
// 校验数据
if (isNaN(count) || count.trim().length == 0 || parseInt(count) <= 0){
// 不满足条件,数据非法,重置商品数目为之前的值()
$(this).val(pre_count);
return;
}
// 发请求
update_remote_cart_info(sku_id, count);
// 判断是否更新成功
if (error_update == false){
// 重新设置商品数目,点击完了减一之后的值
$(this).val(count);
// 计算商品小计
amount = update_goods_amount($(this).parents('ul'));
// 设置商品小计
$(this).parents('ul').children('col07').text(amount);
// 获取商品对应的checkbox的状态,如果选中,则更新页面信息
is_checked = $(this).parents('ul').find(':checkbox').prop('checked');
if (is_checked){
// 更新页面信息
update_page_info();
}
// 不管是否选中,都更新页面中购物车商品总数目
// $('.total_count').children('em').text(data.count);(data已经在post请求外面了,拿不到data,应该在上面定义)
$('.total_count').children('em').text(total);
}
else {
// 如果失败设置为之前的值
$(this).val(pre_count);
}
});
<script/>