基於Layui的多級聯動時間控件(laydate開始時間和結束時間聯動,含日期控制)
0 引言
近期,跟隨團隊做項目,項目前端基於Layui框架開發,(插一句使用框架真的比自己寫原生HTML+CSS舒服多了),項目中有一個時間控件的需求,一般項目常用的就是選取一個時間日期就完了,但是這個項目的時間控件需要考慮開始時間和結束時間的相互聯動,即多個(本文是三個時間控件-日期控件、開始時間控件及結束時間控件相互限制,層級聯動)。
1 示例
比如,當我選擇了當前日期爲當天後,開始時間控件的可選時間節點必須是當前時間之後(即當前時間之前不可選了),選取開始時間後需要限制結束時間必須在開始時間之後,本項目需求是結束時間必須必開始時間晚十分鐘。
2 需求細化
(1)開始時間和結束時間每天可選的最大最小時間爲凌晨1點-23點;
(2)當選取的時間和當天時,開始時間自動調整之後當前時間之後的時間節點可選;
(3)結束時間必須在開始時間後10分鐘;
(4)開始和結束時間無需選擇秒,分鐘單位間隔爲10;
(5)當出現開始時間比當天系統時間更小時或結束時間比開始時間更小時需要錯誤提示;
Tips:以上需求大部分LayUI的時間控件均無法直接滿足,需要通過邏輯設計或修改CSS達到
3 實現
3.1 引入基本控件(laydate)
Html代碼:
<div class="layui-form-item layui-row layui-col-space10">
<div class="layui-col-xs4">
<label for="mDate" class="layui-form-label">會議日期</label>
<div class="layui-input-block">
<input type="text" class="layui-input" name="mDate" id="mDate"
autocomplete="off" placeholder="請選擇會議日期" lay-verify="required|date">
</div>
</div>
<div class="layui-col-xs4">
<label class="layui-form-label" for="mDateStartTime" >開始時間</label>
<div class="layui-input-block">
<input class="layui-input" placeholder="選擇開始時間" name="mDateStartTime" id="mDateStartTime"
autocomplete="off" lay-verify="required|time" >
</div>
</div>
<div class="layui-col-xs4">
<label class="layui-form-label" for="mDateEndTime">預計結束時間</label>
<div class="layui-input-block">
<input class="layui-input" placeholder="請選擇預計結束時間" name="mDateEndTime" id="mDateEndTime"
autocomplete="off" lay-verify="required|time">
</div>
</div>
</div>
Js處理
(Tips:這部分可以參考LayUI文檔即可實現,這裏只做演示,詳細還是見下面完整代碼,https://www.layui.com/doc/modules/laydate.html)
<script src="laydate.js"></script> //導入laydate.js腳本響應處理
laydate.render({
elem: '# mDate ' //指定要響應的時間控件id – mDate、mDateStartTime、mDateEndTime
});
3.2 實現LayUI分鐘間隔10分鐘且不可點擊秒數
這部分,筆者嘗試去查閱了文檔,原本以爲,layui文檔這個需求會提供配置,找了一圈最後還是沒有找到,最後只好自己通過“粗暴”的做法實現了這個需求。做法,通過CSS樣式的nth-child強制隱藏秒數部分,間隔10分鐘也是一樣的。
代碼如下:(時分寬度各佔50%,即把整個控件喫滿,同時秒的li設置爲隱藏)
<style type="text/css">
.laydate-time-list > li:nth-child(1){
width: 50%;
}
.laydate-time-list > li:nth-child(2){
width: 50%;
}
.laydate-time-list > li:nth-child(2) > ol > li{
display: none;// 處理間隔10分鐘
}
.laydate-time-list > li:nth-child(2) > ol > li:nth-child(10n+1){
display: block; // 處理間隔10分鐘,每10的整分數就顯示
}
.laydate-time-list > li:nth-child(3){
display: none !important;
}
.error-tips{
border: solid 1px red;
}
</style>
3.3 日期和開始結束時間範圍限制
日期可選範圍:半個月之內可選
開始結束時間:1-23點
<script src="${pageContext.request.contextPath}/UIAdmin/layui/layui.js"></script>
<script>
layui.config({
base: '${pageContext.request.contextPath}/UIAdmin/' //靜態資源所在路徑
}).extend({
index: 'lib/index', //主入口模塊
comm: 'lib/CommonFunction',
pullDwonPartTree:'lib/extend/pullDwonPartTree'
}).use(['index', 'comm', 'jquery', 'layer', 'form','laydate'], function () {
var $ = layui.jquery
, form = layui.form
, laydate = layui.laydate
,layer=layui.layer
, comm = layui.comm;
// 限制開始結束時間最大最小值
var min = "01:00:00",
max = "24:00:00";
var selectday = laydate.render({
elem: '#mDate' //指定元素
,min: 0//7天前
,max: 15 //15天后
,trigger: 'click'
,done: function(value, date){}
});
// 開始時間配置
var start =laydate.render({
elem: '#mDateStartTime' //指定元素
,type: 'time'
,trigger: 'click'
,format: 'HH:mm:ss'
,min: min
,max: max
,btns: ['clear', 'confirm']
,done: function(value, date){}
});
// 結束時間
var end = laydate.render({
elem: '#mDateEndTime' //指定元素
,type: 'time'
,trigger: 'click'
,format: 'HH:mm:ss'
,min: min
,max: max
,btns: ['clear', 'confirm']
,done: function(value, date){}
});
(1)日期如爲當天,則開始時間必須爲大於系統當前時刻;
(2)結束時間必須大於開始10分鐘以後;
(3)如果上述不滿足,則需要錯誤提示,即在控件上添加紅色標識;
處理邏輯上,選擇了日期就要判斷當前日期是否當天,如果是當天則需要限定開始時間的可選範圍;選取開始時間後,就同樣需要限制結束時間的可選範圍;同理,如果先選擇了結束時間,那麼他要反向限制開始時間。這些操作均在layui提供的時間中間中的done:function(){}中,即控件選取後要執行的動作,而我們限制範圍本來就是通過min、max值控制的,這裏要注意的是,因爲要知道我們要控制的是哪個控件,所以每一個控件都定義成了變量,如開始時間 var start =laydate.render({ …})
<script src="${pageContext.request.contextPath}/UIAdmin/layui/layui.js"></script>
<script>
layui.config({
base: '${pageContext.request.contextPath}/UIAdmin/' //靜態資源所在路徑
}).extend({
index: 'lib/index', //主入口模塊
comm: 'lib/CommonFunction',
pullDwonPartTree:'lib/extend/pullDwonPartTree'
}).use(['index', 'comm', 'jquery', 'layer', 'form','laydate'], function () {
var $ = layui.jquery
, form = layui.form
, laydate = layui.laydate
,layer=layui.layer
, comm = layui.comm;
// 限制開始結束時間最大最小值
var min = "01:00:00",
max = "24:00:00";
var selectday = laydate.render({
elem: '#mDate' //指定元素
,min: 0//7天前
,max: 15 //15天后
,trigger: 'click'
,done: function(value, date){
var isRealTime = true;
var curDate = new Date();
var month = curDate.getMonth()+1;
month = month > 9 ? month : '0' + month;
var day = curDate.getDate();
day = day > 9 ? day : '0' + day;
var h = curDate.getHours();
var sh = h > 9 ? h : '0' + h;
var mi = curDate.getMinutes();
var smi = mi > 9 ? mi : '0' + mi;
var today = curDate.getFullYear()+ '-' + month + '-' + day;
// 判斷當前選時間是否爲當天
if (today==value){
//處理小時
if (h >= 1){
// 當天可選最小時間爲當前時間
start.config.min.hours = h;
// start.config.min.minutes = mi;
}
// 結合開始時間 判斷選擇的時間是否比當前時間
if ($("#mDateStartTime").val()!=""|| $("#mDateEndTime").val()!=""){
var startTime = $("#mDateStartTime").val();
var endTime = $("#mDateEndTime").val();
var systemTime = sh+":"+smi+":"+"00";
if (endTime!="" && endTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約時間必須大於當前時刻", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDateEndTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
}else if(startTime!="" && startTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約開始時間必須大於當前時刻", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
}
}
}else{
start.config.min.hours = 1;
}
if (isRealTime){
$("#mDateStartTime").removeClass("error-tips");
$("#mDateEndTime").removeClass("error-tips");
$("#mDate").removeClass("error-tips");
}
}
});
// 開始時間
var start =laydate.render({
elem: '#mDateStartTime' //指定元素
,type: 'time'
,trigger: 'click'
,format: 'HH:mm:ss'
,min: min
,max: max
,btns: ['clear', 'confirm']
,done: function(value, date){
var selStartH = date.hours;
var selStartM = date.minutes;
// 判斷當前選擇時間是否超過系統時間
var isRealTime = true;
var selectDay = $("#mDate").val();
var startTime = value;
var endTime = $("#mDateEndTime").val();
if (selectDay !=""){
var curDate = new Date();
var month = curDate.getMonth()+1;
month = month > 9 ? month : '0' + month;
var day = curDate.getDate();
day = day > 9 ? day : '0' + day;
var h = curDate.getHours();
var sh = h > 9 ? h : '0' + h;
// 處理4小時內
var ah = curDate.getHours()+4;
var sah = ah > 9 ? ah : '0' + ah;
var mi = curDate.getMinutes();
var smi = mi > 9 ? mi : '0' + mi;
var today = curDate.getFullYear()+ '-' + month + '-' + day;
if (today==selectDay){
var systemTime = sh+":"+smi+":"+"00";
var foursystemTime = sah+":"+smi+":"+"00";
if (endTime!="" && endTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約時間必須大於當前時刻", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDateEndTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
// }else if(startTime<=systemTime){
}else if(startTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約開始時間必須大於系統當前時刻!", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
}
}
}
if(endTime!="" && endTime<=startTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約結束時間必須大於開始時間", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDateEndTime").addClass("error-tips");
}
// 開始時間處理完之後 處理結束時間,一個會議時間間隔至少10分鐘,
var endPreM = selStartM+10;
var endPreH = selStartH;
if (50<endPreM && endPreM<=60){
endPreH = selStartH+1;
endPreM = 0;
}
if(60<endPreM){
endPreH = selStartH+1;
endPreM = 10;
}
// 設置結束時間的min max限制值
end.config.min.hours = endPreH;
end.config.min.minutes = endPreM;
// 會場時間衝突提醒
if (isRealTime){
$("#mDateStartTime").removeClass("error-tips");
$("#mDateEndTime").removeClass("error-tips");
$("#mDate").removeClass("error-tips");
}
}
,change: function(value, date, endDate){
var curDate = new Date();
var month = curDate.getMonth()+1;
month = month > 9 ? month : '0' + month;
var day = curDate.getDate();
day = day > 9 ? day : '0' + day;
var h = curDate.getHours();
var sh = h > 9 ? h : '0' + h;
var mi = curDate.getMinutes();
var smi = mi > 9 ? mi : '0' + mi;
var today = curDate.getFullYear()+ '-' + month + '-' + day;
// 根據今天點擊小時數,決定分鐘數,如果是當期小時 則需要根據當前系統分鐘限制
var selectday = $("#mDate").val();
if (selectday==today && date.hours==h){
// 雙擊時間纔會生效
start.config.min.minutes = mi;
}else{
start.config.min.minutes = 0;
}
}
});
// 結束時間
var end = laydate.render({
elem: '#mDateEndTime' //指定元素
,type: 'time'
,trigger: 'click'
,format: 'HH:mm:ss'
,min: min
,max: max
,btns: ['clear', 'confirm']
,done: function(value, date){
// 判斷當前選擇時間是否超過系統時間
var isRealTime = true;
var selectDay = $("#mDate").val();
var startTime = $("#mDateStartTime").val();
var endTime = value;
if (selectDay !=""){
var curDate = new Date();
var month = curDate.getMonth()+1;
month = month > 9 ? month : '0' + month;
var day = curDate.getDate();
day = day > 9 ? day : '0' + day;
var h = curDate.getHours();
var sh = h > 9 ? h : '0' + h;
// 處理4小時內
var ah = curDate.getHours()+4;
var sah = ah > 9 ? ah : '0' + ah;
var mi = curDate.getMinutes();
var smi = mi > 9 ? mi : '0' + mi;
var today = curDate.getFullYear()+ '-' + month + '-' + day;
if (today==selectDay){
var systemTime = sh+":"+smi+":"+"00";
var foursystemTime = sah+":"+smi+":"+"00";
if (endTime!="" && endTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約時間必須大於當前時刻", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDateEndTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
}else if(startTime!="" && startTime<=systemTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約開始時間必須大於系統當前時刻!", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDate").addClass("error-tips");
}
}
}
if(startTime!="" && endTime<=startTime){
isRealTime=false;
layer.msg("會議選擇時間異常!會議預約結束時間必須大於開始時間", function () {
return false;
});
$("#mDateStartTime").addClass("error-tips");
$("#mDateEndTime").addClass("error-tips");
}
// 處理時間限制-先選擇了結束時間,那麼開始時間的最大值應爲結束時間-10
if($("#mDateStartTime").val()==""){
var selStartH = date.hours;
var selStartM = date.minutes;
var endPreM = selStartM-10;
console.log(endPreM);
console.log(selStartH);
var endPreH = selStartH;
if (endPreM<0){
endPreH = selStartH-1;
endPreM = 50;
}
// 設置開始時間的min max限制值
start.config.max.hours = endPreH;
start.config.max.minutes = endPreM;
}
// 會場時間衝突提醒
if (isRealTime){
$("#mDateStartTime").removeClass("error-tips");
$("#mDateEndTime").removeClass("error-tips");
$("#mDate").removeClass("error-tips");
}
}
});
});