基于redips-drag-min.js拖动排课功能
最近在做一个功能,大致是,老师提交自己想要上的课和时间,然后管理员进行排课,每个课程在同一时间段可以有多个老师,老师需要排优先级,学生预约课程时,按老师优先级顺序进行确认上课。
开始的时候给客户做了一个勾选进行排课的,但是客户为了漂亮,刀架在脖子上非要拖动排课,于是只能勉为其难做了。废话不多说,开始阐述实现。
本功能主要用到一个第三方js,官方地址为:https://www.redips.net,大家可以进官网下载样例。
遇到的问题
- html中div包裹样式一定要按规定格式,其中id="redips-drag"的div包含了目标区域的table和拖动区域的table,需要拖动的div上边需要加上class=“redips-drag”,不能拖动的div上边加上class=“redips-mark”
<div class="row">
<div id="main_container">
<div id="redips-drag">
<!-- 课表 -->
<div id="weekTemplateDetail">
<div class="dayTemplateDetail" id="dayTemplateDetail">
<table id="templateTable" class="courseDetail">
</table>
</div>
</div>
<!-- 可预约信息 -->
<div id="lecturerSubmitInfoDetails">
<div id="showDetail_div">
<table id="table1" class="table submitInfoTable">
<c:choose>
<c:when test="${not empty page.list }">
<c:set var="temp" value="0"></c:set>
<c:set var="brCount" value="4"></c:set>
<c:choose>
<c:when test="${page.list.size()%brCount == 0}">
<c:set var="end" value="${page.list.size()/brCount-1}"></c:set>
</c:when>
<c:otherwise>
<c:set var="end" value="${page.list.size()/brCount}"></c:set>
</c:otherwise>
</c:choose>
<c:forEach begin="0" end="${end}">
<tr>
<c:set var="num" value="0"></c:set>
<c:forEach var="item" begin="${temp }" end="${temp+brCount-1 }" items="${page.list}">
<td class="redips-mark">
<div class="redips-drag submitInfoDetail" id="${item.id }" data-timeState="${item.timeState }" data-timeZone="${item.timeZone }"
data-lecturerId="${item.lecturerId }" data-itemId="${item.itemId }">
<span>${item.lecturerName }(${fns:getDictLabel(item.pattern,'consulting_type','')})</span></br>
<span>${item.itemName }</span></br>
<span>${item.timeZoneStr }</span>
</div>
</td>
<c:set var="num" value="${num+1 }"></c:set>
</c:forEach>
<!-- 如果最后一行数据没填满,则补充空td -->
<c:if test="${num<brCount }">
<c:forEach begin="1" end="${brCount-num }">
<td class="redips-mark"></td>
</c:forEach>
</c:if>
<c:set var="temp" value="${temp+brCount }"></c:set>
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<td colspan="1"><span>暂无没有可预约信息</span></td>
</tr>
</c:otherwise>
</c:choose>
</table>
<div class="row">
${page}
</div>
</div>
</div>
</div>
</div>
- 在做的过程中出现了一个问题,能拖动相关课程信息,但是却放不到具体时间段上,由于本人是做java开发的,对html和js理解不深,一直以为是html写的有问题,后来在官网上找到问题的原因是在css上边,需要将id="redips-drag"的div设置 display=“table”
#redips-drag {
display: table;
width: 100%;
}
- 几个主要的js方法
'use strict';
let redips = {}, // redips container
pos = {}, // initial positions of DIV elements
rd = REDIPS.drag; // reference to the REDIPS.drag lib
// redips initialization
redips.init = function () {
// 初始化
rd.init();
rd.shift.animation = true;
redips.startPositions();
rd.dropMode = 'multiple';
// 放下之前做的事件处理,需要验证是否符合时间段等,给出提示
rd.event.droppedBefore = function(targetCell){
// 比对信息,是否可以放到此处
var re = checkCanDrop(rd, targetCell);
console.log("re="+re);
if (!re) {
return false;
}
return confirm('确定即进行预约信息设置,确定进行此操作吗?');
}
// 放下之后进行的操作
rd.event.dropped = function(targetCell){
// ajax 保存操作
var re = dragAjaxSave(rd);
console.log("re="+re);
// 保存完毕刷新页面左侧table内容
//initTemplate();
}
// 双击进行删除
rd.event.dblClicked = function(){
confirmx('确定要删除这条数据吗?', function(){
if(isParent(rd.obj.id, '')){
console.log("执行了删除");
deleteTemplate(rd);
}else{
console.log("没有执行删除");
}
})
}
rd.event.deleted = function(){
}
};
// 样例中带的不用修改,主要用于获取操作div
redips.startPositions = function () {
let divs, id, i, position;
divs = document.getElementById('redips-drag').getElementsByTagName('div');
for (i = 0; i < divs.length; i++) {
id = divs[i].id;
if (id) {
position = rd.getPosition(divs[i]);
if (position.length > 0) {
pos[id] = position;
}
}
}
};
redips.toggleAnimation = function (chk) {
rd.shift.animation = chk.checked;
};
// add onload event listener
if (window.addEventListener) {
window.addEventListener('load', redips.init, false);
}
else if (window.attachEvent) {
window.attachEvent('onload', redips.init);
}
- 由于这个页面没有用到iframe进行布局,左边和右边的table在同一个页面上,然而左边和右边表格都涉及到了刷新的问题,刷新问题采取的方法是ajax带参发送请求,然后后端拼接html代码,然后前端进行table替换刷新
下面是完成之后的页面图:
补充
测试中出现的问题及修改
问题: 由于左侧table比较长,页面出现了上下滚动条,当页面向上滚动后,右侧table会出现部分内容遮挡,不利于操作,于是需要将右侧css甚至为position:fixed;一开始由于右侧table的div嵌套层数太多,将最外侧div设置为position:fixed,导致页面向上滚动后拖动右侧小方块鼠标位置和小方块位置不在一个位置
解决:经过对js一番测试发现calculateCells() 方法非常重要,它是计算拖动元素的关键方法,其中,标红位置的代码很关键,意思是先检测右侧table的position样式是否是fixed,不是的话就检测其父元素样式是否是fixed,因为这里只检测一级父元素,而我HTML中嵌套了三级div,而且fixed样式放在了最外边的div上,所以出现了这种情况,修改html之后效果达到了
遗留问题:如果在rd.event.dropped 函数中,即执行保存操作,也执行刷新操作时,会出现刷新出来的数据不显示当前保存的那一条信息,再次手动刷新时才会显示,希望有懂的小伙伴赐教,不胜感激。