You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

326 lines
13 KiB
JavaScript

1 week ago
/**
* 时间范围滑块选择插件
* 基于 layui.slider 扩展的时间范围选择插件
*
* sliderTime.js License By momo
* V1.0 2021-04-19
*
*
* 使用说明
* 1.sliderTime 基于 layui.slider所以 slider 的配置都得以保留
* 2.range 参数强制为 true
* 3.新增 disabledValue 属性禁止选择时间范围
* 例如[[8:00, 10:00], [14:00, 15:00]]
* 4.新增 disabledText 属性禁止选择时间范围被选中后的提示内容不配置不显示提示
* 例如'{start} - {end} 已占用'支持start和end时间占位符
* 5.新增 getValue 方法返回当前选择的时间段时间格式
* 6.新增 isOccupation 方法返回当前选择的时间段是否包含了禁止选择的时间段
* 7.新增 numToTime 公用方法用于将十进制转为时间格式例如480 08:00
* 8.新增 timeToNum 公用方法用于将时间格式转为十进制例如24:00 1440
*/
layui.define(['slider'], function (exports) {
"use strict";
var MOD_NAME = 'sliderTime',
$ = layui.jquery,
slider = layui.slider;
;
/**
* 外部接口
*/
var SliderTime = {
config: {}
/**
* 核心入口
*/
, render: function (options) {
var object = new Class(options);
return thisSliderTime.call(object);
}
/**
* 数字转时间格式
*/
, numToTime: function (value) {
var hours = Math.floor(value / 60);
var mins = (value - hours * 60);
return (hours < 10 ? "0" + hours : hours) + ":" + (mins < 10 ? "0" + mins : mins);
}
/**
* 时间转数字
*/
, timeToNum: function (value) {
var time = value.split(":");
return time[0] * 60 + parseInt(time[1]);
}
};
/**
* 构造器
*/
var Class = function (options) {
var that = this;
that.config = $.extend({}, SliderTime.config, options);
that.render();
};
/**
* 操作当前实例
*/
var thisSliderTime = function () {
var that = this
, options = that.config;
return {
/**
* 设置时间段
*/
setValue: function (value, index) {
if (index !== 1) {
index = 0;
}
value = SliderTime.timeToNum(value);
var start, end, width,
$wrap = $(options.elem).find('.layui-slider-wrap'),
val = [$wrap.eq(0).data("value"), $wrap.eq(1).data("value")];
if (value === val[0] || value === val[1]) {
// 设置值等于当前最小或最大值,不移动
return;
} else if (value > val[1]) {
// 设置值大于当前最大值,移动后面圆点
val[1] > val[0] ? index = 1 : index = 0;
val[index] = value;
} else if (value < val[0]) {
// 设置值小于当前最小值,移动前面圆点
val[0] < val[1] ? index = 0 : index = 1;
val[index] = value;
} else {
// 设置值间与中间则按照index移动
index === 0 ? val[0] = value : val[1] = value;
}
$wrap.eq(index).data("value", value);
start = (val[0] - options.min) / (options.max - options.min) * 100;
end = (val[1] - options.min) / (options.max - options.min) * 100;
// 设置圆点位置
if ("vertical" === options.type) {
$(options.elem).find('.layui-slider-wrap').eq(index).css("bottom", (index === 0 ? start : end) + '%');
} else {
$(options.elem).find('.layui-slider-wrap').eq(index).css("left", (index === 0 ? start : end) + '%');
}
// 设置滑动位置
width = Math.abs(end - start);
if ("vertical" === options.type) {
$(options.elem).find('.layui-slider-bar').css({
"height": width + '%',
"bottom": (start < end ? start : end) + '%'
});
} else {
$(options.elem).find('.layui-slider-bar').css({
"width": width + '%',
"left": (start < end ? start : end) + '%'
});
}
return;
// return that.slider.setValue(SliderTime.timeToNum(value), index)
}
/**
* 获取选中的时间段
*/
, getValue: function () {
var $wrap = $(options.elem).find('.layui-slider-wrap');
var value = [$wrap.eq(0).data("value"), $wrap.eq(1).data("value")];
//如果前面的圆点超过了后面的圆点值,则调换顺序
if (value[0] > value[1]) {
value.reverse();
}
return [SliderTime.numToTime(value[0]), SliderTime.numToTime(value[1])];
}
/**
* 选择的时间段是否包含被禁止选择的时间段
* 包含返回禁止选择的时间段
* 不包含false
*/
, isOccupation: function () {
if (options.disabledValue) {
var $wrap = $(options.elem).find('.layui-slider-wrap');
var value = [$wrap.eq(0).data("value"), $wrap.eq(1).data("value")];
//如果前面的圆点超过了后面的圆点值,则调换顺序
if (value[0] > value[1]) {
value.reverse();
}
for (var i in options.disabledValue) {
var date = options.disabledValue[i];
var min = SliderTime.timeToNum(date[0]);
var max = SliderTime.timeToNum(date[1]);
if (value[0] > min && value[0] < max
|| value[1] > min && value[1] < max
|| value[0] <= min && value[1] >= max) {
return date;
} else {
that.closeTips(options.elem);
}
}
return false;
} else {
return false;
}
}
, config: options
}
};
/**
* 滑块渲染
* @param options
*/
Class.prototype.render = function () {
var that = this
, options = that.config;
// 是否显示时刻,默认是
options.showstep = options.showstep == false ? false : true;
// 开启滑块的范围拖拽
options.range = true;
// 最小值最小为0=0:00
options.min = options.min == undefined || SliderTime.timeToNum(options.min) < 0 ? 0 : SliderTime.timeToNum(options.min);
// 最大值最大为1440=24*60=24:00
options.max = options.max == undefined || SliderTime.timeToNum(options.max) > 1440 ? 1440 : SliderTime.timeToNum(options.max);
//间隔值不能大于 max
options.step = options.step > options.max ? options.max : options.step;
// 初始值
options.value = typeof (options.value) == 'object' ? options.value : [SliderTime.numToTime(options.min), SliderTime.numToTime(options.min)];
options.value[0] = SliderTime.timeToNum(options.value[0]);
options.value[1] = SliderTime.timeToNum(options.value[1]);
// 初始化
that.slider = slider.render({
elem: options.elem
, type: options.type
, height: options.height
, theme: options.theme
, range: options.range
, showstep: options.showstep
, min: options.min
, max: options.max
, step: options.step
, value: options.value
, disabled: options.disabled
, setTips: function (value) {
value = SliderTime.numToTime(value);
if (options.setTips) {
return options.setTips(value);
} else {
return value;
}
}
, change: function (value) {
if (options.disabledValue && options.disabledText) {
// 当滑动到禁用时间范围时,自动提醒
for (var i in options.disabledValue) {
var date = options.disabledValue[i];
var min = SliderTime.timeToNum(date[0]);
var max = SliderTime.timeToNum(date[1]);
if (value[0] > min && value[0] < max
|| value[1] > min && value[1] < max
|| value[0] <= min && value[1] >= max) {
var disabledText = options.disabledText.replace('{start}', date[0]).replace('{end}', date[1])
that.showTips(options, disabledText)
break;
} else {
that.closeTips(options.elem);
}
}
}
if (options.change) {
options.change(value);
}
}
});
// 扩展元素
$(options.elem).find('.layui-slider')
// 开始结尾刻度时间
.append('<div class="step-start-num">' + SliderTime.numToTime(options.min) + '</div>')
.append('<div class="step-end-num">' + SliderTime.numToTime(options.max) + '</div>')
// 警告提示Tips
.append('<div class="slider-danger-tips"></div>');
if (options.showstep) {
// 开始结尾刻度标识
$(options.elem).find('.layui-slider')
.append('<div class="step-start-wrap"></div>')
.append('<div class="step-end-wrap"></div>');
}
// 定义整点和半点时刻标识
var $steps = $(options.elem).find('.layui-slider .layui-slider-step');
for (var i = 0, num = options.min; num <= options.max && i < $steps.length - 1; i++, num += options.step) {
if (that.numToMins(num) == 0 && i > 0) {
$steps.eq(i - 1).addClass('step-hour');
} else if (that.numToMins(num) == 30) {
$steps.eq(i - 1).addClass('step-half-hour');
}
}
// 初始化选中禁止选择时间范围
if (options.disabledValue) {
options.disabledValue.forEach(function (date) {
var dateNum = [SliderTime.timeToNum(date[0]), SliderTime.timeToNum(date[1])];
var start = (dateNum[0] - options.min) / (options.max - options.min) * 100,
end = (dateNum[1] - options.min) / (options.max - options.min) * 100,
width = end - start;
var selectedSlider = '<div class="layui-slider-bar-selected layui-disabled" style=" ' + ("vertical" === options.type ? "height" : "width") + ':' + width + '%; ' + ("vertical" === options.type ? "bottom" : "left") + ':' + start + '% ;"></div>';
$(options.elem).find('.layui-slider-bar').after(selectedSlider);
});
}
// 主题设置
if (options.theme) {
$(options.elem).find('.step-hour,.step-half-hour,.step-start-wrap,.step-end-wrap,.layui-slider-step').css("background", options.theme);
}
};
/**
* 数字转分钟
*/
Class.prototype.numToMins = function (value) {
var hours = Math.floor(value / 60);
var mins = (value - hours * 60);
return mins;
};
/**
* 显示警告信息
*/
Class.prototype.showTips = function (options, text) {
if ("vertical" === options.type) {
$(options.elem).find('.slider-danger-tips').css({
"display": "block",
"bottom": $(options.elem).find('.layui-slider-tips')[0].style.bottom
}).text(text);
} else {
$(options.elem).find('.slider-danger-tips').css({
"display": "block",
"left": $(options.elem).find('.layui-slider-tips')[0].style.left
}).text(text);
}
};
/**
* 关闭警告信息
*/
Class.prototype.closeTips = function (elem) {
$(elem).find('.slider-danger-tips').css({
"display": "none"
}).text('');
};
// 加载css
layui.link(layui.cache.base + 'sliderTime/sliderTime.css');
exports(MOD_NAME, SliderTime);
});