/** * 时间范围滑块选择插件 * 基于 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('
' + SliderTime.numToTime(options.min) + '
') .append('
' + SliderTime.numToTime(options.max) + '
') // 警告提示Tips .append('
'); if (options.showstep) { // 开始结尾刻度标识 $(options.elem).find('.layui-slider') .append('
') .append('
'); } // 定义整点和半点时刻标识 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 = '
'; $(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); });