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);
 });
时间: 2024-10-21 08:36:52

bootStrap树形目录组件的相关文章

bootstrap轮播组件,大屏幕图片居中效果

在慕课网学习bootstrap轮播组件的时候,了解到轮播的图片都放在了类名为item下的img中 视频中老师对图片自适应采用给图片img设置width=100%完成,然而这样自适应处理图片在不同屏幕中效果不同,大屏效果非常糟糕.比如 这样一张图片, 为了图片自适应设置width=100%,在宽1920px下显示效果是这样的 显然,因为图片设置了100%的宽度,其大部分内容被截去,显示非常糟糕. 后来想了想.有没有办法可以让图片真正的自适应呢并且居中呢,于是想到了css3背景图片属性backgro

Vim升华之树形目录插件NERDTree安装图解

Vim升华之树形目录插件NERDTree安装图解 无意中看到实验室的朋友使用的vim竟然能在左边显示树形目录,感觉很方便,这样子文件夹有什么文件一目了然.她说是一个插件叫NERDTree,安装执行后的效果如下,不是你想要的效果就别安了.我的系统是Ubuntu12.04,版本不同可能 .vim 所在的目录不同.本节用到的压缩包已经上传到网站,如有需要,请自行下载. 免费下载地址在 http://linux.linuxidc.com/ 用户名与密码都是www.linuxidc.com 具体下载目录在

第二百二十八节,jQuery EasyUI,TreeGrid(树形表格)组件

jQuery EasyUI,TreeGrid(树形表格)组件 学习要点: 1.加载方式 2.属性列表 3.事件列表 4.方法列表 本节课重点了解 EasyUI 中 TreeGrid(树形表格)组件的使用方法,这个组件依赖于 DataGrid(数据表格)组件. 一.加载方式 建立一个 JSON 文件 [ { "id": 1, "name": "系统管理", "date": "2015-05-10", &quo

JQuery树形目录制作

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <meta http-equiv="Content-

vim 树形目录插件NERDTree安装及简单用法

转自: http://blog.csdn.net/love__coder/article/details/6659103 1.安装NERDTree插件 先下载,官网:http://www.vim.org/scripts/script.php?script_id=1658 解压缩之后,把 plugin/NERD_tree.vim 和doc/NERD_tree.txt分别拷贝到~/.vim/plugin 和 ~/.vim/doc 目录. 2.使用 1.在linux命令行界面,输入vim 2.输入  

bootstrap 之 列表组件使用

列表是几乎所有网站都会用到的一个组件,正好bootstrap也给我们提供了这个组件的样式,下面我给大家简单介绍一下bootstrap中的列表组件的用法! 首先,重提一下引用bootstrap的核心文件的问题,以免有些刚入手的朋友忘了这个. 在页面的开头,先引用bootstrap的核心文件(css,js)等. <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel='stylesheet' href='css/bootstrap.min.css' /> &l

vim树形目录

NERD tree树形目录插件 • 插件简介 NERD tree是一款vim树形文件资源管理器插件.NERD tree可以让你在vim中浏览你的文件系统,打开想要的文件或目录. • 插件安装 ? 下载NERD tree,下载地址:http://www.vim.org/scripts/script.php?script_id=1658: ?  存放路径,在Windows系统下路径为:vim安装路径\vimXX\,在Linux系统下安装路径为:/usr/share/vim/vimXX/: ?  将下

简单的树形目录展示

<!DOCTYPE html><head> <meta charset="utf-8"/><title>树形菜单</title><style type="text/css" media="all">a,a:visited { color:#333; text-decoration:none; }a:hover { color:#f60; }body,td { font:13p

vim插件:显示树形目录插件NERDTree安装 和 使用

下载和配置 NERDTree插件的官方地址如下,可以从这里获取最新的版本 https://github.com/scrooloose/nerdtree 下载zip安装包 或者使用下面官网源文件安装方法 我的实验环境是centos6.6,其他版本可能有些不同. 安装方法很简单,先把压缩文件下载下来,解压后将plugin目录下的NERD_tree.vim拷贝~/.vim/plugin以及doc目录下的NERD_tree.txt拷贝到~/.vim/doc. ~表示当前用户的目录,我的环境中没有~/.v