使用jquery easyui和MVC实现无限级部门的treeview 升降级 重命名 新增等功能。
1、效果预览:
2、Department数据库设计:
Description暂时未用和Deep只是识别了一下深度为0的为root级部门(可以换用ParentId==null识别,Deep虽只是标示了root级别部门但在实现升降时候也做了相应的处理)。
CREATE TABLE [dbo].[Department] ( Id int identity(1,1) NOT NULL, Name nvarchar(50) NOT NULL, [Description] nvarchar(400) NOT NULL, ParentId int NULL, Deep int NOT NULL default(0), ) --主键 ALTER TABLE [dbo].[Department] ADD CONSTRAINT [PK_Department] PRIMARY KEY (Id) --自引用外键 ALTER TABLE [dbo].[Department] ADD CONSTRAINT [FK_Department_ParentId] FOREIGN KEY (ParentId) REFERENCES [dbo].[Department] (Id)
3、数据访问使用的是NHibernate 使用codesmith生成,并加以改造。
默认生成的hbm和model使用起来不是很方便hbm增加一个one-to-many的Departments来获取当前Department下的子部门。
改造后的hbm文件内容如下:
<?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="IMubiao.Data.DomainModels" assembly="IMubiao.Data"> <class name="IMubiao.Data.DomainModels.Department, IMubiao.Data" table="[dbo].[Department]" lazy="true"> <id name="Id" column="[Id]"> <generator class="native" /> </id> <property name="Name" column="[Name]" /> <property name="Description" column="[Description]" /> <property name="Deep" column="[Deep]" /> <many-to-one name="DepartmentMember" column="[ParentId]" class="Department" /> <bag name="Departments" lazy="true" cascade="all-delete-orphan" inverse="true" > <key column="[ParentId]"></key> <one-to-many class="Department"></one-to-many> </bag> <bag name="Hrms" lazy="true" cascade="all-delete-orphan" inverse="true" > <key column="[DepartmentId]"></key> <one-to-many class="Hrm"></one-to-many> </bag> </class> </hibernate-mapping>
对模板生成的model也要进行相应的修改(对应修改的hbm文件进行相应处理)
private
IList<Department> _dep =
new
List<Department>();
[JsonProperty]
public
virtual
IList<Department> Departments
{
get
{
return
_dep; }
set
{
OnDepartmentsChanging();
_dep = value;
OnDepartmentsChanged();
}
}
partial
void
OnDepartmentsChanging();
partial
void
OnDepartmentsChanged();
|
涉及到的view index.aspx(显示效果就是开头的预览图效果)两个easyui-window 做部门降级和新增的容器 代码:
<
div
class
=
"easyui-panel"
title
=
"部门管理"
icon
=
"icon-option"
collapsible
=
"true"
minimizable
=
"true"
maximizable
=
"false"
style
=
"height: 500px; padding: 10px; background: #fafafa;"
>
<
ul
id
=
"department_tree"
style
=
"height: 350px;"
>
</
ul
>
<
div
id
=
"department_tree_menu"
class
=
"easyui-menu"
style
=
"width: 120px;"
>
<
div
onclick
=
"dep_up()"
iconcls
=
"icon-up"
>
升级</
div
>
<
div
onclick
=
"dep_down()"
iconcls
=
"icon-down"
>
降级</
div
>
<
div
class
=
"menu-sep"
>
</
div
>
<
div
onclick
=
"dep_rename()"
iconcls
=
"icon-rename"
>
重命名</
div
>
<
div
class
=
"menu-sep"
>
</
div
>
<
div
onclick
=
"department_add(0)"
iconcls
=
"icon-add"
>
新增子部门</
div
>
</
div
>
<
div
id
=
"show_d_tree"
class
=
"easyui-window"
closed
=
"true"
title
=
"选择上级部门"
iconcls
=
"icon-list"
style
=
"width: 200px; height: 300px; padding: 5px; background: #fafafa;"
>
<
div
class
=
"easyui-layout"
fit
=
"true"
>
<
div
region
=
"center"
border
=
"false"
style
=
"padding: 10px; background: #fff; border: 1px solid #ccc;"
>
<
div
id
=
"load_tree"
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
id
=
"department_add"
class
=
"easyui-window"
closed
=
"true"
title
=
"新增部门"
iconcls
=
"icon-add"
style
=
"width: 300px; height: 200px; padding: 5px; background: #fafafa;"
>
<
div
class
=
"easyui-layout"
fit
=
"true"
>
<
div
region
=
"center"
border
=
"false"
style
=
"padding: 10px; background: #fff; border: 1px solid #ccc;"
>
<
div
>
<
ul
>
<
li
style
=
"list-style-type: none; height: 30px;"
>
<
input
type
=
"hidden"
id
=
"parent_id"
value
=
""
/>
<
label
>
上级部门:</
label
><
label
id
=
"parent_text"
style
=
"color: Green;"
>无</
label
></
li
>
<
li
style
=
"list-style-type: none; height: 30px;"
>
<
label
for
=
"department_name"
>
部门名称:</
label
><
input
type
=
"text"
id
=
"department_name"
/>
</
li
>
<
li
style
=
"list-style-type: none; height: 30px;"
><
a
href
=
"javascript:department_create()"
class
=
"easyui-linkbutton"
icon
=
"icon-save"
>保存</
a
></
li
>
</
ul
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
style
=
"margin: 10px;"
>
<
a
href
=
"javascript:department_add()"
class
=
"easyui-linkbutton"
icon
=
"icon-add"
>新增部门</
a
>
<
a
href
=
"javascript:reload();"
class
=
"easyui-linkbutton"
icon
=
"icon-reload"
>重新加载</
a
>
</
div
>
</
div
>
|
部门降级用到了一个PreDown.aspx的PartialView 代码如下:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<
int
>" %>
<
ul
id
=
"pre_down"
>
</
ul
>
<
li
style
=
"list-style-type: none; margin-top: 5px;"
>
<
label
for
=
"selected"
>
已选择:</
label
><
label
id
=
"selected"
style
=
"color: Green;"
>未选择</
label
></
li
>
<
li
style
=
"list-style-type: none;"
>
<
input
type
=
"hidden"
id
=
"id_transfer"
value="<%=Model %>" />
<
input
type
=
"hidden"
id
=
"selected_id"
/>
<
a
href
=
"javascript:submit_down()"
icon
=
"icon-ok"
class
=
"easyui-linkbutton"
>确认降级</
a
></
li
>
<
script
type
=
"text/javascript"
>
$(function () {
$('#pre_down').tree({
checkbox: false,
url: '<%=Url.Action("PreDownData","Department",new {id=Model}) %>?' + new Date().getTime(),
onClick: function (node) {
$('#selected').text(node.text);
$('#selected_id').val(node.id);
$(this).tree('toggle', node.target);
}
});
});
function submit_down() {
$.post('<%=Url.Action("Down","Department") %>', { id: $('#id_transfer').val(), pid: $('#selected_id').val() }, function () {
$('#show_d_tree').window('close');
$('#department_tree').tree('reload');
});
}
</
script
>
|
效果预览:
部门降级只能降至当前部门上级部门的子部门一下部门,也就是这个原因没有使用easyui tree的拖拽功能去做功能调整。
用到的几个js function:
<script type=
"text/javascript"
>
//初始化部门的tree
$(
function
() {
$(
'#department_tree'
).tree({
animate:
true
,
url:
'<%=Url.Action("DataList","Department") %>'
,
onClick:
function
(node) {
$(
this
).tree(
'toggle'
, node.target);
},
onDblClick:
function
(node) {
$(
'#department_tree'
).tree(
'beginEdit'
, node.target);
},
onAfterEdit:
function
(node) {
$.post(
'<%=Url.Action("Edit","Department") %>'
, { id: node.id, name: node.text });
reload();
},
onContextMenu:
function
(e, node) {
e.preventDefault();
$(
'#department_tree'
).tree(
'select'
, node.target);
$(
'#department_tree_menu'
).menu(
'show'
, {
left: e.pageX,
top: e.pageY
});
}
});
});
//刷新部门树
function
reload() {
$(
'#department_tree'
).tree(
'reload'
);
}
//部门升级
function
dep_up() {
var
node = $(
'#department_tree'
).tree(
'getSelected'
);
$.post(
'<%=Url.Action("UP","Department") %>'
, { id: node.id },
function
() {
$(
'#department_tree'
).tree(
'reload'
);
});
}
//部门降级
function
dep_down() {
var
node = $(
'#department_tree'
).tree(
'getSelected'
);
$(
'#load_tree'
).empty().load(
'<%=Url.Action("PreDown","Department") %>/'
+ node.id,
function
() {
$(
'#show_d_tree'
).window(
'open'
);
});
}
//重命名
function
dep_rename() {
var
node = $(
'#department_tree'
).tree(
'getSelected'
);
$(
'#department_tree'
).tree(
'beginEdit'
, node.target);
}
//新增部门
function
department_add(val) {
if
(val == undefined || val ==
null
) {
$(
'#parent_id'
).val(
''
);
$(
'#parent_text'
).text(
'无'
);
}
else
{
var
node = $(
'#department_tree'
).tree(
'getSelected'
);
$(
'#parent_id'
).val(node.id);
$(
'#parent_text'
).text(node.text);
}
$(
'#department_name'
).val(
''
);
$(
'#department_add'
).window(
'open'
);
}
//新增窗体里保存按钮的提交操作
function
department_create() {
var
pid = $(
'#parent_id'
).val();
var
name = $(
'#department_name'
).val();
name = encodeURIComponent(name);
$.post(
'<%=Url.Action("Create","Department") %>'
, { pid: pid, name: name });
reload();
$(
'#department_add'
).window(
'close'
);
}
</script>
|
DepartmentController Actions说明:
提供无限级tree数据的DataList 内容:
public string DataList(int? id)
{
var
preModel = db.Departments.Where(x => x.Deep == 0);
return
Convert(preModel).ToJson();
}
private List<Models.EUITreeModel> Convert(IQueryable<Department> model)
{
List<Models.EUITreeModel> result =
new
List<Models.EUITreeModel>();
foreach (
var
v
in
model)
{
var
temp =
new
Models.EUITreeModel
{
id = v.Id,
text = v.Name,
attributes = string.Empty,
iconCls = string.Empty,
};
if
(v.Departments.Count > 0)
{
temp.children = Convert(v.Departments.AsQueryable());
}
result.Add(temp);
}
return
result;
}
|
Convert方法做无限级部门的递归,绑定jquery easyui tree data。
对应 jquery easyui tree 的EUITreeModel 属性:
public
class
EUITreeModel
{
public
int
id {
get
;
set
; }
public
string
text {
get
;
set
; }
public
string
iconCls {
get
;
set
; }
public
bool
@
checked
{
get
;
set
; }
public
List<EUITreeModel> children {
get
;
set
; }
public
string
attributes {
get
;
set
; }
}
|
其他一些Action辅助做一些数据的更新和新增工作!