HTML的级联Select

      系统开发中,经常遇到级联Select的状况,而级联的Select Option数据一般记录于DB,如果每次都重新写一套级联Select,工作将是繁琐滴。。。

      一般来说,写一套级联的Select的几个步骤:

  1. 从DB读取Select Option的级联数据
  2. 将数据封装成JSON或xml传到前台
  3. 在前台由JS动态组装/填充Select元素
  4. 用JS调整各个级联Select之间的交互,如父Select值发生改变,重新填充子Select的选项,并清空子Select的已选值

  而这次,想写一套可重用的代码,便于以后有需要的时候可方便的搬进以后的项目,本代码依赖于

  1. Gson 2.2.4
  2. Jquery 1.6.1

  

  Kick-off:

  首先,由于是Demo,我们不从DB查询数据,只是用Collection直接模拟数据,为了便于生成JSON,使用Gson转换,为了组装级联数据结构方便,使用Selector.java和SelectorOption.java作为存储的结构:

  1 import java.io.IOException;
  2 import java.util.ArrayList;
  3 import java.util.HashMap;
  4 import java.util.List;
  5 import java.util.Map;
  6 
  7 import javax.servlet.ServletException;
  8 import javax.servlet.http.HttpServlet;
  9 import javax.servlet.http.HttpServletRequest;
 10 import javax.servlet.http.HttpServletResponse;
 11 
 12 import com.google.gson.Gson;
 13 import com.google.gson.GsonBuilder;
 14 
 15 public class CascapeSelectorServlet extends HttpServlet {
 16     private static final long serialVersionUID = 1L;
 17        
 18     public CascapeSelectorServlet() {
 19         super();
 20     }
 21 
 22     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 23         this.doPost(request, response);
 24     }
 25 
 26     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 27         
 28         /* country */
 29         Selector countrySelector = new Selector("country", null, getCountry());
 30         
 31         /* province */
 32         Selector provinceSelector = new Selector("province", null, new HashMap());
 33         List<SelectorOption> provinceList = getProvince();
 34         for (int i = 0; i < provinceList.size(); i++) {
 35             provinceSelector.put(provinceList.get(i).getParent(), provinceList.get(i));
 36         }
 37         
 38         /* city */
 39         Selector citySelector = new Selector("city", null, new HashMap());
 40         List<SelectorOption> cityList = getCity();
 41         for (int i = 0; i < cityList.size(); i++) {
 42             citySelector.put(cityList.get(i).getParent(), cityList.get(i));
 43         }
 44         
 45         Map dataMap = new HashMap();
 46         dataMap.put("country", countrySelector);
 47         dataMap.put("province", provinceSelector);
 48         dataMap.put("city", citySelector);
 49         
 50         /* Gson */
 51         GsonBuilder gsonBuilder = new GsonBuilder();
 52         gsonBuilder.setPrettyPrinting();
 53         Gson gson = gsonBuilder.create();
 54         
 55         /* To json */
 56         String json = gson.toJson(dataMap);
 57         
 58         System.out.println("json -> " + json);
 59         response.getWriter().write(json);
 60     }
 61     
 62     /**
 63      * Analog data
 64      * @return
 65      */
 66     private List<SelectorOption> getCountry() {
 67         List countryList = new ArrayList();
 68         countryList.add(new SelectorOption("cn", "China"));
 69         countryList.add(new SelectorOption("uk", "United Kingdom"));
 70         countryList.add(new SelectorOption("ca", "Canada"));
 71         countryList.add(new SelectorOption("us", "United States"));
 72         
 73         return countryList;
 74     }
 75     
 76     /**
 77      * Analog data
 78      * @return
 79      */
 80     private List<SelectorOption> getProvince() {
 81         List provinceList = new ArrayList();
 82         provinceList.add(new SelectorOption("hb", "Heibei", "cn"));
 83         provinceList.add(new SelectorOption("zj", "Zhejiang", "cn"));
 84         provinceList.add(new SelectorOption("gd", "Guangdong", "cn"));
 85         provinceList.add(new SelectorOption("gx", "Guangxi", "cn"));
 86         provinceList.add(new SelectorOption("ca", "California", "us"));
 87         
 88         return provinceList;
 89     }
 90     
 91     /**
 92      * Analog data
 93      * @return
 94      */
 95     private List<SelectorOption> getCity() {
 96         List cityList = new ArrayList();
 97         cityList.add(new SelectorOption("gz", "Guangzhou", "gd"));
 98         cityList.add(new SelectorOption("nn", "Nanning", "gx"));
 99         cityList.add(new SelectorOption("fs", "Foshan", "gd"));
100         cityList.add(new SelectorOption("hz", "Huizhou", "gd"));
101         cityList.add(new SelectorOption("la", "Los Angeles", "ca"));
102         
103         return cityList;
104     }
105 
106 }
CascapeSelectorServlet.java

  SelectorOption.java用于装一个Select的Option数据:

 1 public class SelectorOption {
 2 
 3     private String value;
 4     private String name;
 5     private String parent;
 6 
 7     public String getValue() {
 8         return value;
 9     }
10 
11     public void setValue(String value) {
12         this.value = value;
13     }
14 
15     public String getName() {
16         return name;
17     }
18 
19     public void setName(String name) {
20         this.name = name;
21     }
22 
23     public String getParent() {
24         return parent;
25     }
26 
27     public void setParent(String parent) {
28         this.parent = parent;
29     }
30 
31     public SelectorOption(String value, String name) {
32         super();
33         this.value = value;
34         this.name = name;
35     }
36 
37     public SelectorOption(String value, String name, String parent) {
38         super();
39         this.value = value;
40         this.name = name;
41         this.parent = parent;
42     }
43     
44 }
SelectorOption.java

  Selector.java用于装一个Selecti的数据:

 1 import java.util.ArrayList;
 2 import java.util.HashMap;
 3 import java.util.List;
 4 import java.util.Map;
 5 
 6 public class Selector {
 7 
 8     private String name;
 9     private String parent;
10     private Map dataMap;
11 
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     public String getParent() {
21         return parent;
22     }
23 
24     public void setParent(String parent) {
25         this.parent = parent;
26     }
27 
28     public Map getDataMap() {
29         return dataMap;
30     }
31 
32     public void setDataMap(Map dataMap) {
33         this.dataMap = dataMap;
34     }
35 
36     public Selector(String name, String parent, List dataList) {
37         super();
38         this.name = name;
39         this.parent = parent;
40         this.dataMap = new HashMap();
41         this.dataMap.put("default", dataList);
42     }
43 
44     public Selector(String name, String parent, Map dataMap) {
45         super();
46         this.name = name;
47         this.parent = parent;
48         this.dataMap = dataMap;
49     }
50     
51     public void put(String key, Object object) {
52         
53         if (key == null || key.length() == 0) {
54             return;
55         }
56         
57         if (object == null) {
58             return;
59         }
60         
61         if (this.dataMap == null) {
62             this.dataMap = new HashMap();
63         }
64         
65         if (this.dataMap.containsKey(key) && this.dataMap.get(key) != null) {
66             List tempList = (List)this.dataMap.get(key);
67             tempList.add(object);
68         }
69         
70         if (!this.dataMap.containsKey(key)) {
71             List tempList = new ArrayList();
72             tempList.add(object);
73             
74             this.dataMap.put(key, tempList);
75         }
76         
77     }
78     
79 }
Selector.java

  cascsel.js则用于处理各个级联Select之间的交互:

 1 /**
 2  * Register & initialize select
 3  */
 4 function registerSelector(data, array, index) {
 5     if (!array || array.length == 0) {
 6         return;
 7     }
 8     
 9     if (index < 0 || index >= array.length) {
10         return;
11     }
12     
13     if (!data[array[index]]) {
14         return;
15     }
16     
17     var $select = $("[name='" + array[index] + "']");
18     
19     /* Initialize default select */
20     var dataList = data[array[index]]["dataMap"]["default"];
21     if (dataList && dataList.length > 0) {
22         $select.empty();
23         for (var i = 0; i < dataList.length; i++) {
24             $select.append("<option value='" + dataList[i]["value"] + "'>" + dataList[i]["name"] + "</option>")
25         }
26     }
27     
28     /* Register onchange event for select */
29     if ((index + 1) < array.length && data[array[index + 1]]) {
30         $select.bind("change", function(event) {
31             var value = $select.val();
32             var dataList = data[array[index + 1]]["dataMap"][value];
33             
34             $nextSelect = $("[name='" + array[index + 1] + "']");
35             /* If the option of select changes, refactor the cascape select */
36             if (dataList && dataList.length > 0) {
37                 $nextSelect.empty();
38                 for (var i = 0; i < dataList.length; i++) {
39                     $nextSelect.append("<option value='" + dataList[i]["value"] + "'>" + dataList[i]["name"] + "</option>")
40                 }
41             } else {
42                 $nextSelect.empty();
43             }
44             
45             /* Trigger */
46             $nextSelect.trigger("change");
47         });
48         
49         $select.trigger("change");
50     }
51     
52     registerSelector(data, array, index + 1);
53     
54 }
cascsel.js

  cascsel.jsp为Demo的展示页面(调用cascsel.js):

 1 <%@ page language="java" contentType="text/html; charset=utf-8"
 2     pageEncoding="utf-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 7 <script type="text/javascript" src="js/jquery-1.6.1.js"></script>
 8 <script type="text/javascript" src="js/cascsel.js"></script>
 9 <script type="text/javascript">
10 $().ready(function() {
11 
12     querySelector();
13 
14 });
15 
16 /**
17  * Get select json by ajax
18  */
19 function querySelector() {
20     $.ajax({
21         url : "CascapeSelectorServlet",
22         dataType : "json",
23         type : "post",
24         contentType : "application/x-www-form-urlencoded; charset=utf-8", 
25         cache : false, 
26         error : function(dty, errorType) {
27             alert(errorType);
28         },
29         success : function(data) {
30             registerSelector(data, ["country", "province", "city"], 0);
31         }
32     });
33 }
34 
35 </script>
36 
37 <title>Cascape Select</title>
38 </head>
39 <body>
40 
41 <select name="country" ></select>
42 <select name="province" ></select>
43 <select name="city" ></select>
44 
45 </body>
46 </html>
cascsel.jsp

Enjoy it!

原文地址:https://www.cnblogs.com/nick-huang/p/3606693.html