最近,因為工作需要一個樹形下拉框的組件,經過查資料一般有兩種的實現方法。其一,就是使用zTree實現;其二,就是使用easyUI實現。因為公司的前端不是使用easyUI設計的,故這裡我選擇了zTree來實現下拉樹。
這裡使用簡單的數據格式(即簡單的Json格式)類似如下Json:
var zNodes =[ {id:1, pId:0, name:"北京"}, {id:2, pId:0, name:"天津"}, {id:3, pId:0, name:"上海"}, {id:6, pId:0, name:"重慶"}, {id:4, pId:0, name:"河北省", open:true, nocheck:true}, {id:41, pId:4, name:"石家莊"}, {id:42, pId:4, name:"保定"}, {id:43, pId:4, name:"邯鄲"}, {id:44, pId:4, name:"承德"}, {id:5, pId:0, name:"廣東省", open:true, nocheck:true}, {id:51, pId:5, name:"廣州"}, {id:52, pId:5, name:"深圳"}, {id:53, pId:5, name:"東莞"}, {id:54, pId:5, name:"佛山"}, {id:6, pId:0, name:"福建省", open:true, nocheck:true}, {id:61, pId:6, name:"福州"}, {id:62, pId:6, name:"廈門"}, {id:63, pId:6, name:"泉州"}, {id:64, pId:6, name:"三明"} ];
這裡首先需要一個實體bean,用來封裝對應查出來的數據,如下:
public class ZtreeNode { // id private String id; // 父id private String pId; // 顯示名稱 private String name; // 是否打開 (這裡默認是不打開的,如果需要打開,設為true) // private boolean open ; // 能否選擇 (設置節點是否能夠選擇,默認都能選擇,設為true對應的節點不能選擇) // private boolean nocheck ; /**getter and setter*/ }
這裡需要注意的是 pId 中的第二的字母是大寫的,如果寫成小寫的就不能構造成樹形結構,所有的都是根節點。
然後,將從數據庫中查出來的數據,轉換為對應的ztree需要的bean,再轉換為相應的Json,代碼如下:
// 獲取商品分類樹 返回json public String getGoodsCategoryTreeJson() { List<GoodsCategory> allGoodsCategoryList = goodsCategoryService.getGoodsCategoryTreeJson() ; List<ZtreeNode> ztreelist = new ArrayList<ZtreeNode>(); for(GoodsCategory gcty : allGoodsCategoryList){ ZtreeNode treenade = new ZtreeNode(); treenade.setId(gcty.getId()); treenade.setpId(gcty.getParent()==null?"":gcty.getParent().getId()); treenade.setName(gcty.getName()); ztreelist.add(treenade); } return ajax(ztreelist); }
將list轉換為對應的Json方法,如下:
用到的Json工具包:
import org.springframework.base.util.JsonUtil; private static final String HEADER_ENCODING = "UTF-8"; private static final boolean HEADER_NO_CACHE = true; private static final String HEADER_TEXT_CONTENT_TYPE = "text/plain"; private static final String HEADER_JSON_CONTENT_TYPE = "text/plain"; // AJAX輸出 protected String ajax(String content, String contentType) { try { HttpServletResponse response = initResponse(contentType); response.getWriter().write(content); response.getWriter().flush(); } catch (IOException e) { e.printStackTrace(); } return NONE; } // 根據文本內容輸出AJAX protected String ajax(String text) { return ajax(text, HEADER_TEXT_CONTENT_TYPE); } // 根據操作狀態輸出AJAX protected String ajax(Status status) { HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE); Map<String, String> jsonMap = new HashMap<String, String>(); jsonMap.put(STATUS_PARAMETER_NAME, status.toString()); JsonUtil.toJson(response, jsonMap); return NONE; } // 根據操作狀態、消息內容輸出AJAX protected String ajax(Status status, String message) { HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE); Map<String, String> jsonMap = new HashMap<String, String>(); jsonMap.put(STATUS_PARAMETER_NAME, status.toString()); jsonMap.put(MESSAGE_PARAMETER_NAME, message); JsonUtil.toJson(response, jsonMap); return NONE; } // 根據Object輸出AJAX protected String ajax(Object object) { HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE); JsonUtil.toJson(response, object); return NONE; } // 根據boolean狀態輸出AJAX protected String ajax(boolean booleanStatus) { HttpServletResponse response = initResponse(HEADER_JSON_CONTENT_TYPE); Map<String, Object> jsonMap = new HashMap<String, Object>(); jsonMap.put(STATUS_PARAMETER_NAME, booleanStatus); JsonUtil.toJson(response, jsonMap); return NONE; } private HttpServletResponse initResponse(String contentType) { HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType(contentType + ";charset=" + HEADER_ENCODING); if (HEADER_NO_CACHE) { response.setDateHeader("Expires", 1L); response.addHeader("Pragma", "no-cache"); response.setHeader("Cache-Control", "no-cache, no-store, max-age=0"); } return response; }
這樣前台所需要的數據,就從庫裡取出,並封裝成了對應的Json。
接下來就是前台的實現了,前台需要導入的js和css如下:
<link rel="stylesheet" href="${base}/template/ztree/css/demo.css" type="text/css"> <link rel="stylesheet" href="${base}/template/ztree/css/zTreeStyle/zTreeStyle.css" type="text/css"> <script type="text/javascript" src="${base}/template/ztree/js/jquery.ztree.core.js"></script>
這裡只有demo.css是自己添加的,其他都是官方制定的,demo.css是將官方的demo用到的css修改的,如下(這裡有冗余樣式沒有刪除掉);
div.content_wrap {width: 400px;} div.content_wrap div.left{float: left;} div.content_wrap div.right{float: right;width: 340px;} div.zTreeDemoBackground {text-align:left;} ul.ztree {margin-top: 10px;border: 1px solid #617775;background: #fefefe;width:220px;height:360px;overflow-y:scroll;overflow-x:auto;} ul.log {border: 1px solid #617775;background: #f0f6e4;width:300px;height:170px;overflow: hidden;} ul.log.small {height:45px;} ul.log li {color: #666666;list-style: none;padding-left: 10px;} ul.log li.dark {background-color: #E3E3E3;} /* ruler */ div.ruler {height:20px; width:220px; background-color:#f0f6e4;border: 1px solid #333; margin-bottom: 5px; cursor: pointer} div.ruler div.cursor {height:20px; width:30px; background-color:#3C6E31; color:white; text-align: right; padding-right: 5px; cursor: pointer}
然後,就是對應的下拉框:
<div class="content_wrap"> <div class="zTreeDemoBackground left"> <input id="citySel" class="formText" type="text" onclick="showMenu(); return false;" readonly value="" style="width:150px;"/> <input id="treeids" type="hidden" name="goods.goodsCategory.id" > <input type="button" onclick="showMenu();" value="∨"> </div> </div> 8<div id="menuContent" class="menuContent" style="display:none; position: absolute;"> <ul id="treeDemo" class="ztree" style="margin-top:0;"></ul> </div>
這裡有一個隱藏的文本框用來存放下拉框選擇內容對應的id。
對應的腳本如下:
<SCRIPT type="text/javascript"> var setting = { view: { dblClickExpand: false }, data: { simpleData: { enable: true } }, callback: { onClick: onClick }, view: { // 不顯示對應的圖標 showIcon: false } }; function onClick(e, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj("treeDemo"), nodes = zTree.getSelectedNodes(), v = ""; ids = ""; nodes.sort(function compare(a,b){return a.id-b.id;}); for (var i=0, l=nodes.length; i<l; i++) { v += nodes[i].name + ","; ids += nodes[i].id + ","; } if (v.length > 0 ) v = v.substring(0, v.length-1); var cityObj = $("#citySel"); cityObj.attr("value", v); // 將選中的id放到隱藏的文本域中 if (ids.length > 0 ) ids = ids.substring(0, ids.length-1); var treeids = $("#treeids"); treeids.attr("value", ids); } function showMenu() { var cityObj = $("#citySel"); var cityOffset = $("#citySel").offset(); $("#menuContent").css({left:cityOffset.left + "px", top:cityOffset.top + cityObj.outerHeight() + "px"}).slideDown("fast"); $("body").bind("mousedown", onBodyDown); } function hideMenu() { $("#menuContent").fadeOut("fast"); $("body").unbind("mousedown", onBodyDown); } function onBodyDown(event) { if (!(event.target.id == "menuBtn" || event.target.id == "menuContent" || $(event.target).parents("#menuContent").length>0)) { hideMenu(); } } var zNodes ; $(document).ready(function(){ // 加載數據 $.ajax({ async : false, cache:false, type: 'POST', dataType : 'json', url: '${base}/admin/goods!getGoodsCategoryTreeJson.action', error: function () { alert('請求失敗'); }, success:function(data){ zNodes = data; } }); $.fn.zTree.init($("#treeDemo"), setting, zNodes); }); </SCRIPT>
這樣,一個下拉框就做完了。
如下圖所示:
如果,需要在修改頁面中回寫相應的下拉列表數據,添加如下的腳本:
<script type="text/javascript"> $(document).ready(function(){ if ("${goods.goodsCategory.id}"!="") { var treeObj = $.fn.zTree.getZTreeObj("treeDemo"); var node = treeObj.getNodeByParam("id", "${goods.goodsCategory.id}" , null); treeObj.selectNode(node,false , false); onClick(event,"${goods.goodsCategory.id}",node,true); } }); </script>
以上就是本文的全部內容,希望對大家學習zTree插件有所幫助。