模仿淘宝卖家的店铺分类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模仿淘宝卖家的店铺分类相关的知识,希望对你有一定的参考价值。
功能要求:
随意添加分类、移动排序(要有上移下移置顶置底)、删除按钮需要保存修改之后才可以生效、需要无子类时候才可以、页面上也是可以立即更改,难点是前端的javascript逻辑。
效果:
用的是bootstrap框架,页面所以有点粗糙。
逻辑上是,删除发送ajax请求验证但不执行删除操作,只有在保存的时候一并入库。
前端代码比较复杂,后台是依靠$_POST[-1][name]的二维数组去执行一并入库,负值的键值则为新增数据,正值且属于该店铺的分类ID会被当成修改。就酱紫。
至于前端如何实现移动啦、新增啦的、还有就是按钮状态啦、
/**店铺分类 begin**/ /** * @method 合并分类 * @author xu 2017/6/26 */ function combineTree(e) { var id = $(e).parents(‘tr‘).attr(‘conbineId‘); var classVal = $(e).attr(‘class‘); if(classVal == ‘icon icon_cdown‘){ $("tr[conbineId=tree_"+id+"]").hide(); $(e).attr(‘class‘,‘icon icon_cright‘); }else{ $("tr[conbineId=tree_"+id+"]").show(); $(e).attr(‘class‘,‘icon icon_cdown‘); } //这里检测全部展开、全部收起 //判定是否全部都是合并 var allIsCombine = true; $(‘i[icontype="combine"]‘).each(function(index,i){ if($(i).attr(‘class‘)==‘icon icon_cdown‘) { allIsCombine = false; } }); if(allIsCombine) { $("input[myAttr=‘changetext‘]").val("全部展开"); } //判定是否全部都是展开 var allIsNoCombine = true; $(‘i[icontype="combine"]‘).each(function(index,i){ if($(i).attr(‘class‘)==‘icon icon_cright‘) { allIsNoCombine = false; } }); if(allIsNoCombine) { $("input[myAttr=‘changetext‘]").val("全部收起"); } } /** * @method 全部展开合并切换 * @author xu 2017/6/26 */ function showHideTog(e) { var thisText = $(e).val(); if(thisText==‘全部展开‘) { $("input[myAttr=‘changetext‘]").val("全部收起"); $("i[iconType=‘combine‘]").each(function(index,i){ if($(i).attr(‘class‘)==‘icon icon_cright‘){ var id = $(i).parents(‘tr‘).attr(‘conbineId‘); $("tr[conbineId=tree_"+id+"]").show(); $(i).attr(‘class‘,‘icon icon_cdown‘); } }); } else { $("input[myAttr=‘changetext‘]").val("全部展开"); $("i[iconType=‘combine‘]").each(function(index,i){ if($(i).attr(‘class‘)==‘icon icon_cdown‘){ var id = $(i).parents(‘tr‘).attr(‘conbineId‘); $("tr[conbineId=tree_"+id+"]").hide(); $(i).attr(‘class‘,‘icon icon_cright‘); } }); } } /** * @method 删除产品分类(逻辑删除) * @author xu 2017/6/26 */ function checkDelShopSort(id) { var thispartr = $("tr[myAttr=‘"+id+"‘]"); //将当前类的下级全部删除 if(thispartr.attr(‘class‘) == ‘level_1‘){ var nextlength = $("tr[myAttr=‘"+id+"‘]").nextAll().length; var hasSon = false; if(nextlength > 0 && thispartr.next().attr(‘class‘) != ‘level_1‘) { hasSon = true; } if(hasSon) { MESSAGE.alert(‘此分类中还有子分类,不可以删除!‘); return false; } } //删除分类需要判定该分类下面有无分类,若有就禁止删除 $.ajax({ url:‘‘, data:{‘id‘:id,‘isAjax‘:1}, dataType:‘json‘, type:‘POST‘, success:function(res){ if(res.data == ‘success‘) { $("tr[myAttr=‘"+id+"‘]").remove(); $(‘#sort_table tfoot‘).html(‘<input name="delsign" type="hidden" value="yes">‘); } else { MESSAGE.confirm(‘您选择的分类里还有配件,删除后在店铺里将无法再访问这些分类,且配件会被移出这些分类。确定删除?‘,‘confirmDelSort(‘+id+‘)‘); } } }); } /** * @method 确定删除含有商品的分类 * @author xu 2017/6/26 */ function confirmDelSort(id) { $("tr[myAttr=‘"+id+"‘]").remove(); $(‘#sort_table tfoot‘).html(‘<input name="delsign" type="hidden" value="yes">‘); } /** * @method 取消添加子类 * @author xu 2017/6/26 */ function cancelAddChild(e) { $(e).parents(‘tr‘).remove(); SORTSHOP.moveIcon(); } /** * @method 添加顶级分类 * @author xu 2017/6/26 */ function addTopChild(e) { new_count = new_count - 1; var tr = ‘<tr conbineid="‘+new_count+‘" myattr="‘+new_count+‘" class="level_1">‘ +‘<td><i onclick="combineTree(this)" iconType="combine" class="icon icon_cright"></i>‘ +‘<input type="text" submitcheck="checkval" class="form-control" name="data[‘+new_count+‘][name]" placeholder="请输入分类名称"/>‘ +‘ <i onclick="addChild(this,‘+new_count+‘,0)" class="icon2 icon2_add"></i>‘ +‘<input type="hidden" class="seq" value="" name="data[‘+new_count+‘][seq]"/>‘ +‘<input type="hidden" value="0" name="data[‘+new_count+‘][path]"/>‘ +‘<input type="hidden" value="0" name="data[‘+new_count+‘][pid]"/></td>‘ +‘<td><i class="icon icon_top"></i><i class="icon icon_up"></i><i class="icon icon_down"></i><i class="icon icon_foot"></i></td>‘ +‘<td style="padding-left:42px;"><a onclick="cancelAddChild(this)" href="javascript:;" class="a_blue">删除</a></tr>‘;; $(‘tbody‘).append(tr); SORTSHOP.moveIcon(); } /** * @method 提交检测 * @author xu 2017/6/26 */ function submitCheck() { //对表单进行必要的一些检测操作 var cancelSubmit = false; $(‘tbody input[submitcheck="checkval"]‘).each(function(index,i){ if($(this).val()=="") { $(this).focus(); cancelSubmit = true; return false; } }); if(cancelSubmit) { return false; } //对所有tr进行重新排序 $(".seq").each(function(index,i) { $(i).val(index+1); }); $("#sortForm").submit(); } var new_count = 0;//全局变量 /** * @method 添加子类 * @author xu 2017/6/26 */ function addChild(e,pid,path) { var iconClass = $(e).parents(‘tr‘).find("i[iconType=‘combine‘]").attr(‘class‘); if(iconClass == ‘icon icon_cright‘) { var conbineId = $(e).parents(‘tr‘).attr(‘conbineId‘); $("tr[conbineId=tree_"+conbineId+"]").show(); $(e).parents(‘tr‘).find("i[iconType=‘combine‘]").attr(‘class‘,‘icon icon_cdown‘); } new_count = new_count - 1; path = "‘"+path+"‘"; var tr = ‘<tr conbineId="tree_‘+pid+‘" myattr="‘+new_count+‘" class="level_2">‘ +‘<td style="padding-left:25px;">‘ +‘└-- <input type="text" class="form-control" submitcheck="checkval" name="data[‘+new_count+‘][name]" placeholder="请输入分类名称"/>‘ +‘<input type="hidden" class="seq" value="" name="data[‘+new_count+‘][seq]"/>‘ +‘<input type="hidden" value="‘+path+‘" name="data[‘+new_count+‘][path]"/>‘ +‘<input type="hidden" value="‘+pid+‘" name="data[‘+new_count+‘][pid]"/></td>‘ +‘<td><i class="icon icon_top"></i><i class="icon icon_up"></i><i class="icon icon_down"></i>‘ +‘<i class="icon icon_foot"></i></td><td style="padding-left:42px;">‘ +‘<a class="a_blue" onclick="cancelAddChild(this)" href="javascript:;">删除</a></td></tr>‘; var length = $(e).parents(‘tr‘).nextAll().length; if(length==0){$(e).parents(‘tr‘).after(tr);} $(e).parents(‘tr‘).nextAll().each(function(index,i){ var _class_name = $(this).attr(‘class‘); if(_class_name == ‘level_1‘) { $(this).prev().after(tr); return false; } if(index == length-1) { $(this).after(tr); return false; } }); SORTSHOP.moveIcon(); } /** * @method 店铺分类 * @author soul 2017/6/21 */ var SORTSHOP = { //图标按钮状态 moveIcon: function(){ $(‘.icon_hover‘).removeClass(‘icon_hover‘); $(‘#sort_table tbody tr‘).each(function(i, e){ $(e).find(‘.icon_disabled‘).removeClass(‘icon_disabled‘); var now_level = parseInt($(this).attr(‘class‘).match(/level_\\d+/i)[0].replace(‘level_‘, ‘‘)); if(now_level == 1) { //上面没有level_1的就要去除上移 if($(e).prevAll(‘.level_1‘).length < 1) { $(e).find(‘.icon_top, .icon_up‘).addClass(‘icon_disabled‘); } //对于level_1下面的level1未0的时候就是没有下移置底功能 if($(e).nextAll(‘.level_1‘).length < 1) { $(e).find(‘.icon_foot, .icon_down‘).addClass(‘icon_disabled‘); } }else if(now_level > 1){ var has = false; $(e).prevAll().each(function(i2, e2){ //碰到父节点退出循环 if($(e2).hasClass(‘level_‘+(now_level-1))) { return false; } has = true; return false; }); if(!has) { $(e).find(‘.icon_top, .icon_up‘).addClass(‘icon_disabled‘); } var has = false; $(e).nextAll().each(function(i2, e2){ //碰到父节点退出循环 if($(e2).hasClass(‘level_‘+(now_level-1))) { return false; } has = true; return false; }); if(!has) { $(e).find(‘.icon_foot, .icon_down‘).addClass(‘icon_disabled‘); } } }); $(‘#sort_table tbody tr .icon:not(.icon_disabled)‘).mouseover(function(){ $(this).addClass(‘icon_hover‘); }).mouseout(function(){ $(this).removeClass(‘icon_hover‘); }); //为了避免重复执行点击的回调函数,这里进行解绑 $(".icon").unbind(); //在这里给每一个icon重新绑定事件 //上移按钮添加click事件 $(‘.icon_up:not(.icon_disabled)‘).bind(‘click‘,clickSortUp); //下移按钮添加click事件 $(‘.icon_down:not(.icon_disabled)‘).bind(‘click‘,clickSortDown); //置顶按钮添加click事件 $(‘.icon_top:not(.icon_disabled)‘).bind(‘click‘,clickSortTop); //置底按钮添加click事件 $(‘.icon_foot:not(.icon_disabled)‘).bind(‘click‘,clickSortFoot); } }; /** * @method 点击类别上移 * @author xu 2017/6/26 */ function clickSortUp(){ var level = parseInt($(this).parents(‘tr‘).attr(‘class‘).match(/level_\\d+/i)[0].replace(‘level_‘, ‘‘)); if(level==2) { //此时往上移动 var upTr = $(this).parents(‘tr‘).prev(); $(this).parents(‘tr‘).insertBefore(upTr); } if(level==1){ var sonTr = $(this).parents(‘tr‘).nextUntil(‘.level_1‘); var parentTr = $(this).parents(‘tr‘); // html = html+htmls; //现在获取上一个节点的起点 $(this).parents(‘tr‘).prevAll().each(function(index,i){ var _class_name = $(this).attr(‘class‘); if(_class_name ==‘level_1‘) { parentTr.insertBefore($(i)); sonTr.insertBefore($(i)); return false; } }); } SORTSHOP.moveIcon(); } /** * @method 点击类别下移 * @author xu 2017/6/26 */ function clickSortDown() { var level = parseInt($(this).parents(‘tr‘).attr(‘class‘).match(/level_\\d+/i)[0].replace(‘level_‘, ‘‘)); //此时往下移动 if(level==2) { var downTr = $(this).parents(‘tr‘).next(); $(this).parents(‘tr‘).insertAfter(downTr); } if(level==1) { //获取当前节点和其子节点html var sonTr = $(this).parents(‘tr‘).nextUntil(‘.level_1‘); var parentTr = $(this).parents(‘tr‘); //现在获取下一个节点的终点 var hasfir = false; var length = $(this).parents(‘tr‘).nextAll().length; $(this).parents(‘tr‘).nextAll().each(function(index,i){ var _class_name = $(this).attr(‘class‘); if(hasfir) { if(_class_name ==‘level_1‘) { parentTr.insertBefore($(i)); sonTr.insertBefore($(i)); return false; } if(index == length-1) { sonTr.insertAfter($(i)); parentTr.insertAfter($(i)); return false; } } if(index == length-1) { sonTr.insertAfter($(i)); parentTr.insertAfter($(i)); return false; } if(_class_name == ‘level_1‘) { hasfir = true; } }); } SORTSHOP.moveIcon(); } /** * @method 点击类别置顶 * @author xu 2017/6/26 */ function clickSortTop() { var level = parseInt($(this).parents(‘tr‘).attr(‘class‘).match(/level_\\d+/i)[0].replace(‘level_‘, ‘‘)); //此时往上置顶 if(level==2) { var topTr = ""; //此时移动的是第二个级别的置顶 $(this).parents(‘tr‘).prevAll().each(function(index,i){ if($(i).attr(‘class‘)==‘level_1‘) { topTr = $(i); return false; } }); $(this).parents(‘tr‘).insertAfter(topTr); } //现在是一级的置顶操作 if(level==1) { //获取当前节点和其子节点html var sonTr = $(this).parents(‘tr‘).nextUntil(‘.level_1‘); var parentTr = $(this).parents(‘tr‘); //现在直接将html插入进去最顶级 var firstTr = $("tr[class=‘level_1‘]").eq(0); parentTr.insertBefore(firstTr); sonTr.insertBefore(firstTr); } SORTSHOP.moveIcon(); } /** * @method 点击类别置底 * @author xu 2017/6/26 */ function clickSortFoot() { var level = parseInt($(this).parents(‘tr‘).attr(‘class‘).match(/level_\\d+/i)[0].replace(‘level_‘, ‘‘)); //此时往上置底 if(level==2){ //当前节点的HTML var footTr =""; var type ="" //此时移动的是第二个级别的置底 var length = $(this).parents(‘tr‘).nextAll().length; $(this).parents(‘tr‘).nextAll().each(function(index,i){ //往下循环,遇到level_1就插在该节点前面 if($(i).attr(‘class‘)==‘level_1‘) { footTr = $(i); type = ‘2‘; return false; } //如果一直都遇不到level_1那就放在最后节点的后面吧 if(index == length-1) { footTr = $(i); type = ‘1‘; return false; } }); if(type == ‘1‘) { $(this).parents(‘tr‘).insertAfter(footTr); }else{ $(this).parents(‘tr‘).insertBefore(footTr); } } //现在是一级的置底操作 if(level==1){ //获取当前节点和其子节点html var sonTr = $(this).parents(‘tr‘).nextUntil(‘.level_1‘); var parentTr = $(this).parents(‘tr‘); var lastTr = $("#sort_table tbody tr").last(); sonTr.insertAfter(lastTr); parentTr.insertAfter(lastTr); } SORTSHOP.moveIcon(); } /** * @method * @author xu 2017/6/30 */ function checkShopBaseInfo(formid) { var val = $(‘#‘+formid+‘ [name="province[0]"]‘).val(); var error = false; var check_arr = new Array(‘shopName‘,‘province[0]‘,‘shopAddr‘); for(var i in check_arr) { var obj = $(‘#‘+formid+‘ [name="‘+check_arr[i]+‘"]‘); var val = $.trim(obj.val()); switch(check_arr[i]) { case ‘shopName‘: if(val==‘‘){ obj.parent().find(‘span[class="txt_error"]‘).text(‘店铺名称不能为空‘); obj.focus(); error = true; }else{ var data = AJAX.synchronize("post", "/seller/checkShopNameUnique", {"shopName":val}) if(data.status && data.data < 1){ }else{ obj.parent().find(‘span[class="txt_error"]‘).text(‘店铺名称已被使用‘); obj.focus(); error = true; } } break; case ‘province[0]‘: if(val==0){ console.log(111) obj.parent().parent().find("span[class=‘txt_error‘]").text(‘地区不能为空‘); error = true; } break; case ‘shopAddr‘: if(val==‘‘){ obj.parent().find(‘span[class="txt_error"]‘).text(‘经营地址不能为空‘); obj.focus(); error = true; } break; } if(error) break; } if(error) { return false; }else{ return true; } } /**店铺分类 end**/
以上是关于模仿淘宝卖家的店铺分类的主要内容,如果未能解决你的问题,请参考以下文章