html選擇框多級聯動
阿新 • • 發佈:2018-12-26
Demo來源:http://www.imuum.com/plugin-jquery-cityselect-js-provinces-linkage-effect.html
我把Demo改寫成最多可以到5級聯動,需要增加修改也很容易
資料來源,Java端通過Spring boot輸出將實體類轉成JSON物件,轉換效率有點低
TreeItem.java
Tree.javapublic class TreeItem { private String id; private String pId; private String name; private String extra; public TreeItem(String id,String pId,String name) { this.id = id; this.pId = pId; this.name = name; } public TreeItem(String id,String pId, String name, String extra) { this.id = id; this.pId = pId; this.name = name; this.extra = extra; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getpId() { return pId; } public void setpId(String pId) { this.pId = pId; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
通過呼叫Tree.buildTree函式就可以生成我們需要的json資料import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Tree { private List<TreeItem> nodes; public Tree(List<TreeItem> nodes){ this.nodes = nodes; } public Map buildTree(){ List<Map<String,Object>> list=new ArrayList<>(); for (TreeItem node : nodes) { String id = node.getId(); if (node.getpId() == null) { list.add(build(node)); } } Map treeMap=new HashMap<>(); treeMap.put("citylist",list); return treeMap; } private Map build(TreeItem node){ List<TreeItem> children = getChildren(node); List<Map<String,Object>> list=new ArrayList<>(); Map<String,Object> map=new HashMap<>(); map.put("node",node); if (children.isEmpty()) { return map; } for (TreeItem child : children) { list.add(build(child)); } map.put("children",list); return map; } private List<TreeItem> getChildren(TreeItem node){ List<TreeItem> children = new ArrayList<TreeItem>(); String id = node.getId(); for (TreeItem child : nodes) { if (id.equals(child.getpId())) { children.add(child); } } return children; } }
然後就是前端頁面了,預設值部分還沒有做
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>基於jQuery+JSON的省市聯動效果</title> <script type="text/javascript" src="js/jquery.2.1.1.min.js"></script> <script type="text/javascript" src="js/jquery.cityselect2.js"></script> <script type="text/javascript"> $(function(){ $("#city").citySelect({ nodata:null, required:false }); }); </script> </head> <body> <div id="main"> <div class="demo"> <h3>設定省份、城市、地區(縣)的預設值</h3> <p>三級聯動</p> <div id="city"> <select class="s0"></select> <select class="s1" disabled="disabled"></select> <select class="s2" disabled="disabled"></select> <select class="s3" disabled="disabled"></select> <select class="s4" disabled="disabled"></select> </div> </div> </div> <br /> <br /> </div> </body> </html>
cityselect2.js
/*
Ajax 多級聯動
http://code.ciaoca.cn/
日期:2012-7-18
settings 引數說明
-----
url:省市資料josn檔案路徑
prov:預設省份
city:預設城市
dist:預設地區(縣)
nodata:無資料狀態
required:必選項
------------------------------ */
(function($){
$.fn.citySelect=function(settings){
if(this.length<1){return;};
// 預設值
settings=$.extend({
url:"js/city.js",
prov:null,
city:null,
dist:null,
nodata:null,
required:true
},settings);
var box_obj=this;
var s0_obj=box_obj.find(".s0");
var s1_obj=box_obj.find(".s1");
var s2_obj=box_obj.find(".s2");
var s3_obj=box_obj.find(".s3");
var s4_obj=box_obj.find(".s4");
var prov_val=settings.prov;
var select_prehtml=(settings.required) ? "" : "<option value=''>請選擇</option>";
var city_json;
//獲取當前選擇框前面的選擇框
var getPreS=function(s){
if(s==s1_obj) return s0_obj;
if(s==s2_obj) return s1_obj;
if(s==s3_obj) return s2_obj;
if(s==s4_obj) return s3_obj;
return null;
}
//獲取當前選擇框的下一個選擇框
var getNextS=function(s){
if(s==s0_obj) return s1_obj;
if(s==s1_obj) return s2_obj;
if(s==s2_obj) return s3_obj;
if(s==s3_obj) return s4_obj;
return null;
}
//獲取當前選擇框的序號
var getSelectN=function(s){
if(s==s0_obj) return 0;
if(s==s1_obj) return 1;
if(s==s2_obj) return 2;
if(s==s3_obj) return 3;
return 4;
}
//根據當前選擇框的值獲取json資料的children
var getCityChildren=function(s){
var s0_id=s0_obj.get(0).selectedIndex;
var s1_id=s1_obj.get(0).selectedIndex;
var s2_id=s2_obj.get(0).selectedIndex;
var s3_id=s3_obj.get(0).selectedIndex;
var s4_id=s4_obj.get(0).selectedIndex;
if(!settings.required){
s0_id--;
s1_id--;
s2_id--;
s3_id--;
s4_id--;
};
if(s==s0_obj) return city_json.citylist[s0_id].children;
if(s==s1_obj) return city_json.citylist[s0_id].children[s1_id].children;
if(s==s2_obj) return city_json.citylist[s0_id].children[s1_id].children[s2_id].children;
if(s==s3_obj) return city_json.citylist[s0_id].children[s1_id].children[s2_id].children[s3_id].children;
return null;
}
//根據序號隱藏選擇框
var hidSubSelect=function(n){
if(n<1){
s1_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s1_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s1_obj.css("visibility","hidden");
};
}
if(n<2){
s2_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s2_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s2_obj.css("visibility","hidden");
};
}
if(n<3){
s3_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s3_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s3_obj.css("visibility","hidden");
};
}
if(n<4){
s4_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s4_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s4_obj.css("visibility","hidden");
};
}
}
// 賦值地區(縣)函式
var distStart=function(s){
var current_id=s.selectedIndex;
if(!settings.required){
current_id--;
};
hidSubSelect(getSelectN(s));
if(current_id<0||typeof(getCityChildren(s))=="undefined"||getCityChildren(s)==null){
if(settings.nodata=="none"){
getNextS(s).css("display","none");
}else if(settings.nodata=="hidden"){
getNextS(s).css("visibility","hidden");
};
return;
};
// 遍歷
temp_html=select_prehtml;
$.each(getCityChildren(s),function(i,dist){
temp_html+="<option value='"+dist.node.id+"'>"+dist.node.name+"</option>";
});
getNextS(s).html(temp_html).attr("disabled",false).css({"display":"","visibility":""});
};
var init=function(){
// 遍歷賦值省份下拉列表
temp_html=select_prehtml;
$.each(city_json.citylist,function(i,prov){
temp_html+="<option value='"+prov.node.id+"'>"+prov.node.name+"</option>";
});
s0_obj.html(temp_html);
// 若有傳入省份與市級的值,則選中。(setTimeout為相容IE6而設定)
setTimeout(function(){
if(settings.prov!=null){
prov_obj.val(settings.prov);
cityStart();
setTimeout(function(){
if(settings.city!=null){
city_obj.val(settings.city);
distStart();
setTimeout(function(){
if(settings.dist!=null){
dist_obj.val(settings.dist);
};
},1);
};
},1);
};
},1);
// 選擇省份時發生事件
s0_obj.bind("change",function(){
distStart(s0_obj);
});
s1_obj.bind("change",function(){
distStart(s1_obj);
});
s2_obj.bind("change",function(){
distStart(s2_obj);
});
s3_obj.bind("change",function(){
distStart(s3_obj);
});
s4_obj.bind("change",function(){
distStart(s4_obj);
});
};
// 設定省市json資料
if(typeof(settings.url)=="string"){
$.getJSON(settings.url,function(json){
city_json=json;
init();
});
}else{
city_json=settings.url;
init();
};
};
})(jQuery);
把樹的建立放到了前端js來建立
後端直接輸出List<TreeItem>物件,框架自動輸出JSON陣列,前端js遞迴建樹的程式碼如下
var districts;
var arrayToTree=function(parentId) {
var temp = [];
for (var index in districts) {
if (districts[index].pId == parentId) {
var children=arrayToTree(districts[index].id);
temp.push({
node: districts[index],
children: children
});
}
}
return temp;
};
var buildTree= function (parentId) {
var temp = {citylist:[]};
for (var index in districts) {
if (districts[index].id == parentId) {
temp.citylist.push({
node: districts[index],
children: arrayToTree(districts[index].id)
});
}
}
return temp;
};
在得到資料的時候修改一下
$.getJSON(settings.url, function (json) {
districts=json;
city_json = buildTree('000');//000是根節點的ID
init();
}
jquery.cityselect.js最後的Javascript程式碼如下
/*
多級聯動 劉放
日期:2016-8-22
settings 引數說明
-----
url:省市資料josn檔案路徑
s0:預設省份
s1:預設市
s2:預設縣
s3:預設鄉鎮
s4:預設村
nodata:無資料狀態 如果需要隱藏則填寫none或者hidden
required:必選項
依賴於web-storage-cache.min.js
------------------------------ */
(function($){
$.fn.citySelect=function(settings){
if(this.length<1){return;};
var wsCache = new WebStorageCache();
// 預設值
settings=$.extend({
url:null,
s1:null,
s2:null,
s3:null,
s4:null,
s0:null,
nodata:null,
required:true
},settings);
var box_obj=this;
var s0_obj=box_obj.find(".s0");
var s1_obj=box_obj.find(".s1");
var s2_obj=box_obj.find(".s2");
var s3_obj=box_obj.find(".s3");
var s4_obj=box_obj.find(".s4");
var text_obj=box_obj.find("input[type=hidden]");
var setTextObj=function(){
if(text_obj.length>0) {
if(s4_obj.val()!=="") {
text_obj.val(
s0_obj.find("option:selected").text()+
s1_obj.find("option:selected").text()+
s2_obj.find("option:selected").text()+
s3_obj.find("option:selected").text()+
s4_obj.find("option:selected").text());
}else{
text_obj.val("");
}
}
};
var prov_val=settings.prov;
var select_prehtml=(settings.required) ? "" : "<option value=''>請選擇</option>";
var city_json;
//獲取當前選擇框前面的選擇框
var getPreS=function(s){
if(s==s1_obj) return s0_obj;
if(s==s2_obj) return s1_obj;
if(s==s3_obj) return s2_obj;
if(s==s4_obj) return s3_obj;
return null;
}
//獲取當前選擇框的下一個選擇框
var getNextS=function(s){
if(s==s0_obj) return s1_obj;
if(s==s1_obj) return s2_obj;
if(s==s2_obj) return s3_obj;
if(s==s3_obj) return s4_obj;
return null;
}
//獲取當前選擇框的序號
var getSelectN=function(s){
if(s==s0_obj) return 0;
if(s==s1_obj) return 1;
if(s==s2_obj) return 2;
if(s==s3_obj) return 3;
return 4;
}
//根據當前選擇框的值獲取json資料的children
var getCityChildren=function(s){
var s0_id=s0_obj.get(0).selectedIndex;
var s1_id=s1_obj.get(0).selectedIndex;
var s2_id=s2_obj.get(0).selectedIndex;
var s3_id=s3_obj.get(0).selectedIndex;
var s4_id=s4_obj.get(0).selectedIndex;
if(!settings.required){
s0_id--;
s1_id--;
s2_id--;
s3_id--;
s4_id--;
};
if(s===s0_obj) return city_json.list[s0_id].children;
if(s===s1_obj) return city_json.list[s0_id].children[s1_id].children;
if(s===s2_obj) return city_json.list[s0_id].children[s1_id].children[s2_id].children;
if(s===s3_obj) return city_json.list[s0_id].children[s1_id].children[s2_id].children[s3_id].children;
return null;
}
//根據序號隱藏選擇框
var hidSubSelect=function(n){
if(n<1){
s1_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s1_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s1_obj.css("visibility","hidden");
};
}
if(n<2){
s2_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s2_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s2_obj.css("visibility","hidden");
};
}
if(n<3){
s3_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s3_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s3_obj.css("visibility","hidden");
};
}
if(n<4){
s4_obj.empty().attr("disabled",false);
if(settings.nodata=="none"){
s4_obj.css("display","none");
}else if(settings.nodata=="hidden"){
s4_obj.css("visibility","hidden");
};
}
}
// 賦值地區(縣)函式
var distStart=function(s){
if($(s).val()==="") return;
var current_id=s.selectedIndex;
if(!settings.required){
current_id--;
};
hidSubSelect(getSelectN(s));
if(current_id<0||typeof(getCityChildren(s))=="undefined"||getCityChildren(s)==null){
if(settings.nodata=="none"){
getNextS(s).css("display","none");
}else if(settings.nodata=="hidden"){
getNextS(s).css("visibility","hidden");
};
return;
};
var next_obj=getNextS(s);//獲取到下一個元件
if(next_obj==null) return;
// 遍歷
temp_html=select_prehtml;
$.each(getCityChildren(s),function(i,dist){
temp_html+="<option value='"+dist.node.id+"'>"+dist.node.name+"</option>";
});
next_obj.html(temp_html).attr("disabled",false).css({"display":"","visibility":""});
if($(s).val()!==""){
distStart(next_obj);
}
};
var initCity=function(){
// 遍歷賦值省份下拉列表
temp_html=select_prehtml;
$.each(city_json.list,function(i,prov){
temp_html+="<option value='"+prov.node.id+"'>"+prov.node.name+"</option>";
});
s0_obj.html(temp_html);
distStart(s0_obj);
// 若有傳入省份與市級的值,則選中。(setTimeout為相容IE6而設定)
setTimeout(function(){
if(settings.s0!==null&&settings.s0!==""){
s0_obj.val(settings.s0);
distStart(s0_obj);
setTimeout(function(){
if(settings.s1!=null){
if(s1_obj==null) return;
s1_obj.val(settings.s1);
distStart(s1_obj);
setTimeout(function(){
if(s2_obj==null) return;
if(settings.s2!=null){
s2_obj.val(settings.s2);
distStart(s2_obj);
setTimeout(function(){
if(s3_obj==null) return;
if(settings.s3!=null){
s3_obj.val(settings.s3);
distStart(s3_obj);
setTimeout(function(){
if(s4_obj==null) return;
if(settings.s4!=null){
s4_obj.val(settings.s4);
};
},1);
};
},1);
};
},1);
};
},1);
};
},1);
setTimeout(function(){
// 選擇省份時發生事件
s0_obj.bind("change",function(){
distStart(s0_obj);
});
s1_obj.bind("change",function(){
distStart(s1_obj);
});
s2_obj.bind("change",function(){
distStart(s2_obj);
});
s3_obj.bind("change",function(){
distStart(s3_obj);
});
s4_obj.bind("change",function(){
distStart(s4_obj);
setTextObj();
});
},50);
};
var districts;
var arrayToTree=function(parentId) {
var temp = [];
for (var index in districts) {
if (districts[index].pId == parentId) {
var children=arrayToTree(districts[index].id);
temp.push({
node: districts[index],
children: children
});
}
}
return temp;
};
var buildTree= function (parentId) {
var temp = {list:[]};
for (var index in districts) {
if (districts[index].id == parentId) {
temp.list.push({
node: districts[index],
children: arrayToTree(districts[index].id)
});
}
}
return temp;
};
// 設定省市json資料
if(typeof(settings.url)=="string"){
city_json=wsCache.get("allCity");
if(city_json!==undefined&&city_json!==null){
initCity();
}
else {
$.getJSON(settings.url, function (json) {
districts=json;
city_json = buildTree('320000000000');//前端建好樹
wsCache.set('allCity', city_json, {exp : 60*12});//快取12*60s
initCity();
});
}
}else{
city_json=settings.url;
initCity();
};
};
})(jQuery);