Easyui Treegrid 上下移动实现
Easyui Treegrid 上下移动实现
上面是源码地址,由于自己使用Vue,使用源码有问题,故自己又加工了一下
首先是项目框架 点击下移之后 当然上移也是可以的,下面看看代码
function move(o) { // 将此方法加入上下移的按钮事件即可
var n = $("#lineNodes").treegrid("getSelected");
if(n === null){
alert("无法移动!");
return;
}
var selectRow = $('#datagrid-row-r2-2-'+n.id);
/* 注:在Vue中,当切换页面时,row-r后面的数字会累加,
如切换到别的页面再切换回来,会变成row-r3-2,
如果再切换到别的页面再切换回来,会变成row-r4-2
所以在Vue中无法使用这个选择器,而treegrid当点击某一个节点时,
会给该节点添加`datagrid-row-checked datagrid-row-selected`
这两个类,可以根据其中某一个类来替换上面的选择器 */
if(o=="up") {
var pre = selectRow.prev();//此处获得上一节点,关键
// alert(typeof(pre.attr("node-id"))=="undefined");return;
if(typeof(pre.attr("node-id"))=="undefined" || pre.attr("node-id").indexOf("L")==0) {
alert("无法移动!");
}else {//下面写数据库中的排序逻辑
var preId = pre.attr("node-id");
$.post("lineNodes/exchangeOrder.json",{"id1":n.id,"id2":preId},function(data) {
if(data=="true") {
var n2 = $("#lineNodes").treegrid("pop",n.id);
$("#lineNodes").treegrid("insert",{before:preId,data:n2});
$("#lineNodes").treegrid("select",n.id);
}else {
alert("移动过程出现异常,请稍后再试");
}
});
}
}else if(o=="down") {
var next = selectRow.next();//此处获得下一节点,关键
//alert(next.attr("node-id"));return;
if(typeof(next.attr("node-id"))=="undefined" || next.attr("node-id").indexOf("L")==0) {
alert("无法移动!")
}else {
var nextId = next.attr("node-id");
$.post("lineNodes/exchangeOrder.json",{"id1":n.id,"id2":nextId},function(data) {
if(data=="true") {
var n2 = $("#lineNodes").treegrid("pop",nextId);
$("#lineNodes").treegrid("insert",{before:n.id,data:n2})
}else {
alert("移动过程出现异常,请稍后再试");
}
});
}
}
}
操作就是选中某行记录点击上下移按钮,关键代码:
var n2 = $("#lineNodes").treegrid("pop",nextId);
$("#lineNodes").treegrid("insert",{before:n.id,data:n2})
先把当前选中行弹出来再插入到某行前面,如果是上移就插入到上条记录前面,如果是下移就将下一行插入到当前选中行前面,获取上、下行代码:
var next = selectRow.prev();
var next = selectRow.next();
注意取不到会是null的判断
自己提取出来的
基于Vue点击某一个节点,切换上移、下移按钮是否可点击状态 template:
<el-button type="primary" :disabled="changeUpDisabled" @click="moveUp">上移</el-button>
<el-button type="primary" :disabled="changeDownDisabled" @click="moveDown">下移</el-button>
script:
data () {
return {
changeUpDisabled: true,
changeDownDisabled: true
}
}
let _this = this
$('#schedule_tree').treegrid({
onClickRow: function (node) {
// 节点高亮选择时触发
let selectRow = $('.datagrid-row-selected');
let pre = selectRow.prev(); // 此处获得上一节点,关键
let next = selectRow.next(); // 此处获得下一节点,关键
if (typeof(pre.attr("node-id")) === "undefined" || pre.attr("node-id").indexOf("L") === 0) {
// 由于这里的this指向不是Vue的实例对象,所以在外面将_this指向Vue的实例对象,下同
_this.changeUpDisabled = true
} else {
_this.changeUpDisabled = false
}
if (typeof(next.attr("node-id")) === "undefined" || next.attr("node-id").indexOf("L") === 0) {
_this.changeDownDisabled = true
} else {
_this.changeDownDisabled = false
}
}
})
这样相当于将上移、下移按钮显示状态和实际与后台处理分开来做。只要上移、下移按钮可以点击,在函数moveUp和moveDown中不用再判断了,就可以直接处理
优化
上面代码仍然有问题,当有多个同级的根节点时,所有的根节点都不可以上下移 上图中管理工具-应用和管理工具-权限是同级的根节点,正常情况应该是管理工具-应用不能上移,但可以下移,而且在其下的子节点再创建子节点,也会有问题 企业形象(定制VI)正常应该是可以上下移的,此时只可以上移,而他同级的项目列表只可以下移 优化后代码:
$('#schedule_tree').treegrid({
onClickRow: function (node) {
// 节点高亮选择时触发
let selectRow = $('.datagrid-row-selected');
// 此处获得之前所有同级有属性[node-id]的tr(有可能没有),关键
let pre = selectRow.prevAll('tr[node-id]');
// 此处获得之后所有同级有属性[node-id]的tr(有可能没有),关键
let next = selectRow.nextAll('tr[node-id]');
if (pre.length) {
_this.changeUpDisabled = false
} else {
_this.changeUpDisabled = true
}
if (next.length) {
_this.changeDownDisabled = false
} else {
_this.changeDownDisabled = true
}
}
})
移动问题
现在做上下移的思路:当点击某一个节点时,判断是否可以上下移,如果可以上下移,发送请求进行上下移,成功后重新获取数据渲染Treegrid。但现在有两个问题:
- 上下移成功后,没有继续判断是否可以移动,有时候明明已经到顶端或低端,还显示可以移动
- 移动成功后,当前选中列没有跟着移动。如现在有两列,选中第二列(选中列颜色会变化),上移后,选中列选中的是移动后的第一列。
解决问题
思路:
- 上下移成功后,重新执行上面onClickRow的函数,这需要将函数提取出来,在onClickRow中需要调用,重新获取数据后也需要调用,而且要传递this
- 移动成功后,手动修改选中列,即修改class值
完成移动
// 获取进度填报列表
fetchScheduleList() {
this.loading = true
this.$get(url, {
tenantId: this.tenantId
}).then((res) => {
$('#schedule_tree').treegrid('loadData', res);
// 成功后调用函数判断是否可以上下移
this.changeUpDown(this)
this.loading = false;
}).catch((mes) => {
this.$message.error(mes.message)
this.loading = false;
})
}
/**
* 上下移状态
* @param _this Vue实例对象
*/
changeUpDown(_this) {
let selectRow = $('.datagrid-row-selected');
if (selectRow.length) {
// 此处获得之前所有同级有属性[node-id]的tr(有可能没有),关键
let pre = selectRow.prevAll('tr[node-id]');
// 此处获得之后所有同级有属性[node-id]的tr(有可能没有),关键
let next = selectRow.nextAll('tr[node-id]');
_this.changeUpDisabled = pre.length < 1
_this.changeDownDisabled = next.length < 1
} else {
_this.changeUpDisabled = _this.changeDownDisabled = true;
}
},
moveUp() {
let selectRow = $('.datagrid-row-selected');
let scheduleId, replaceId
if (selectRow.length) {
scheduleId = selectRow[0].id.substring(selectRow[0].id.lastIndexOf('-') + 1)
let pre = selectRow.prevAll('tr[node-id]');
if (pre.length) {
replaceId = pre[0].id.substring(pre[0].id.lastIndexOf('-') + 1)
} else {
replaceId = ''
}
}
this.$get(url, {
scheduleId,
replaceId,
moveType: 0
}).then((res) => {
this.fetchScheduleList()
this.$message({
type: 'success',
message: '上移成功'
});
setTimeout(() => {
// 手动修改选中列,如果不延迟,选中列的颜色会先移动,然后需要移动的列才会移动
$('#schedule_tree').treegrid('select', replaceId)
}, 30)
}).catch((error) => {
console.log(error)
});
},
moveDown() {
let selectRow = $('.datagrid-row-selected');
let scheduleId, replaceId
if (selectRow.length) {
scheduleId = selectRow[0].id.substring(selectRow[0].id.lastIndexOf('-') + 1)
let next = selectRow.nextAll('tr[node-id]')
if (next.length) {
replaceId = next[0].id.substring(next[0].id.lastIndexOf('-') + 1)
} else {
replaceId = ''
}
}
this.$get(url, {
scheduleId,
replaceId,
moveType: 1
}).then((res) => {
this.fetchScheduleList()
this.$message({
type: 'success',
message: '下移成功'
});
setTimeout(() => {
$('#schedule_tree').treegrid('select', replaceId)
}, 30)
}).catch((error) => {
console.log(error)
});
}
$('#schedule_tree').treegrid({
onClickRow: function (node) {
_this.changeUpDown(_this)
}
})
treegrid分级问题
- treegrid根据_parentId来分级
- 树子节点的_parentId和其父节点的id对应
- 根节点的_parentId为null
- 一个节点的id和_parentId不能相同