/**
级联下拉菜单
Last Edit: 2011-11-4
Version: 0.1
默认数据格式,没有自定义数据解析器时,都是以这种格式处理:
[
{text:'2',value:'2',child:[
{text:'2.1',value:'2.1',child:[]}
]
},
{text:'1.1.1',value:'1.1.1'}
]
**/
(function($) {
//全局设定
var globalSetting = {
dataType : null,//地区area、证书类型licence
language : "cn",//显示语言
maxLevel: 5,//级联层数
onChange : function(){},//onchange事件
format : function(text){ //格式化下拉菜单显示的内容,可以在全局参数统一设置,也可以在每一级单独设置
return text;
},
css : ""
};
//某一级设定
var levelSetting = {
container : null,//容器
blankItem : null, //{text:'-----',value:-1}
title : "",
titlePos : "left",
id : "select",
css : "",
defaultValue : null,
format : function(text){}
};
//数据解析
var DataParser = {
language : "cn",
//每种类型不同的处理
"area": {
ordinalData : window.citys||[],
idIndex : 5,
textIndex : 2,
setLanguage : function(language){
if(language == "en"){
this.idIndex = 5;
this.textIndex = 3;
}
},
getOrdinalData : function(i){
return {value:this.ordinalData[i][this.idIndex],
text:this.ordinalData[i][this.textIndex],
isParent:this.ordinalData[i][4] == 1 ? true : false};
}
},
"licence":{
ordinalData : window.licence||[],
idIndex : 1,
textIndex : 0,
setLanguage : function(language){
if(language == "en"){
this.idIndex = 1;
this.textIndex = 0;
}
},
getOrdinalData : function(i){
return {value:this.ordinalData[i][this.idIndex],
text:this.ordinalData[i][this.textIndex],
isParent:this.ordinalData[i][2] == 1 ? true : false};
}
},
getData : function(dataType){
var data = [];
var st = this[dataType];
if(!st) return null;
st.setLanguage(DataParser.language);
var item,parentItem;
for(var i=0;i<st.ordinalData.length;i++){
item = st.getOrdinalData(i);
if(item.isParent == true){
item.child = [];
parentItem = item;
data.push(item);
} else {
parentItem.child.push(item);
}
}
return data;
},
changeObjToMap : function(orgData){
var stack = [].concat(orgData);
var item, result = {};
//将树形的结构转换为简单的key,value结构,key为菜单项的值,value为该项的子菜单数组
while(stack.length != 0){
item = stack.shift();
result[item.value] = item.child || [];
if(item.child){
for(var j=0;j<item.child.length;j++){
stack.push(item.child[j]);
}
}
}
return result;
},
getDataParser : function(arg){
var orgData = DataParser.getData(arg);
if(!orgData){
orgData = arg;
}
var result = this.changeObjToMap(orgData);
//返回默认的数据解析器,自定义的解析器也要实现这里的方法
return {
//返回第一个菜单数组
getRoot : function(){
return orgData;
},
//根据级别参数和选中的值,返回下一级的
getNext : function(value, level){
return !!result[value] ? result[value] : [];
}
}
}
};
/**
* 生成多级下拉菜单,并且控制菜单的关系
**/
cv.linkSelect = function(container, setting){
this.container = jQuery(container);
this.setting = [];
this.setting[0] = $.extend({}, globalSetting, setting);
for(var i=1;i<=this.setting[0].maxLevel;i++){
this.setting[i] = $.extend({}, levelSetting, this.setting[0]);
}
this.parser = null;
if(this.setting[0].dataType){
DataParser.language = this.setting[0].language;
this.parser = DataParser.getDataParser(this.setting[0].dataType);
}
this.selectors = [];
};
cv.linkSelect.prototype = {
setOption : function(level, setting){
if(level < 0){
throw "level must start from 0";
}
this.setting[level + 1] = $.extend({}, this.setting[level + 1], setting);
},
render : function(){
var selector,defaultValue,currentData = this.parser.getRoot();
for(var i=0;i<this.setting[0].maxLevel;i++){
if(this.setting[i+1].blankItem){
currentData.unshift(this.setting[i+1].blankItem)
}
defaultValue = this.setting[i+1].defaultValue;
if(!defaultValue){
defaultValue = currentData[0].value;
}
selector = new Selector(this, this.setting[i+1], i);
selector.setData(currentData);
selector.render();
selector.setSelect(defaultValue);
this.selectors[i] = selector;
if(this.parser.getNext(defaultValue, i).length > 0){
currentData = this.parser.getNext(defaultValue, i);
}else {
break;//20121025修改
// currentData = [];
}
}
},
//设置符合默认格式的数据
setData : function(data){
this.parser = DataParser.getDataParser(data);
},
setDataParser : function(parser){
this.parser = parser;
},
setSelect : function(level, value){
if(this.selectors[level]){
this.selectors[level].setSelect(value);
this.change(level);
}
},
setText : function(level, text){
if(this.selectors[level]){
var value = this.selectors[level].setText(text);
this.change(level);
}
},
change : function(level){
var childData, selector;
for(var i=level;i<this.setting[0].maxLevel;i++){
childData = this.parser.getNext(this.selectors[i].getSelectValue(), i);
//当前选项没有子菜单,将已经生成的子菜单都删除
if(!childData || childData.length == 0){
for(var j=i+1;j<this.selectors.length;j++){
if(this.selectors[j]){
this.selectors[j].remove();
this.selectors[j] = null;
}
}
//break;//20121025修改
break;
}
//因为level表示当前的级别,现在要取下一个级别的空白元素(level + 1),又因为setting跟level错开了一位,所以要level+2
if(this.setting[level + 2].blankItem){
childData.unshift(this.setting[level + 2].blankItem)
}
//判断下一级的子菜单是否存在,存在则刷新数据,不存在则创建新的子菜单
if(this.selectors[i+1]){
this.selectors[i+1].setData(childData);
this.selectors[i+1].refreshItem();
} else {
selector = new Selector(this, this.setting[i+2], i+1);
selector.setData(childData);
selector.render();
this.selectors[i+1] = selector;
}
}
this.setting[0].onChange(level, this.selectors[level].getSelectValue());
},
getValue : function(){
var result = [];
for(var i=0;i<this.selectors.length;i++){
if(!this.selectors[i]) break;
result.push(this.selectors[i].getSelectValue());
}
return result;
},
getText : function(){
var result = [];
for(var i=0;i<this.selectors.length;i++){
if(!this.selectors[i]) break;
result.push(this.selectors[i].getSelectText());
}
return result;
}
};
/**
* 代表每一级的菜单对象
**/
var Selector = function(linkSelectObj, setting, level){
this.data = null;
this.linkSelectObj = linkSelectObj;
this.setting = setting;
this.level = level;
this.selectObj = null;
this.container;
};
Selector.prototype = {
addItem : function(item){
this.selectObj.append("<option value='"+item.value+"'>"+this.setting.format(item.text)+"</option>");
},
addAllItem : function(){
for(var i=0;i<this.data.length;i++){
this.addItem(this.data[i]);
}
},
setSelect : function(value){
var item;
this.selectObj.find("option").each(function(){
if(this.value == value){
this.selected=true;
this.defaultSelected=true;
} else {
this.defaultSelected=false;
}
});
},
setText : function(text){
var item , value;
this.selectObj.find("option").each(function(){
value = this.value;
if($(this).html() == text){
this.selected=true;
this.defaultSelected=true;
} else {
this.defaultSelected=false;
}
});
return value;
},
setData : function(data){
this.data = data;
},
getSelectValue : function(){
return this.selectObj.val();
},
getSelectText : function(){
return this.selectObj.find("option").eq(this.selectObj.attr("selectedIndex")).html();
},
render : function(){
var self = this;
this.selectObj = $("<select></select>").attr("id", this.setting.id).addClass(this.setting.css)
.change(function(){
self.linkSelectObj.change(self.level);
});
if(this.setting.name)this.selectObj.attr("name", this.setting.name);
this.addAllItem();
if(this.setting.titlePos == "left"){
this.container = $("<span></span>").append(this.setting.title).append(this.selectObj)
.appendTo(this.setting.container ? this.setting.container : this.linkSelectObj.container);
} else {
this.container = $("<span></span>").append(this.selectObj).append(this.setting.title)
.appendTo(this.setting.container ? this.setting.container : this.linkSelectObj.container);
}
},
refreshItem : function(){
this.selectObj.empty();
this.addAllItem();
},
remove : function(){
this.container.remove();
this.container = null;
},
empty : function(){
this.container.find("select").empty();
}
};
})(jQuery);
各种使用: