• bootStrap树形目录组件


    需求描述

    产品添加页面,需要选择车型。在bootStrap的modal上弹出子modal来使用。
    车型一共有4级目录。要使用目录树。
    然后分活动和商品两种,需要能够通过不通参数来调用该组件。
    车型品牌要使用字母导航。

    技术实现

    数据都是后端传json过来,我们ajax获取然后操作。
    由于车型总数据有几万条以上,不可能一次性请求过来。这里我们使用异步的方式,每点击一次目录节点,加载它的下一级。
    这里我们用两个参数来控制活动和商品的不同加载。_showPrice和opened
    后端传过来的第一级数据是车型品牌,其中有首字母的字段。字母导航的初始化,就是把这个数据用firstWord属性来排序,然后忽略掉其他首字母相同的元素。
    对于活动类型,需要返回所勾选的最低一级的数据。(勾选奥迪和奥迪A6,则只返回A6的意思),这里用了整整4层循环。不过它是根据是否有checked来遍历的,速度不慢。

      1 /**
      2  * Created by nuenfeng on 2016/5/23.
      3  * 车型选择组件
      4  * 参数:
      5  * showPrice 是否要输入价格(不输入价格的从品牌开始就有选项框,没有全选功能)
      6  * params 外部传入的对象
      7  * callback 回调函数
      8  */
      9 (function () {
     10     var uriCarBrand = global.url.carBrandList;
     11     //var uri = uriCarBrand.url;
     12     var opened = false; //当前页面是否打开过本组件
     13     var _callback;      //回调函数
     14     var requestParams;  //请求时要使用的参数
     15     var _showPrice;     //是否要输入价格
     16     var lastShowPrice;  //前一次打开状态
     17     var charNavArr;     //字母导航数组
     18 
     19     function CarTree(showPrice, params, callback) {
     20         // 没打开过,初始化; 打开过,直接显示modal
     21         requestParams = params;
     22         _showPrice = showPrice;
     23         _callback = callback;
     24 
     25         if (!opened || lastShowPrice != showPrice) {
     26             this.init();
     27             opened = true;
     28             lastShowPrice = showPrice;
     29         } else {
     30             $('#zc-sub-modal').modal('show');
     31         }
     32     }
     33 
     34     CarTree.prototype.init = function () {
     35 
     36         msjcTools.addSubModal();
     37         //设置大模态框
     38         $('#zc-sub-modal').addClass("bs-example-modal-lg");
     39         $('#zc-sub-modal .modal-dialog').addClass("modal-lg");
     40 
     41         var str = '<form id="info-form" data-parsley-validate class="form-horizontal form-label-left">';
     42         str += '<ul id="resourceId" class="treeview-gray">'
     43         str += '<li id="cb_0"><span>汽车品牌选择</span>';
     44         str += "</li>"
     45         str += '</ul>'
     46         str += '</form>';
     47 
     48         var objId = 'cb_0';
     49         var carBrandId = 0;
     50         loadSubMenu(objId, carBrandId, 1);  //1 表示第一次加载,用于加载成功后判断时候要初始化字母导航
     51 
     52         $('#zc-sub-modal-body').html(str);
     53         $('#zc-sub-modal').modal({
     54             keyboard: false,
     55             show: true
     56         });
     57 
     58         // 点击保存事件
     59         $('#zc-sub-modal .modal-footer .btn.btn-primary').unbind().bind("click", function () {
     60             save();
     61         });
     62 
     63 
     64         //$("#resourceId").find("input[type=checkbox]").unbind().bind("click",function(){
     65         //    if($(this).is(':checked')==true){//选中 则其上层节点全部展开并选中
     66         //        //上级选中
     67         //        $(this).parents("li").each(function(){
     68         //            $(this).find("input[type=checkbox]:first").attr("checked",true)
     69         //        });
     70         //    } else {
     71         //        //下级取消选中
     72         //        $(this).siblings("ul").find("input[type=checkbox]").each(function(){
     73         //            $(this).removeAttr("checked");
     74         //        });
     75         //    }
     76         //});
     77 
     78 
     79         //隐藏子窗口后 保持父窗口的滚动
     80         $("#zc-sub-modal").on("hidden.bs.modal", function () {
     81             $('body').addClass('modal-open')
     82         });
     83     }
     84 
     85     CarTree.prototype.empty = function () {
     86         opened = false;
     87         console.log('empty me');
     88     }
     89 
     90     //加载子菜单
     91     var loadSubMenu = function (objId, carBrandId, times) {
     92 
     93         requestParams.brandId = carBrandId;
     94         executeAjax(global.url.carBrandList, requestParams, function (data) {
     95             // 给data风骚地排个序
     96             data.sort(keysrt("firstWord"));
     97 
     98             var menuHtml = "<ul>";
     99             for (var index in data) {
    100                 var menu = data[index];
    101                 menuHtml += '<li id="cb_' + menu.carBrandId + '" value="' + menu.carBrandId + '" brand="' + menu.brand + '">';
    102 
    103                 // 带价格的树
    104                 if (_showPrice) {
    105                     // 最后一级,添加选项框
    106                     if (menu.level > 3) {
    107                         menuHtml += '<input type="checkbox" name="resourceIds" value="' + menu.carBrandId + '" />';
    108                     }
    109                     menuHtml += '<span>' + menu.name + '</span>';
    110 
    111                     // 最后一级,添加输入框
    112                     if (menu.level == 4) {
    113                         menuHtml += '<input type="text" maxlength="9">';
    114                     }
    115                 } else { // 不带价格的树
    116                     menuHtml += '<input type="checkbox" name="resourceIds" value="' + menu.carBrandId + '" />';
    117                     menuHtml += '<span>' + menu.name + '</span>';
    118                 }
    119 
    120                 menuHtml += "</li>";
    121             }
    122             menuHtml += "</ul>";
    123             $('#' + objId).append(menuHtml);
    124             $('#' + objId).attr('data-load', 'loaded');
    125 
    126             //汽车类型第一级加载完成后,初始化字符导航
    127             charNavArr = [];
    128             var fwdLast = '';    //上一次的首字母
    129 
    130             for (var i in data) {
    131                 var cobjTemp = {};
    132                 if (fwdLast != data[i].firstWord) {
    133                     fwdLast = data[i].firstWord;
    134                     cobjTemp.firstWord = fwdLast;
    135                     cobjTemp.targetId = 'cb_'+data[i].carBrandId;
    136                     charNavArr.push(cobjTemp);
    137                 }
    138             }
    139             if (times == 1) {
    140                 initCharNav();
    141                 // 点击保存事件
    142                 $('.charNavSaveBtn').unbind().bind("click", function () {
    143                     save();
    144                 });
    145             }
    146         });
    147 
    148     }
    149 
    150     // 此处是风骚的数组对象排序
    151     var keysrt = function (propertyName) {
    152         return function (object1, object2) {
    153             var value1 = object1[propertyName];
    154             var value2 = object2[propertyName];
    155             if (value2 < value1) {
    156                 return 1;
    157             }
    158             else if (value2 > value1) {
    159                 return -1;
    160             }
    161             else {
    162                 return 0;
    163             }
    164         }
    165     }
    166 
    167     // 保存事件
    168     var save = function(){
    169         // 确认后,执行回调函数
    170         if (_showPrice) {
    171             var res = getPriceResult();
    172             if (res.status) {
    173                 _callback(res.data);
    174             } else {
    175                 alert(res.error);
    176                 return;
    177             }
    178         } else {
    179             _callback(getNopriceResult());
    180         }
    181         //返回数据,然后隐藏
    182         $('#zc-sub-modal').modal('hide');
    183     }
    184 
    185     // 设置字符导航初始化
    186     var initCharNav = function () {
    187         var charNavHtml = '<ul id="charNavBar" class="charNavBar pagination">';
    188         for (var i in charNavArr) {
    189             charNavHtml += '<li><a href="#'+charNavArr[i].targetId+'">'+charNavArr[i].firstWord+'</a></li>';
    190         }
    191         charNavHtml += '<li><a class="modalGoTop">↑</a></li>';
    192         charNavHtml += '<button type="button" class="btn btn-primary charNavSaveBtn">保存</button>';
    193         charNavHtml += '</ul>';
    194 
    195         $('#zc-sub-modal').append(charNavHtml);
    196 
    197         $('.modalGoTop').on('click', function(e){
    198             $('#zc-sub-modal').animate({scrollTop: 0}, 500);
    199         });
    200     }
    201 
    202     // 统计带价格的返回数据
    203     var getPriceResult = function () {
    204         var result = {
    205             status : true,
    206             data : [],
    207             error : ''
    208         };
    209         var liTemp;
    210         var objTemp;
    211         $('.treeview-gray input:checkbox:checked').each(function (i) {
    212             liTemp = $(this).parent('li');
    213             objTemp = {};
    214             objTemp.carBrandId = liTemp.attr('value');
    215             objTemp.brand = liTemp.attr('brand');
    216             objTemp.carBrandName = liTemp.find('span').text();
    217             objTemp.unitPrice = liTemp.find('input:text').val();
    218 
    219             // 如果价格没有输入,返回保存失败,并返回没有输入的carBrandName
    220             if(objTemp.unitPrice == '') {
    221                 result.status = false;
    222                 result.error = '请输入 ' + objTemp.carBrandName + ' 的价格!';
    223                 return result;
    224             }
    225             result.data.push(objTemp);
    226         });
    227         return result;
    228     }
    229 
    230     // 统计不带价格的返回数据
    231     var getNopriceResult = function () {
    232         var result = [];
    233         var liTemp;
    234         var objTemp;
    235         var flag1;
    236         var flag2;
    237         var flag3;
    238         var flag4;
    239         var level2Name;
    240 
    241         // 遍历4层
    242         $('#cb_0').children().children('li').children('input:checkbox').each(function (i1) {
    243             if ($(this).is(':checked')) {
    244                 flag1 = true;
    245             } else {
    246                 flag1 = false;
    247             }
    248             $(this).parent().children().children('li').children('input:checkbox').each(function (i2) {
    249                 if ($(this).is(':checked')) {
    250                     flag1 = false;
    251                     flag2 = true;
    252                 } else {
    253                     flag2 = false;
    254                 }
    255                 // 获取第二级的名字,给第三级使用
    256                 liTemp = $(this).parent('li');
    257                 level2Name = liTemp.children('span').text();
    258                 $(this).parent().children().children('li').children('input:checkbox').each(function (i3) {
    259                     if ($(this).is(':checked')) {
    260                         flag1 = false;
    261                         flag2 = false;
    262                         flag3 = true;
    263                     } else {
    264                         flag3 = false;
    265                     }
    266                     $(this).parent().children().children('li').children('input:checkbox').each(function (i4) {
    267                         if ($(this).is(':checked')) {
    268                             flag1 = false;
    269                             flag2 = false;
    270                             flag3 = false;
    271                             flag4 = true;
    272                         } else {
    273                             flag4 = false;
    274                         }
    275                         if (flag4) {
    276                             liTemp = $(this).parent('li');
    277                             objTemp = {};
    278                             objTemp.carBrandId = liTemp.attr('value');
    279                             objTemp.brand = liTemp.attr('brand');
    280                             //objTemp.carBrandName = liTemp.children('span').text();
    281                             objTemp.carBrandName = objTemp.brand + ' ' + liTemp.children('span').text();
    282                             result.push(objTemp);
    283                         }
    284                     });
    285                     if (flag3) {
    286                         liTemp = $(this).parent('li');
    287                         objTemp = {};
    288                         objTemp.carBrandId = liTemp.attr('value');
    289                         objTemp.brand = liTemp.attr('brand');
    290                         //objTemp.carBrandName = liTemp.children('span').text();
    291                         objTemp.carBrandName = objTemp.brand + ' ' + level2Name + ' ' + liTemp.children('span').text();
    292                         result.push(objTemp);
    293                     }
    294                 });
    295                 if (flag2) {
    296                     //liTemp = $(this).parent('li');
    297                     objTemp = {};
    298                     objTemp.carBrandId = liTemp.attr('value');
    299                     objTemp.brand = liTemp.attr('brand');
    300                     //objTemp.carBrandName = objTemp.brand + liTemp.children('span').text();
    301                     objTemp.carBrandName = objTemp.brand + ' ' + liTemp.children('span').text();
    302                     result.push(objTemp);
    303                 }
    304             });
    305             if (flag1) {
    306                 liTemp = $(this).parent('li');
    307                 objTemp = {};
    308                 objTemp.carBrandId = liTemp.attr('value');
    309                 objTemp.brand = liTemp.attr('brand');
    310                 objTemp.carBrandName = liTemp.children('span').text();
    311                 result.push(objTemp);
    312             }
    313         });
    314 
    315         return result;
    316     }
    317 
    318 
    319     // 给目录树绑定点击事件
    320     $(document).on('click', '#resourceId li', function (e) {
    321 
    322 
    323         e.stopPropagation();
    324 
    325         if ($(this).attr('open')) {
    326             $(this).removeAttr('open');
    327             $(this).children('ul').hide();
    328         } else {
    329             $(this).attr('open', 'opened');
    330             $(this).children('ul').show();
    331         }
    332         var objId = $(this).attr('id');
    333         var carBrandId = $(this).attr('value');
    334         //加载过的不执行
    335         if ($(this).attr('data-load')) {
    336             return;
    337         }
    338         loadSubMenu(objId, carBrandId);
    339     });
    340 
    341     // 点击多选框时候不下拉
    342     $(document).on('click', 'input[type="checkbox"]', function (e) {
    343         e.stopPropagation();
    344     });
    345 
    346     window.CarTree = CarTree;
    347 }());

    调用方法:

    carTree = new CarTree(false, {}, function (data) {
        console.log(data);
     });
  • 相关阅读:
    爱情戒指
    李小龙
    20分钟
    大话JAVA(二)
    编程高手
    Free Computer Books, Free eBooks and Read Free Books Online
    (06) [修正版] 判断整数序列是不是二元查找树的后序遍历结果
    [原创]DateTime在使用 format Custom Date and Time Format Strings时遇到的问题和解决方法
    [原创]00:矩形算法题二分法的扩展(2分法 * 2分法)
    用堆栈和用递归分别实现倒序打印
  • 原文地址:https://www.cnblogs.com/woodk/p/5536323.html
Copyright © 2020-2023  润新知