项目场景
使用第三方插件制作层级分明的文件目录,并实现跳转,修改文件名,删除文件,添加新文件的功能。
一、Ztree介绍
1.Ztree是什么?
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。zTree 是开源免费的软件(MIT 许可证)。
2.为什么用Ztree?
- 采用了 延迟加载 技术,上万节点轻松加载,即使在 IE6 下也能基本做到秒杀。
- 兼容 IE、FireFox、Chrome、Opera、Safari 等浏览器。
- 支持 JSON 数据。
- 支持静态 和 Ajax 异步加载节点数据。
- 支持任意更换皮肤 / 自定义图标(依靠css)。
- 支持极其灵活的 checkbox 或 radio 选择功能。
- 提供多种事件响应回调。
- 灵活的编辑(增/删/改/查)功能,可随意拖拽节点,还可以多节点拖拽哟。
- 在一个页面内可同时生成多个Tree 实例。
- 简单的参数配置实现灵活多变的功能。
二、使用步骤
1.下载文件
将zTree v3.x 相关的 js、css、img 文件分别放置到相应目录,并且保证相对路径正确。
在GitHub下载地址:GitHub - zTree/zTree_v3: jQuery Tree Plugin
在gitee下载地址:zTree_v3: jQuery 树插件 zTree v3 系列
1.引入文件
将下载的文件放入到项目中,并替换为自己相应的目录。
<link rel="stylesheet" href="./plugins/zTree/css/demo.css" type="text/css">
<link rel="stylesheet" href="./plugins/zTree/css/zTreeStyle/zTreeStyle.css"type="text/css">
<script type="text/javascript" src="./plugins/zTree/js/jquery.js"></script>
<script type="text/javascript" src="./plugins/zTree/js/jquery.ztree.core.js"></script>
<script type="text/javascript" src="./plugins/zTree/js/jquery.ztree.excheck.js"></script>
<script type="text/javascript" src="./plugins/zTree/js/jquery.ztree.exedit.js"></script>
2.设置容器
<style>
#container{
overflow-y: scroll;
width: 20%;height: 750px;
border: 1px solid #E1E1E1;
float: left;
background-image: url("./plugins/zTree/img/1.png");
background-repeat: no-repeat;
background-size:90% 70%;
background-position: 50% 100%;
}
</style>
<div id="container">
<!--layui框架的固定块-->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
<legend style="margin-left: -30%">文件目录</legend>
</fieldset>
<!--Ztree插件的容器-->
<ul id="treeDemo" class="ztree"></ul>
</div>
3.核心配置
前端js配置:
因为项目需求为无限级文件夹目录,所以不能一次将数据全部取出展示(防止数据量过大,加载缓慢),因此采用异步加载的方式,每当点击节点时加载该节点的下级目录。
下面是异步加载的重点,在setting中配置该项参数:
//异步加载 async: { //是否开启异步加载,默认为false enable: true, //Ajax获取数据的URL地址 url: "{url:/document_revision/ztree_ajax}", //请求方式,默认为post type: "get", //设置id属性为自动提交的参数 //假设 异步加载 父节点(node = {id:1, name:"test"}) 的子节点时,将提交参数 id=1 autoParam: ["id"] },
<script type="text/javascript">
$(function () {
let zTreeObj;
//此处根据自己需要进行配置
let setting ={
edit: {
enable: true,
removeTitle: "删除文件",
renameTitle: "编辑名称"
},
//异步加载
async: {
enable: true,
url: "{url:/document_revision/ztree_ajax}",
type: "get",
autoParam: ["id"]
},
data: {
simpleData: {
enable: true,
idKey: "id",
pIdKey: "pid",
rootPId: 0
},
key: {
url:"nourl"
}
},
view: {
//添加文件夹
addHoverDom: addHoverDom,
//隐藏图标
removeHoverDom: removeHoverDom,
selectedMulti: false,
},
callback: {
//单击节点时触发
onClick: zTreeOnClick,
//移除前
beforeRemove: beforeRemove,
//重命名前
beforeRename: beforeRename,
},
};
zTreeObj=$.fn.zTree.init($("#treeDemo"),setting);
//添加新的节点(新建文件夹)
function addHoverDom(treeId, treeNode) {
const sObj = $("#" + treeNode.tId + "_span");
if (treeNode.editNameFlag || $("#addBtn_" + treeNode.tId).length > 0) return;
const addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='添加文件' onfocus='this.blur();'></span>";
sObj.after(addStr);
const btn = $("#addBtn_" + treeNode.tId);
if (btn) btn.bind("click", function () {
if (treeNode.name) {
const isParent = treeNode.isParent; //获取父级元素的状态
//选中文件的id
const parentId = treeNode.id;
//选中文件的文件名
//var orgName = treeNode.name;
//新建文件名
//getMilliseconds 方法
//返回 Date 对象中用本地时间表示的毫秒值。
const name = "新建文件夹" + (new Date().getMilliseconds()); //新增节点的名字
$.ajax({
url:"{url:/document_revision/ztree_ajax_add_file}",
type: "post",
data: {
orgName: name,
parentId: parentId
},
success: function (res) {
if (res==='0') {
//接收控制器传回来的数据(新节点的ID和父ID)
zTreeObj.addNodes(treeNode, { pId:parentId, id: res, isParent: isParent, name: name });
alert("文件夹添加成功!")
setInterval(function() {
window.location.reload();
}, 1000);
}
if (res==='1') {
alert("所选文件的类型不是文件夹,不可在其下面建立新文件,请重新创建文件夹后再尝试建立文件。");
}
if (res==='2') {
alert("添加失败,疑似所选文件夹不存在,请刷新页面后重试。");
}
}
});
}
});
}
//鼠标移开时隐藏图标
function removeHoverDom(treeId, treeNode) {
$("#addBtn_" + treeNode.tId).unbind().remove();
}
//删除节点信息
function beforeRemove(treeId, treeNode) {
const file_id = treeNode.id;
$.ajax({
url:"{url:/document_revision/ztree_ajax_del_file}",
type: "post",
data: {
file_id: file_id,
},
success: function(res) {
if (res==='0') {
alert('删除成功!');
setInterval(function() {
window.location.reload();
}, 1000);
}
if (res==='1') {
alert('删除失败,您不是超级管理员,没有权限!');
setInterval(function() {
window.location.reload();
}, 1000);
}
if (res==='2') {
alert('删除失败,该文件下有子文件存在,禁止删除!');
setInterval(function() {
window.location.reload();
}, 1000);
}
if (res==='3') {
alert('删除失败,文件不存在,请刷新页面后重试!');
setInterval(function() {
window.location.reload();
}, 1000);
}
}
});
}
//修改节点信息
function beforeRename(treeId, treeNode, newName) {
if (newName===treeNode.name){
alert('文件名与原文件名相同');
return false;
}
if (newName.length === 0) {
alert('节点名称不能为空');
return false;
} else if (newName.length >= 15) {
alert('节点名称长度不得超出14个字符')
return false;
} else if (/^\s+$/gi.test(newName)) {
alert('节点名称不能存在空格')
return false;
}
const file_id = treeNode.id;
$.ajax({
url:"{url:/document_revision/ztree_ajax_edit_file}",
type: "post",
data: {
file_id: file_id,
orgName: newName,
},
success: function(res) {
if (res === '0') {
alert('修改成功!')
} else {
alert('修改失败!')
}
}
});
}
//点击节点时跳转
function zTreeOnClick(event, treeId, treeNode){
const file_id = treeNode.id;
const file_name = treeNode.name;
const link_str = "./index.php?controller=document_revision&action=open_the_file_directory_repeatedly&folder_id=" + file_id + "&folder_name=" + file_name;
art.dialog.confirm('是否跳转到所选文件夹?',function(){
window.location.href=link_str;
})
}
});
</script>
后台代码片段:
//[文件修改][文件列表][文件目录]echarts树状图数据请求
public function ztree_ajax()
{
//接收父id
$p_id=IFilter::act(IReq::get("id"), "int");
if(empty($p_id)) {
$p_id=0;
}
//定义执行的数据表
$p_db = new IModel("document_list");
//跟据节点传递过来的id查询是否存在
$f_list = $p_db->query("pid='$p_id'",'*','id','asc');
if(!empty($f_list)){
foreach($f_list as $k=>$f_item) {
//在数组arr_list中下一级存储文件名
$arr_list[$k]['name'] = $f_item['file_name'];
$arr_list[$k]['id'] = $f_item['id'];
$is_zk = $p_db->query(" pid={$f_item['id']}");
if(empty($is_zk)){
//是否能展开
$arr_list[$k]['isParent'] = 'false';
}else{
$arr_list[$k]['isParent'] = 'true';
}
}
}
//以json形式返回数据
echo json_encode($arr_list);
}
//[文件修改][文件列表][文件目录]echarts树状图添加文件
public function ztree_ajax_add_file()
{
//接收pid和文件名
$file_name=IFilter::act(IReq::get("orgName"), "post");
$file_pid=IFilter::act(IReq::get("parentId"), "post");
//定义执行的数据表
$db = new IModel("document_list");
//根据接收的pid查询父文件是否存在
$p_list=$db->getObj("id={$file_pid}");
if(!empty($p_list)){
//判断是文件还是文件夹
if($p_list['file_type']=='0'){
$set_date=array(
'file_name'=>$file_name,
'pid'=>$file_pid,
'last_update_time'=>time(),
);
$db->setData($set_date);
//添加数据
$db->add();
echo 0;
}else{
echo 1;
}
}else{
echo 2;
}
}
//[文件修改][文件列表][文件目录]echarts树状图修改文件
public function ztree_ajax_edit_file()
{
//接收id和文件名
$file_name=IFilter::act(IReq::get("orgName"), "post");
$file_id=IFilter::act(IReq::get("file_id"), "post");
//定义执行的数据表
$db = new IModel("document_list");
$db->setData(array("file_name" => $file_name));
$list=$db->update("id='{$file_id}'");
if(!empty($list)){
echo 0;
}else{
echo 1;
}
}
//[文件修改][文件列表][文件目录]echarts树状图删除文件
public function ztree_ajax_del_file()
{
//接收id
$file_id=IFilter::act(IReq::get("file_id"), "post");
//定义执行的数据表
$db = new IModel("document_list");
$p_list=$db->getObj("id={$file_id}");
//判断文件是否存在
if(!empty($p_list)){
$list = $db->query("pid='$file_id'",'*','id','asc');
//判断是否有子文件存在
if (empty($list)){
//判断是否是超级管理员
if($_SESSION['iweb_admin_role_username']=='超级管理员') {
//定义执行的数据表
$db->del("id={$file_id}");
echo 0;
}else {
//不是超级管理员
echo 1;
}
}else{
//文件下有子文件,禁止删除
echo 2;
}
}else{
//文件不存在
echo 3;
}
}
效果图
加载完数据及点击修改文件名的效果图:
总结
使用Ztree开发项目时,重点查看Ztree官方API文档,里面详细记载了各项配置,扩展,核心及其相关说明:
- setting 配置详解
- zTree 方法详解
- treeNode 节点数据详解