最近,由于工作的需要,写了一个联动下拉列表控件,理论上支持N级联动,后台可以使用Spring3 MVC的@ResponseBody标注来返回数据(我现在的项目就是使用这种方法),也可以使用其他方式返回数据,只要数据格式为json就行,且不局限于java语言代码。 写的不好的地方,请大家多指教,如果哪位朋友有好的建议或想法,也希望您多多指教,您也可以修改此代码并贴出来与大家共享。
有兴趣的朋友可以更进一步的增强:譬如缓存一些数据到客户端,支持不调用后台的获取数据的方式,支持其他格式(xml等)的数据,等等。 废话不说了,直接贴代码: /**
* LinkedSelect: 联动下拉框控件,支持N级联动。
* 根据每个Select的定义中的url和id为Select做初始化,后台返回的数据为[{value:"",label:""},{value:"",label:""}]形式的数组json
* @author senton
* @version 1.0
*
* 调用示例如下:
* <pre>
* // 声明一个select变量
* var select = new LinkedSelect();
* // 调用selct的init()方法,注意,该方法的参数是一个数组,用[]括起来,每个select的定义用{}括起来,多个select定义之间以,分割
* select.init([
* {
* id:"country",
* url:"获取country列表的url",
* nullable:false,
* defaultValue:2
* },
* {
* id:"province",
* url:"获取province列表的url",
* nullable:false
* },
* {
* id:"city",
* url:"获取city列表的url",
* nullable:false
* }
* ]);
* </pre>
*/
/**
* 定义一个LinkedSelect函数
*/
function LinkedSelect(){
return this;
}/**
* LinkedSelect的初始化方法
* @param allSelectInputs 所有的需要联动显示的下拉框,是一个数组。
* @returns
*/
LinkedSelect.prototype.init = function(allSelectInputs){
// 定义一个内部方法,用于加载一个下拉框,参数:
// allSelectInputs:所有的下拉框定义
// parentId: 上一个被选中的ID,即<option>的value属性值
// currentIndex: 要初始化的下拉框在allSelectInputs中的索引
initNextSelect = function(allSelectInputs, parentId, currentIndex){
// 如果没有allSelectInputs值或者allSelectInputs的长度小于等于currentIndex,说明没有需要初始化的下拉框了,就返回
if(!allSelectInputs || allSelectInputs.length <= currentIndex){
return;
}
// 取出当前需要初始化的select的定义
var currentSelect = allSelectInputs[currentIndex];
// 清空currentSelect的option
$("#"+currentSelect.id).empty();
// 如果还有下一个,则为当前的Select加上onchange事件
if(allSelectInputs.length > currentIndex + 1){
$("#"+currentSelect.id).unbind("change");
$("#"+currentSelect.id).bind("change", function(){
initNextSelect(allSelectInputs, $(this).val(), currentIndex + 1);
});
}
// 如果不是第一个,则需要判断parentId是否为空,如果为空,则递归清空后面的所有下拉框
if(currentIndex != 0){
if(!parentId || parentId == ''){
$("#"+currentSelect.id).append("<option value=''></option>");
initNextSelect(allSelectInputs, $("#"+currentSelect.id).val(), currentIndex + 1);
return;
}
}
// 如果不为空,则根据parentId取出所有的SelectItem初始化currentSelect
$.post(currentSelect.url,
{
parentId:parentId
},
function(data){
// 如果currentSelect在被定义时nullable为true,则说明可以为空,在第一个加上一个空的option
if(currentSelect.nullable){
$("#"+currentSelect.id).append("<option value=''></option>");
}
// 取出所有的selectItem加到currentSelect上
$.each(data, function (index, selectItem) {
// 如果currentSelect在被定义时的defaultValue等于当前selectItem的值,则选中它
if(selectItem.value == currentSelect.defaultValue){
$("#"+currentSelect.id).append("<option selected='selected' value='" + selectItem.value + "'>" + selectItem.label + "</option>");
}
else {
$("#"+currentSelect.id).append("<option value='" + selectItem.value + "'>" + selectItem.label + "</option>");
}
});
// 初始化完毕后,取出当前currentSelect选中的值,作为parentId初始化下一个select
initNextSelect(allSelectInputs, $("#"+currentSelect.id).val(), currentIndex + 1);
},"json"
);
}; // 调用initNextSelect,启动第一个下拉框的加载
initNextSelect(allSelectInputs, "", 0);
};
有兴趣的朋友可以更进一步的增强:譬如缓存一些数据到客户端,支持不调用后台的获取数据的方式,支持其他格式(xml等)的数据,等等。 废话不说了,直接贴代码: /**
* LinkedSelect: 联动下拉框控件,支持N级联动。
* 根据每个Select的定义中的url和id为Select做初始化,后台返回的数据为[{value:"",label:""},{value:"",label:""}]形式的数组json
* @author senton
* @version 1.0
*
* 调用示例如下:
* <pre>
* // 声明一个select变量
* var select = new LinkedSelect();
* // 调用selct的init()方法,注意,该方法的参数是一个数组,用[]括起来,每个select的定义用{}括起来,多个select定义之间以,分割
* select.init([
* {
* id:"country",
* url:"获取country列表的url",
* nullable:false,
* defaultValue:2
* },
* {
* id:"province",
* url:"获取province列表的url",
* nullable:false
* },
* {
* id:"city",
* url:"获取city列表的url",
* nullable:false
* }
* ]);
* </pre>
*/
/**
* 定义一个LinkedSelect函数
*/
function LinkedSelect(){
return this;
}/**
* LinkedSelect的初始化方法
* @param allSelectInputs 所有的需要联动显示的下拉框,是一个数组。
* @returns
*/
LinkedSelect.prototype.init = function(allSelectInputs){
// 定义一个内部方法,用于加载一个下拉框,参数:
// allSelectInputs:所有的下拉框定义
// parentId: 上一个被选中的ID,即<option>的value属性值
// currentIndex: 要初始化的下拉框在allSelectInputs中的索引
initNextSelect = function(allSelectInputs, parentId, currentIndex){
// 如果没有allSelectInputs值或者allSelectInputs的长度小于等于currentIndex,说明没有需要初始化的下拉框了,就返回
if(!allSelectInputs || allSelectInputs.length <= currentIndex){
return;
}
// 取出当前需要初始化的select的定义
var currentSelect = allSelectInputs[currentIndex];
// 清空currentSelect的option
$("#"+currentSelect.id).empty();
// 如果还有下一个,则为当前的Select加上onchange事件
if(allSelectInputs.length > currentIndex + 1){
$("#"+currentSelect.id).unbind("change");
$("#"+currentSelect.id).bind("change", function(){
initNextSelect(allSelectInputs, $(this).val(), currentIndex + 1);
});
}
// 如果不是第一个,则需要判断parentId是否为空,如果为空,则递归清空后面的所有下拉框
if(currentIndex != 0){
if(!parentId || parentId == ''){
$("#"+currentSelect.id).append("<option value=''></option>");
initNextSelect(allSelectInputs, $("#"+currentSelect.id).val(), currentIndex + 1);
return;
}
}
// 如果不为空,则根据parentId取出所有的SelectItem初始化currentSelect
$.post(currentSelect.url,
{
parentId:parentId
},
function(data){
// 如果currentSelect在被定义时nullable为true,则说明可以为空,在第一个加上一个空的option
if(currentSelect.nullable){
$("#"+currentSelect.id).append("<option value=''></option>");
}
// 取出所有的selectItem加到currentSelect上
$.each(data, function (index, selectItem) {
// 如果currentSelect在被定义时的defaultValue等于当前selectItem的值,则选中它
if(selectItem.value == currentSelect.defaultValue){
$("#"+currentSelect.id).append("<option selected='selected' value='" + selectItem.value + "'>" + selectItem.label + "</option>");
}
else {
$("#"+currentSelect.id).append("<option value='" + selectItem.value + "'>" + selectItem.label + "</option>");
}
});
// 初始化完毕后,取出当前currentSelect选中的值,作为parentId初始化下一个select
initNextSelect(allSelectInputs, $("#"+currentSelect.id).val(), currentIndex + 1);
},"json"
);
}; // 调用initNextSelect,启动第一个下拉框的加载
initNextSelect(allSelectInputs, "", 0);
};
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货