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 ...
随机推荐
- 常见web攻击以及防御
xss攻击: 跨站脚本攻击,攻击者在网页中嵌入恶意代码,当用户打开网页,脚本程序便开始在客户端的浏览器上执行,以盗取客户端cookie,用户名密码,下载执行病毒木马程序,甚至是获取客户端admin权限 ...
- windows批处理运行java程序
明确需求 今天你编了一个java swing版照片查看器,想让计算机上的所有照片默认打开方式都改成你的照片查看器. 使用工具软件 很多工具软件都是不把jre打包到exe中的,这就是说打包之后的exe只 ...
- jquery option
转--jquery动态添加option示例 http://www.jb51.net/article/45031.htm //js动态添加option var sel= document.getElem ...
- Android Studio中的CmakeList NDK配置
Android Studio2.2之后直接可以在创建工程时添加NDK支持了,添加之后,main文件夹下会多出一个native-lib.cpp这个文件,如果只为了一个简单的NDK接口,貌似这就结束了.直 ...
- 织梦DedeCMS
DedeAMPZ服务器套件 http://dedeampz.dedecms.com/ DedeCMS PHP开源网站管理系统 CMS系统 http://www.dedecms.com/produc ...
- 【bzoj1415】 Noi2005—聪聪和可可
http://www.lydsy.com/JudgeOnline/problem.php?id=1415 (题目链接) 题意 一张图,聪聪想吃可可.每单位时间聪聪可以先移动两次:可可后移动一次或停在原 ...
- .net自带的IOC容器MEF使用
IOC能做什么 IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合.更优良的程序. 控制反转: 将控制权移交给第三方容器 new 操作 依赖注入: 在程序 ...
- linux 下shell中if的“-e,-d,-f”是什么意思
文件表达式-e filename 如果 filename存在,则为真-d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真-L ...
- 2016福州大学软件工程第三次个人作业-K米软件产品评测
K米软件测评个人作业结果统计如下: 评分标准: 按照栋哥布置的第三次个人作业--K米测评制定评分标准如下: 第一部分:调研.评测 下载并使用,描述最简单直观的个人第一次上手体验. 0.5 按照描述的b ...
- 通过SmartGit把java maven项目传到码云
一.首先先在码云上新建一个项目 二.复制项目的链接 三.打开SmartGit,点击clone 4.把复制的项目链接粘上去 5.然后点两次next,选择一个路径,finish 6.打开刚刚选择的路径,我 ...