标签:
工作需要,使用zTree实现了一个点击显示下拉复选框列表选中项作为查询条件的功能。简单记录下菜鸟级开发历程。
zTree:是一个依靠jQuery实现的多功能树控件。通过简单引用配置就可使用。
具体使用:
(1)、脚本、样式引用
注意:引用顺序,zTree.js一定放最后。
<link rel="stylesheet" href="@Url.Content("~/Scripts/jquery.plugins/zTree/zTreeStyle.css")" type="text/css"> <script src="@Url.Content("~/Scripts/jquery.plugins/zTree/jquery.ztree.core-3.5.js")"></script> <script src="@Url.Content("~/Scripts/jquery.plugins/zTree/jquery.ztree.excheck-3.5.js")"></script> <script src="@Url.Content("~/Scripts/jquery.plugins/jquery.json.js")"></script> <script src="@Url.Content("~/Scripts/jquery.plugins/zTree/zTree.js")"></script>
(2)、前台展示
说明:txt_InfoSource用来展示选中复选框后的数据,DashBoardCheckList为后台查询条件模型传递数据(怎么让txt_InfoSource为模型传递数据?!)。灰色背景为zTree控件展示。
<div style="display:inline-block;"> <div style="display:inline-block;"> <input type="text" id="txt_InfoSource" class="width_130" readonly="readonly" value="@ViewBag.CheckList" /> @Html.HiddenFor(MODEL => MODEL.DashBoardCheckList, new { @id = "DashBoardCheckList", @readonly = "readonly" }) </div> <div id="menuContent" class="menuContent" style="display:none;z-index: 1000; position: absolute; background: #eee;"> <ul id="tree" class="ztree" style=""></ul> </div> </div>
(3)、操作脚本
因为我实现了两个一样的功能,只是数据显示不一样,所以就写了两套zTree
var functionManage = new FunctionManage(); var zTree; $(document).ready(function ($) { functionManage.Init(); }); /// <summary>构造函数 /// <para></para> /// </summary> function FunctionManage() { //当前操作类型: 0= 默认值, 1= 添加新的, 2 = 更新 this.CurOperType = 0; this.CurFunNode = null; //当前选择菜单节点对象 } //**********public methods************************* /// <summary>初始化 /// <para>这是一个详细信息</para> /// </summary> /// <param name="_parameter" type="String">参数说明</param> /// <return></returen> FunctionManage.prototype.Init = function (_parameter) { this._BindEvent(); this.LoadFunctionTree(); } //**********private event methods****************** /// <summary>绑定,注册点击事件 /// <para></para> /// </summary> FunctionManage.prototype._BindEvent = function () { var _this = this $("#txt_InfoSource").click(function () { $("#menuContent").show(); $("body").bind("mousedown", _this.CaseStateOnBodyDown); }); $("#txt_InfoSource2").click(function () { $("#menuContent2").show(); $("body").bind("mousedown", _this.CaseStateOnBodyDown); }); } /// <summary>加载功能树,在这里配置zTree的相关属性、事件,注意:回调事件名必须与官方一致,实现随意。 /// <para></para> /// </summary> FunctionManage.prototype.LoadFunctionTree = function () { var setting = { check: { enable: true }, view: { dblClickExpand: false, showLine: true, selectedMulti: false }, data: { simpleData: { enable: true, idKey: "id", pIdKey: "pId", rootPId: "" } }, callback: { onClick: functionManage.zTreeOnClick , onRightClick: functionManage.OnRightClick , onCheck: functionManage.zTreeOnClick } }; //请求加载数据 $.post("/TrackerGraph/GetModuleNameTreeList", { "ModuleName": $("#txt_InfoSource").val(), CoveredName: $("#txt_InfoSource2").val() }, function (data) { //我的返回数据类型是根据ModuleName和CoveredName返回 json+"="+json. //总感觉这么玩字符串略麻烦,不知有没有简单些的方式?! var array = new Array(); //分割字符串 array = data.split("="); var returnMsg = JSON.parse(array[0]) if (returnMsg.Success) { //给树赋值 $.fn.zTree.init($("#tree"), setting, JSON2.parse(returnMsg.Data)); zTree = $.fn.zTree.getZTreeObj("tree"); } else { alert(returnMsg.Message); } returnMsg = JSON.parse(array[1]) if (returnMsg.Success) { $.fn.zTree.init($("#tree2"), setting, JSON2.parse(returnMsg.Data)); zTree = $.fn.zTree.getZTreeObj("tree2"); } else { alert(returnMsg.Message); } }); } /// <summary>复选框选择事件 /// <para></para> /// </summary> FunctionManage.prototype.zTreeOnClick = function (e, treeId, treeNode) { var zTree = $.fn.zTree.getZTreeObj(treeId), nodes = zTree.getCheckedNodes(true), vName = ""; var statusValue = "", solStatusValue = ""; //主表状态,处理状态值。 for (var i = 0, l = nodes.length; i < l; i++) { if (nodes[i].isParent == false) { //每个节点都有nsme跟value,用起来很方便 statusValue += nodes[i].value + ","; vName += nodes[i].name + ","; } } vName = vName.substr(0, vName.length - 1); //选择节点后,更新前台数据 if (treeId == "tree") { $("#txt_InfoSource").val(vName.toString()); $("#DashBoardCheckList").val(vName.toString()); } if (treeId == "tree2") { $("#txt_InfoSource2").val(vName.toString()); $("#CoveredModelCheckList").val(vName.toString()); } } /// <summary>显示树 /// <para>控件ID</para> /// </summary> FunctionManage.prototype.showMenu = function (controlID) { var cityObj = $("#" + controlID); var cityOffset = $("#" + controlID).offset(); if (controlID == "aInfoSource") { //cityOffset.top + cityObj.outerHeight() $("#menuContent").css({ left: cityOffset.left + "px", top: 60 + "px" }).slideDown("fast"); $("body").bind("mousedown", this.CaseStateOnBodyDown); } if (controlID == "menuStreet") { $("#divStreet").css({ left: cityOffset.left + "px", top: cityOffset.top + cityObj.outerHeight() + "px" }).slideDown("fast"); $("body").bind("mousedown", this.StreetOnBodyDown); } if (controlID == "aInfoSource2") { $("#menuContent2").css({ left: cityOffset.left + "px", top: 60 + "px" }).slideDown("fast"); $("body").bind("mousedown", this.CaseStateOnBodyDown); } if (controlID == "menuStreet2") { $("#divStreet").css({ left: cityOffset.left + "px", top: cityOffset.top + cityObj.outerHeight() + "px" }).slideDown("fast"); $("body").bind("mousedown", this.StreetOnBodyDown); } } /// <summary>隐藏Module Name树列表 /// <para></para> /// </summary> FunctionManage.prototype.CaseStateHideMenu = function () { $("#menuContent").fadeOut("fast"); $("#menuContent2").fadeOut("fast"); $("body").unbind("mousedown", this.CaseStateOnBodyDown); } FunctionManage.prototype.CaseStateOnBodyDown = function (event) { if (!(event.target.id == "txt_InfoSource" || event.target.id == "menuContent" || $(event.target).parents("#menuContent").length > 0 || event.target.id == "txt_InfoSource2" || event.target.id == "menuContent2" || $(event.target).parents("#menuContent2").length > 0 )) { functionManage.CaseStateHideMenu(); } }
引用了上面脚本之后,就成功一半了,剩下的就是后台数据处理了。
(4)、客户端加载数据
a.页面初次加载,直接从数据库读取数据展示出来。否则根据查询条件,显示数据。
b.zTree数据加载
/// <summary> /// 获取zTree节点列表 /// </summary> /// <returns></returns> public string GetModuleNameTreeList(string ModuleName, string CoveredName) { //1)定义根节点对象 JsonTreeItem rootNode = new JsonTreeItem(); JsonTreeItem CoveredrootNode = new JsonTreeItem(); rootNode.id = "0"; rootNode.pId = "0"; rootNode.name = "ModuleName"; rootNode.children = new List<JsonTreeItem>(); rootNode.open = "true"; rootNode.IsChecked = !string.IsNullOrEmpty(ModuleName); CoveredrootNode.id = "0"; CoveredrootNode.pId = "0"; CoveredrootNode.name = "CoveredModuleName"; CoveredrootNode.children = new List<JsonTreeItem>(); CoveredrootNode.open = "true"; CoveredrootNode.IsChecked = !string.IsNullOrEmpty(CoveredName); //2)缓存所有菜单节点数据 var list = (from raw in db.TR_Words where raw.WordType == 11 && raw.ModuleName == "TR" select new { raw.WordName, raw.WordValue }); //3)遍历加载一级根节点 if (list != null) { foreach (var item in list) { bool isChecked = false; if (ModuleName != null && ModuleName.IndexOf(item.WordName) != -1) { isChecked = true; } //定义一级节点,参数参考JsonTreeItem模型中的说明 JsonTreeItem LevelNode1 = new JsonTreeItem("0", rootNode.id, item.WordName, item.WordName.ToString(), "", isChecked, false, "false"); //根节点添加一级节点 rootNode.children.Add(LevelNode1); bool CoveredisChecked = false; if (CoveredName != null && CoveredName.IndexOf(item.WordName) != -1) { CoveredisChecked = true; } //定义一级节点 JsonTreeItem CoveredLevelNode1 = new JsonTreeItem("0", CoveredrootNode.id, item.WordName, item.WordName.ToString(), "", CoveredisChecked, false, "false"); //根节点添加一级节点 CoveredrootNode.children.Add(CoveredLevelNode1); } } string returnJsonValue = GetJson(rootNode); string returnCoveredJsonValue = GetJson(CoveredrootNode); return returnJsonValue + "=" + returnCoveredJsonValue; }
JsonTreeItem模型:
namespace Opentide.DataContracts { /// <summary>Json树对象结构 /// /// </summary> [DataContractAttribute] [Serializable] public class JsonTreeItem { /// <summary> /// treeNode 节点的唯一标识 tId。 /// </summary> [DataMember] public string id { get; set; } ///<summary> /// 节点名称 ///</summary> [DataMember] public string name { get; set; } ///<summary> /// 节点值 ///</summary> [DataMember] public string value { get; set; } ///<summary> /// 父节点id ///</summary> [DataMember] public string pId { get; set; } ///<summary> /// 节点层级 ///</summary> [DataMember] public string level { get; set; } ///<summary> /// 节点的子节点数据集合 ///</summary> [DataMember] public List<JsonTreeItem> children { get; set; } /// <summary> /// 记录 treeNode 节点的 展开 / 折叠 状态。 /// </summary> [DataMember] public string open { get; set; } ///<summary> /// 节点自定义图标的 URL 路径 ///</summary> [DataMember] public string icon { get; set; } ///<summary> /// 节点链接的目标 URL ///</summary> [DataMember] public string url { get; set; } ///<summary> /// 节点链接的目标 URL2 ///</summary> [DataMember] public string url2 { get; set; } ///<summary> /// 是否选中复选框 ///</summary> [DataMember] public bool nocheck { get; set; } ///<summary> /// 是否选中复选框 ///</summary> [DataMember(Name="checked")] public bool IsChecked { get; set; } ///<summary> /// 当前登录用户ID ///</summary> [DataMember] public string UserID { get; set; } ///<summary> /// 菜单排序ID ///</summary> [DataMember] public int SortID { get; set; } ///<summary> /// 菜单状态0-不禁用,1-正常 ///</summary> [DataMember] public int Status { get; set; } public JsonTreeItem() { } /// <summary>构造节点实例信息 /// /// </summary> /// <param name="id">节点ID</param> /// <param name="pid">父节点</param> /// <param name="name">节点名称</param> /// <param name="_value">节点值</param> /// <param name="url">url地址</param> /// <param name="_isChecked">是否选中复选框</param> public JsonTreeItem(string _id, string _pid, string _name, string _value, string _url, bool _isChecked) { this.id = _id; this.pId = _pid; this.name = _name; this.value = _value; this.url = _url; this.IsChecked = _isChecked; } /// <summary>构造节点实例信息 /// /// </summary> /// <param name="id">节点ID</param> /// <param name="pid">父节点</param> /// <param name="name">节点名称</param> /// <param name="_value">节点值</param> /// <param name="_url">url地址</param> /// <param name="_isChecked">是否选中复选框</param> /// <param name="_nocheck">是否隐藏复选框</param> /// <param name="_nocheck">是否打开子节点</param> public JsonTreeItem(string _id, string _pid, string _name, string _value,string _url, bool _isChecked, bool _nocheck,string _open) { this.id = _id; this.pId = _pid; this.name = _name; this.value = _value; this.IsChecked = _isChecked; this.nocheck = _nocheck; this.open = _open; } } }
值得一提的是,在使用linq做动态多条件OR查询的时候使用了Expressions扩展:PredicateExtensions。
namespace Opentide.Common.Extension { /// <summary> /// 构造函数使用True时:单个AND有效,多个AND有效;单个OR无效,多个OR无效;混合时写在AND后的OR有效 /// 构造函数使用False时:单个AND无效,多个AND无效;单个OR有效,多个OR有效;混合时写在OR后面的AND有效 /// </summary> public static class PredicateExtensions { public static Expression<Func<T, bool>> True<T>() { return f => true; } public static Expression<Func<T, bool>> False<T>() { return f => false; } public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) { var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); return Expression.Lambda<Func<T, bool>>(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters); } public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) { var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters); } } } private List<TR_TrackerRaw> GetCoveredModelNameBaseList(TrackerGraphSearch search, List<TR_TrackerRaw> list) { if (search.CoveredModelCheckList != null) { string CoveredModelCheckList = search.CoveredModelCheckList.ToString(); string[] CoveredArray = CoveredModelCheckList.Split(‘,‘); list = GetNeedReceive(list, CoveredArray); } return list; } private static List<TR_TrackerRaw> GetNeedReceive(List<TR_TrackerRaw> list, Array hubID) { IQueryable<TR_TrackerRaw> useList = list.AsQueryable(); try { var predicate = PredicateExtensions.False<TR_TrackerRaw>(); foreach (string h in hubID) { string htemp = h; predicate = predicate.Or(c => c.ModuleName == htemp); } return useList.Where(predicate).ToList(); } catch (Exception ex) { //_log.Error(ex.ToString()); return null; } }
还有很多不足,欢迎大神不吝指教。
最后附上参考博文:
zTree官网:http://www.ztree.me/v3/main.php#_zTreeInfo
linq动态查询:
http://weblogs.asp.net/scottgu/dynamic-linq-part-1-using-the-linq-dynamic-query-library
http://www.cnblogs.com/killuakun/archive/2008/08/03/1259389.html
标签:
原文地址:http://www.cnblogs.com/FlyBKB/p/5052852.html