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

技术实现
数据都是后端传json过来,我们ajax获取然后操作。
由于车型总数据有几万条以上,不可能一次性请求过来。这里我们使用异步的方式,每点击一次目录节点,加载它的下一级。
这里我们用两个参数来控制活动和商品的不同加载。_showPrice和opened
后端传过来的第一级数据是车型品牌,其中有首字母的字段。字母导航的初始化,就是把这个数据用firstWord属性来排序,然后忽略掉其他首字母相同的元素。
对于活动类型,需要返回所勾选的最低一级的数据。(勾选奥迪和奥迪A6,则只返回A6的意思),这里用了整整4层循环。不过它是根据是否有checked来遍历的,速度不慢。
/**
* Created by nuenfeng on 2016/5/23.
* 车型选择组件
* 参数:
* showPrice 是否要输入价格(不输入价格的从品牌开始就有选项框,没有全选功能)
* params 外部传入的对象
* callback 回调函数
*/
(function () {
var uriCarBrand = global.url.carBrandList;
//var uri = uriCarBrand.url;
var opened = false; //当前页面是否打开过本组件
var _callback; //回调函数
var requestParams; //请求时要使用的参数
var _showPrice; //是否要输入价格
var lastShowPrice; //前一次打开状态
var charNavArr; //字母导航数组 function CarTree(showPrice, params, callback) {
// 没打开过,初始化; 打开过,直接显示modal
requestParams = params;
_showPrice = showPrice;
_callback = callback; if (!opened || lastShowPrice != showPrice) {
this.init();
opened = true;
lastShowPrice = showPrice;
} else {
$('#zc-sub-modal').modal('show');
}
} CarTree.prototype.init = function () { msjcTools.addSubModal();
//设置大模态框
$('#zc-sub-modal').addClass("bs-example-modal-lg");
$('#zc-sub-modal .modal-dialog').addClass("modal-lg"); var str = '<form id="info-form" data-parsley-validate class="form-horizontal form-label-left">';
str += '<ul id="resourceId" class="treeview-gray">'
str += '<li id="cb_0"><span>汽车品牌选择</span>';
str += "</li>"
str += '</ul>'
str += '</form>'; var objId = 'cb_0';
var carBrandId = 0;
loadSubMenu(objId, carBrandId, 1); //1 表示第一次加载,用于加载成功后判断时候要初始化字母导航 $('#zc-sub-modal-body').html(str);
$('#zc-sub-modal').modal({
keyboard: false,
show: true
}); // 点击保存事件
$('#zc-sub-modal .modal-footer .btn.btn-primary').unbind().bind("click", function () {
save();
}); //$("#resourceId").find("input[type=checkbox]").unbind().bind("click",function(){
// if($(this).is(':checked')==true){//选中 则其上层节点全部展开并选中
// //上级选中
// $(this).parents("li").each(function(){
// $(this).find("input[type=checkbox]:first").attr("checked",true)
// });
// } else {
// //下级取消选中
// $(this).siblings("ul").find("input[type=checkbox]").each(function(){
// $(this).removeAttr("checked");
// });
// }
//}); //隐藏子窗口后 保持父窗口的滚动
$("#zc-sub-modal").on("hidden.bs.modal", function () {
$('body').addClass('modal-open')
});
} CarTree.prototype.empty = function () {
opened = false;
console.log('empty me');
} //加载子菜单
var loadSubMenu = function (objId, carBrandId, times) { requestParams.brandId = carBrandId;
executeAjax(global.url.carBrandList, requestParams, function (data) {
// 给data风骚地排个序
data.sort(keysrt("firstWord")); var menuHtml = "<ul>";
for (var index in data) {
var menu = data[index];
menuHtml += '<li id="cb_' + menu.carBrandId + '" value="' + menu.carBrandId + '" brand="' + menu.brand + '">'; // 带价格的树
if (_showPrice) {
// 最后一级,添加选项框
if (menu.level > 3) {
menuHtml += '<input type="checkbox" name="resourceIds" value="' + menu.carBrandId + '" />';
}
menuHtml += '<span>' + menu.name + '</span>'; // 最后一级,添加输入框
if (menu.level == 4) {
menuHtml += '<input type="text" maxlength="9">';
}
} else { // 不带价格的树
menuHtml += '<input type="checkbox" name="resourceIds" value="' + menu.carBrandId + '" />';
menuHtml += '<span>' + menu.name + '</span>';
} menuHtml += "</li>";
}
menuHtml += "</ul>";
$('#' + objId).append(menuHtml);
$('#' + objId).attr('data-load', 'loaded'); //汽车类型第一级加载完成后,初始化字符导航
charNavArr = [];
var fwdLast = ''; //上一次的首字母 for (var i in data) {
var cobjTemp = {};
if (fwdLast != data[i].firstWord) {
fwdLast = data[i].firstWord;
cobjTemp.firstWord = fwdLast;
cobjTemp.targetId = 'cb_'+data[i].carBrandId;
charNavArr.push(cobjTemp);
}
}
if (times == 1) {
initCharNav();
// 点击保存事件
$('.charNavSaveBtn').unbind().bind("click", function () {
save();
});
}
}); } // 此处是风骚的数组对象排序
var keysrt = function (propertyName) {
return function (object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value2 < value1) {
return 1;
}
else if (value2 > value1) {
return -1;
}
else {
return 0;
}
}
} // 保存事件
var save = function(){
// 确认后,执行回调函数
if (_showPrice) {
var res = getPriceResult();
if (res.status) {
_callback(res.data);
} else {
alert(res.error);
return;
}
} else {
_callback(getNopriceResult());
}
//返回数据,然后隐藏
$('#zc-sub-modal').modal('hide');
} // 设置字符导航初始化
var initCharNav = function () {
var charNavHtml = '<ul id="charNavBar" class="charNavBar pagination">';
for (var i in charNavArr) {
charNavHtml += '<li><a href="#'+charNavArr[i].targetId+'">'+charNavArr[i].firstWord+'</a></li>';
}
charNavHtml += '<li><a class="modalGoTop">↑</a></li>';
charNavHtml += '<button type="button" class="btn btn-primary charNavSaveBtn">保存</button>';
charNavHtml += '</ul>'; $('#zc-sub-modal').append(charNavHtml); $('.modalGoTop').on('click', function(e){
$('#zc-sub-modal').animate({scrollTop: 0}, 500);
});
} // 统计带价格的返回数据
var getPriceResult = function () {
var result = {
status : true,
data : [],
error : ''
};
var liTemp;
var objTemp;
$('.treeview-gray input:checkbox:checked').each(function (i) {
liTemp = $(this).parent('li');
objTemp = {};
objTemp.carBrandId = liTemp.attr('value');
objTemp.brand = liTemp.attr('brand');
objTemp.carBrandName = liTemp.find('span').text();
objTemp.unitPrice = liTemp.find('input:text').val(); // 如果价格没有输入,返回保存失败,并返回没有输入的carBrandName
if(objTemp.unitPrice == '') {
result.status = false;
result.error = '请输入 ' + objTemp.carBrandName + ' 的价格!';
return result;
}
result.data.push(objTemp);
});
return result;
} // 统计不带价格的返回数据
var getNopriceResult = function () {
var result = [];
var liTemp;
var objTemp;
var flag1;
var flag2;
var flag3;
var flag4;
var level2Name; // 遍历4层
$('#cb_0').children().children('li').children('input:checkbox').each(function (i1) {
if ($(this).is(':checked')) {
flag1 = true;
} else {
flag1 = false;
}
$(this).parent().children().children('li').children('input:checkbox').each(function (i2) {
if ($(this).is(':checked')) {
flag1 = false;
flag2 = true;
} else {
flag2 = false;
}
// 获取第二级的名字,给第三级使用
liTemp = $(this).parent('li');
level2Name = liTemp.children('span').text();
$(this).parent().children().children('li').children('input:checkbox').each(function (i3) {
if ($(this).is(':checked')) {
flag1 = false;
flag2 = false;
flag3 = true;
} else {
flag3 = false;
}
$(this).parent().children().children('li').children('input:checkbox').each(function (i4) {
if ($(this).is(':checked')) {
flag1 = false;
flag2 = false;
flag3 = false;
flag4 = true;
} else {
flag4 = false;
}
if (flag4) {
liTemp = $(this).parent('li');
objTemp = {};
objTemp.carBrandId = liTemp.attr('value');
objTemp.brand = liTemp.attr('brand');
//objTemp.carBrandName = liTemp.children('span').text();
objTemp.carBrandName = objTemp.brand + ' ' + liTemp.children('span').text();
result.push(objTemp);
}
});
if (flag3) {
liTemp = $(this).parent('li');
objTemp = {};
objTemp.carBrandId = liTemp.attr('value');
objTemp.brand = liTemp.attr('brand');
//objTemp.carBrandName = liTemp.children('span').text();
objTemp.carBrandName = objTemp.brand + ' ' + level2Name + ' ' + liTemp.children('span').text();
result.push(objTemp);
}
});
if (flag2) {
//liTemp = $(this).parent('li');
objTemp = {};
objTemp.carBrandId = liTemp.attr('value');
objTemp.brand = liTemp.attr('brand');
//objTemp.carBrandName = objTemp.brand + liTemp.children('span').text();
objTemp.carBrandName = objTemp.brand + ' ' + liTemp.children('span').text();
result.push(objTemp);
}
});
if (flag1) {
liTemp = $(this).parent('li');
objTemp = {};
objTemp.carBrandId = liTemp.attr('value');
objTemp.brand = liTemp.attr('brand');
objTemp.carBrandName = liTemp.children('span').text();
result.push(objTemp);
}
}); return result;
} // 给目录树绑定点击事件
$(document).on('click', '#resourceId li', function (e) { e.stopPropagation(); if ($(this).attr('open')) {
$(this).removeAttr('open');
$(this).children('ul').hide();
} else {
$(this).attr('open', 'opened');
$(this).children('ul').show();
}
var objId = $(this).attr('id');
var carBrandId = $(this).attr('value');
//加载过的不执行
if ($(this).attr('data-load')) {
return;
}
loadSubMenu(objId, carBrandId);
}); // 点击多选框时候不下拉
$(document).on('click', 'input[type="checkbox"]', function (e) {
e.stopPropagation();
}); window.CarTree = CarTree;
}());
调用方法:
carTree = new CarTree(false, {}, function (data) {
console.log(data);
});
bootStrap树形目录组件的更多相关文章
- [moka同学收藏]Vim升华之树形目录插件NERDTree安装图解
无意中看到实验室的朋友使用的vim竟然能在左边显示树形目录,感觉很方便,这样子文件夹有什么文件一目了然.她说是一个插件叫NERDTree,安装执行后的效果如下,不是你想要的效果就别安了.我的系统是Ub ...
- Vim升华之树形目录插件NERDTree安装图解
来源:CSDN 作者:mybelief321 无意中看到实验室的朋友使用的vim竟然能在左边显示树形目录,感觉很方便,这样子文件夹有什么文件一目了然.他说是一个插件叫NERDTree,安装执行后的效果 ...
- 利用bootstrap的modal组件自定义alert,confirm和modal对话框
由于浏览器提供的alert和confirm框体验不好,而且浏览器没有提供一个标准的以对话框的形式显示自定义HTML的弹框函数,所以很多项目都会自定义对话框组件.本篇文章介绍自己在项目中基于bootst ...
- vim 树形目录插件NERDTree安装及简单用法
转自: http://blog.csdn.net/love__coder/article/details/6659103 1,安装NERDTree插件 先下载,官网:http://www.vim.or ...
- bootstrap轮播组件,大屏幕图片居中效果
在慕课网学习bootstrap轮播组件的时候,了解到轮播的图片都放在了类名为item下的img中 视频中老师对图片自适应采用给图片img设置width=100%完成,然而这样自适应处理图片在不同屏幕中 ...
- bootstrap 之 列表组件使用
列表是几乎所有网站都会用到的一个组件,正好bootstrap也给我们提供了这个组件的样式,下面我给大家简单介绍一下bootstrap中的列表组件的用法! 首先,重提一下引用bootstrap的核心文件 ...
- vim插件:显示树形目录插件NERDTree安装 和 使用
下载和配置 NERDTree插件的官方地址如下,可以从这里获取最新的版本 https://github.com/scrooloose/nerdtree 下载zip安装包 或者使用下面官网源文件安装方法 ...
- JQuery树形目录插件Dynatree
最近做网页需要做一个树形目录功能.找了一下发现有很多JQuery插件都可以实现这个功能.选了一个自己觉得最满意的插件Dynatree做个学习笔记. 可以把静态的html转成树形目录,还可以动态创建添加 ...
- bootstrap轮播组件之“如何关闭自动轮播”
在一个页面里使用多个bootstrap轮播组件的时候,如果还让所有轮播图都自动轮播的话,整个画面都在动,会给用户一种很不好的体验感受.所以,需要关闭轮播图的自动轮播. 关闭方法:去除如下属性即可: d ...
随机推荐
- DrawerLayout 和 NavigationView 的使用
参考: 1.NavigationView 的使用 2.NavigationView更改菜单icon和title颜色变化效果 3.Android 自己实现 NavigationView 转了第一篇 ...
- [HTML5] ArrayBuffer与类型化数组
写在前面 这是关于JS二进制操作的第三篇博客,前两篇详见: [HTML5] Blob对象 [HTML5] FileReader对象 此前从宏观角度介绍了如何通过JS创建一个二进制对象,并介绍了如何将本 ...
- NBUT 1457 莫队算法 离散化
Sona Time Limit:5000MS Memory Limit:65535KB 64bit IO Format: Submit Status Practice NBUT 145 ...
- 个人作业-Week1
问题1:程序员的优劣是否在软件开发中已经不重要了??用户实际关心的 外形,使用的乐趣和效率,自我形象,个人满足感,回忆,这么多条中,仅有效率与代码有关,而实际上用户比起效率却更在意其他这些“幺蛾子”. ...
- Android 样式 (style) 和主题(theme)
转载:https://gold.xitu.io/post/58441c48c59e0d0056a30bc2 样式和主题 样式是指为 View 或窗口指定外观和格式的属性集合.样式可以指定高度.填充.字 ...
- ubuntu用作开发办公平台的完美体验
2016年6月3日 对于使用使用linux操作系统作为办公平台的新手来说很不适应,需要在多种方式中找到自己喜欢,适合自己的方式比较难.摸索了很久终于发现了一个适合我自己的使用方式了.这种方式也适合其他 ...
- 【JavaWeb】SSM+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(六)
Showings 我个人的项目,当前不断地在更新. 我希望做成一个好项目,同时,也是在锻炼自己的技术. 在项目中发现问题,学习知识,是比较可取的一条路子. 这样学习到的知识,虽然分散,但是都很实用,而 ...
- TThread.CreateAnonymousThread() 匿名线程对象的应用
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- 个人作业——week3
1.软件工程师的成长 拜读了多位优秀前辈的文章后,感觉十分复杂,虽然说不上是醍醐灌顶的那种大彻大悟,但是确实的感觉到自己内心中某个部分被真切的感触到了.推荐的文章语言都比较平易近人,感觉就像是和多年未 ...
- linux 系统、命令、软件
软件名称:Putty 使用方法:http://jingyan.baidu.com/article/e73e26c0eb063324adb6a737.html 需要资料: 服务IP:228.5624.5 ...