需求描述
產品添加頁面,需要選擇車型。在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_"><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="">';
}
} 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 -;
}
else {
return ;
}
}
}
// 保存事件
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: }, );
});
}
// 統計帶價格的返回數據
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 levelName;
// 遍歷4層
$('#cb_').children().children('li').children('input:checkbox').each(function (i) {
if ($(this).is(':checked')) {
flag = true;
} else {
flag = false;
}
$(this).parent().children().children('li').children('input:checkbox').each(function (i) {
if ($(this).is(':checked')) {
flag = false;
flag = true;
} else {
flag = 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 (flag) {
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 + ' ' + levelName + ' ' + 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實現樹形目錄組件代碼詳解的相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對網站的支持!