场景描述:某个公司有多个部门并且部门存在子部门,通过一个下拉框选取多个部门,但是如果某个部门的子部门被全部选择,则只取该部门,而忽略子部门。(叶子节点全被选中时,只取父节点)

知识点:ComboTree、一般处理程序、递归、Json

效果如图

数据库表设计:unit_main

unit_id

unit_name

parent_id

desc

部门ID

部门名称

父ID

说明

节点类设计:

 public class Unit
{
public decimal id { get; set; }
public string text { get; set; }
public string state { get; set; }
public List<Unit> children { get; set; }
public Unit ()
{
this.children = new List<Unit>();
this.state = "open";
}
}

处理类设计:

public class UnitComponent
{
ExeceteOralceSqlHelper SqlHelper= new ExeceteOralceSqlHelper();//数据库处理类
public UnitParent GetUnit()
{
Unit rootUnit = new Unit();
rootUnit.id = ;
rootUnit.text = "BO API";
rootUnit.children = GetUnitList();
UnitRecursive(rootUnit.children);
return rootUnit;
} /// <summary>
/// 递归查询部门
/// </summary>
/// <param name="units"></param>
private void UnitRecursive(List<Unit> units)
{
foreach (var item in units)
{
item.children = GetUnitList(item.id);
if (item.children != null && item.children.Count > )
{
item.state = "closed";
UnitRecursive(item.children);
}
}
} /// <summary>
/// 通过parentID获取所有子部门
/// </summary>
/// <param name="parentID">父id</param>
/// <returns>返回Unit集合</returns>
private List<Unit> GetUnitList(decimal parentID)
{
List<Unit> unitLst = new List<Unit>();
string sql = string.Format("select hh.unit_id,hh.unit_name from unit_main hh where hh.parent_id={0}", parentID);
DataTable dt = SqlHelper.ExecuteDataTable(sql);//返回DataTable方法
if (dt != null && dt.Rows.Count > )
{
for (int i = ; i < dt.Rows.Count; i++)
{
Unit dtup = new Unit()
{
id = Convert.ToInt32(dt.Rows[i]["unit_id"]),
text = dt.Rows[i]["unit_name"].ToString()
};
unitLst.Add(dtup);
}
}
return unitLst;
}
}

下面,新建web应用程序-添加-一般处理程序,其中JavaScriptSerializer你可以换为NewtonSoft来处理

public void ProcessRequest(HttpContext context)
{
JavaScriptSerializer js = new JavaScriptSerializer();
context.Response.ContentType = "application/json";
UnitComponent uc = new SynUser.UnitComponent();
var unit = uc.GetUnit();
context.Response.Write("[" + js.Serialize(unit) + "]");
}

现在我们测试一下这个一般处理程序,如果像图片一样返回了结果说明正确:

好了,部门结构的数据准备好了,下开始写前台代码:

新建一个aspx页面,拖一个控件

<asp:TextBox ID="tbUnit" runat="server" Width="280px"></asp:TextBox>

引入相应的js,在script加入代码

$('#tbUnit').combotree({
url: , '/unit.ashx'
cascadeCheck: true,
placeholder: "请选择部门",
method: 'get',
required: true,
multiple: true,
onChange: function (newValue, oldValue) {
computeunit();
},
onLoadSuccess: function (node, data) { }
});

不知你有没有发现我选中的是应用管理服务中心、xiaobo、tech三个节点,但是xiaobo、tech是应用服务中心的叶子节点。需求要求,我们只需获取应用管理服务中心节点,不需要在获取xiaobo、tech。

所有要通过js遍历tree来获取我们想要的节点,computerunit方法是我们想要的。

思路为:递归获取被选的子节点,然后与所选的节点作差集,最后的得到的就是被选的节点(不包括全选的子节点)

    function computeunit() {
var arr = new Array();
var selectstr = $("#tbUnit").combotree("getValues").toString();
var select = selectstr.split(",");
var t = $('#tbUnit').combotree('tree'); // get the tree object
var n = t.tree('getChecked'); // get selected node
unitrecursive(t, n, arr);
alert(subtraction(select, arr).join(","));
} /*计算数组差集
**返回结果数组
*/
function subtraction(arr1, arr2) {
var res = [];
for (var i = 0; i < arr1.length; i++) {
var flag = true;
for (var j = 0; j < arr2.length; j++) {
if (arr2[j] == arr1[i]) {
flag = false;
}
}
if (flag) {
res.push(arr1[i]);
}
}
return res;
} /*获取被选父节点的子项目
**返回结果arr里
*/
function unitrecursive(t, nodes, arr) {
for (var i = 0; i < nodes.length; i++) {
if (!t.tree('isLeaf', nodes[i].target)) {
var nn = t.tree('getChildren', nodes[i].target);
for (var j = 0; j < nn.length; j++) {
arr.push(nn[j].id);
}
unitrecursive(t, nn, arr);
}
}
}

转载请标明出处

最新文章

  1. ACM/ICPC 之 网络流入门-EK算法(参考模板)(POJ1273)
  2. JDBC编程
  3. 通过href简单实现单击a链接跳转到页面指定位置
  4. 论文阅读(Zhuoyao Zhong——【aixiv2016】DeepText A Unified Framework for Text Proposal Generation and Text Detection in Natural Images)
  5. Python中的元组(tuple)、列表(list)、字典(dict)
  6. 安装包制作工具 SetupFactory使用2 API清单
  7. stm32f系列单片机startup_stm32fxxx.s文件说明(转)
  8. [译] TypeScript入门指南(JavaScript的超集)
  9. python学习第七天
  10. scala学习笔记:高阶函数
  11. digitalocean注册验证账户、激活账号教程
  12. Redis进阶实践之九 独立封装的RedisClient客户端工具类
  13. 前台js接收后台的json数据
  14. 【数学建模】day04-插值与拟合
  15. tcpdump抓包具体分析
  16. 一步步实现windows版ijkplayer系列文章之二——Ijkplayer播放器源码分析之音视频输出——视频篇
  17. 嵌入式开发之hi3519---fifo ringbuffer
  18. Java英文单词Java基础常见英语词汇
  19. SQL语句的执行过程
  20. 关于3d打印

热门文章

  1. hdu1024 Max Sum Plus Plus[降维优化好题(貌似以后可以不用单调队列了)]
  2. SRC常见WEB漏洞系列之HTTP-HOST头攻击
  3. Linux系统内核main函数执行之前
  4. IE各浏览器HACK
  5. 最小费用流判负环消圈算法(poj2175)
  6. Scikit Learn安装教程
  7. 解决IE7下scroll的bug
  8. Mac下通过远程桌面向Windows发送Ctrl+Alt+Delete
  9. 云备份厂商Rubrik再获2.61亿美元融资,估值高达33亿美元 转自中国存储网
  10. django2.0集成xadmin0.6报错集锦