UNPKG

@dingdaoos/lucid-utils

Version:
520 lines (514 loc) 20 kB
import { TimeInfo } from '../../utils/time' interface Options<T> { hourList: any[] minuteList: any[] secondsList: any[] timeList: any[] valueFormatArr: any[] showHour: boolean showMinute: boolean isShowTimeType: boolean combination: boolean interval: string hourType: number } class TimePicker<T> { private hourList: any[] private minuteList: any[] private secondsList: any[] private timeList: any[] private valueFormatArr: any[] private showHour: boolean private showMinute: boolean private isShowTimeType: boolean private combination: boolean private interval: string private hourType: number private timeInfo: any private disabledTimeData: object private timeTypeIndexList: Array<number> private timeType: Array<string> constructor(options: Options<T>) { this.hourList = options.hourList this.minuteList = options.minuteList this.secondsList = options.secondsList this.timeList = options.timeList this.valueFormatArr = options.valueFormatArr this.showHour = options.showHour this.showMinute = options.showMinute this.isShowTimeType = options.isShowTimeType this.combination = options.combination this.interval = options.interval this.hourType = options.hourType this.timeTypeIndexList = [0, 1] this.timeType = ['AM', 'PM'] this.init() } init() { const hourDuration = this.hourType === 12 && !this.combination ? '0-11' : '0-23' const intervalArr = this.interval.split(':') const interval = +intervalArr[0] * 60 + +intervalArr[1] || 0 const options = { hourType: this.hourType, hourDuration: hourDuration, minuteDuration: '0-59', secondDuration: '0-59', interval: interval } this.timeInfo = new TimeInfo(options) this.hourList = this.timeInfo.hours this.minuteList = this.timeInfo.minutes this.secondsList = this.timeInfo.seconds this.timeList = this.timeInfo.timeList } timeTypeIndexListInit(range) { const timeTypeIndexList = [] range.map(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') const endTime = this.translateRangeTime(itemArr[1] || '') if (this.isShowTimeType && timeTypeIndexList.length < 2) { if (timeTypeIndexList.indexOf(startTime['timeTypeIndex']) === -1) { timeTypeIndexList.push(startTime['timeTypeIndex']) } if (timeTypeIndexList.indexOf(endTime['timeTypeIndex']) === -1) { timeTypeIndexList.push(endTime['timeTypeIndex']) } } this.timeTypeIndexList = timeTypeIndexList }) } getNowInfo() { return this.timeInfo.getNowInfo() } translateRangeTime(time) { if (time === '' || time === undefined) { return { time: '' } } const timeArr = time.split(':') const timeObject = {} if (this.hourType === 12) { timeObject['TfHour'] = timeArr[0] timeObject['timeTypeIndex'] = +timeArr[0] >= 12 ? 1 : 0 } timeArr[0] = this.isShowTimeType && +timeArr[0] > 12 ? +timeArr[0] - 12 : timeArr[0] timeObject['time'] = timeArr.join(':') timeObject['hour'] = this.showHour || this.combination ? timeArr[0] : '' timeObject['hour'] = +timeObject['hour'] === 12 && this.hourType === 12 ? '00' : timeObject['hour'] let second = '' if (timeArr.length <= this.valueFormatArr.length) { if (!this.showHour && !this.showMinute) { second = timeArr[0] } else if (!this.showHour && this.showMinute) { second = timeArr[1] } else { second = timeArr[2] } } else { second = timeArr[2] } timeObject['minute'] = this.showHour || (!this.showHour && timeArr.length === 3) || this.combination ? timeArr[1] : timeArr[0] timeObject['second'] = second return timeObject } getHourRangeList(range, timeTypeIndex) { let hours = [] range.map(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') let endTime = this.translateRangeTime(itemArr[1] || '') endTime = endTime['time'] === '' ? startTime : endTime if (this.isShowTimeType) { if (startTime['timeTypeIndex'] === endTime['timeTypeIndex'] && startTime['timeTypeIndex'] === timeTypeIndex) { for (let i = +startTime['hour']; i <= +endTime['hour']; i++) { hours.push(timeDataHandle(i)) } } if (startTime['timeTypeIndex'] !== endTime['timeTypeIndex']) { if (timeTypeIndex === startTime['timeTypeIndex']) { for (let i = +startTime['hour']; i <= 12; i++) { hours.push(timeDataHandle(i)) } } else { for (let i = 0; i <= endTime['hour']; i++) { hours.push(timeDataHandle(i)) } } } } else { for (let i = +startTime['hour']; i <= +endTime['hour']; i++) { hours.push(timeDataHandle(i)) } } }) hours = hours.length === 0 ? this.hourList : hours return hours } getMinuteRangeList = (range, hour, timeTypeIndex) => { let minutes = [] range.map(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') let endTime = this.translateRangeTime(itemArr[1] || '') endTime = endTime['time'] === '' ? startTime : endTime let startMinute = +startTime['minute'] || 0 let endMinute = +endTime['minute'] || 59 if (!this.showHour) { const start = Math.min(startMinute, endMinute) const end = Math.max(startMinute, endMinute) startMinute = start endMinute = end } if (this.hourType === 12 && startTime['timeTypeIndex'] !== endTime['timeTypeIndex']) { if (+startTime['hour'] === +hour && startTime['timeTypeIndex'] === timeTypeIndex) { for (let i = startMinute; i <= 59; i++) { minutes.push(timeDataHandle(i)) } } else if (+endTime['hour'] === +hour && endTime['timeTypeIndex'] === timeTypeIndex) { for (let i = 0; i <= endMinute; i++) { minutes.push(timeDataHandle(i)) } } } else { const start = (this.hourType === 12 && startTime['timeTypeIndex'] === timeTypeIndex) || this.hourType === 24 const end = (this.hourType === 12 && endTime['timeTypeIndex'] === timeTypeIndex) || this.hourType === 24 if (+startTime['hour'] === +hour && +endTime['hour'] !== +hour && start) { for (let i = startMinute; i <= 59; i++) { minutes.push(timeDataHandle(i)) } } else if (+startTime['hour'] !== +hour && +endTime['hour'] === +hour && end) { for (let i = 0; i <= endMinute; i++) { minutes.push(timeDataHandle(i)) } } else if (+startTime['hour'] === +hour && +endTime['hour'] === +hour) { for (let i = startMinute; i <= endMinute; i++) { minutes.push(timeDataHandle(i)) } } if (!this.showHour) { minutes = minutes[minutes.length - 1] > endMinute ? [] : minutes for (let i = startMinute; i <= endMinute; i++) { minutes.push(timeDataHandle(i)) } } } }) minutes = minutes.length === 0 ? this.minuteList : minutes return minutes } getSecondRangeList(range, hour, minute) { let seconds = [] range.map(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') let endTime = this.translateRangeTime(itemArr[1] || '') endTime = endTime['time'] === '' ? startTime : endTime let startSecond = +startTime['second'] || 0 let endSecond = +endTime['second'] || 59 if ((+startTime['hour'] === +hour || !this.showHour) && +startTime['minute'] === +minute) { for (let i = startSecond; i <= 59; i++) { seconds.push(timeDataHandle(i)) } } else if ((+endTime['hour'] === +hour || !this.showHour) && +endTime['minute'] === +minute) { for (let i = 0; i <= endSecond; i++) { seconds.push(timeDataHandle(i)) } } if (!this.showHour && !this.showMinute) { const start = Math.min(startSecond, endSecond) const end = Math.max(startSecond, endSecond) startSecond = start endSecond = end seconds = seconds[seconds.length - 1] > endSecond ? [] : seconds for (let i = startSecond; i <= endSecond; i++) { seconds.push(timeDataHandle(i)) } } }) seconds = seconds.length === 0 ? this.secondsList : seconds return seconds } getTimeRangeList(timeList, range) { let list = [] const date = new Date() timeList.map(timeItem => { const timeArr = timeItem.split(':') const time = date.setHours(+timeArr[0], +timeArr[1], 0) range.some(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') let endTime = this.translateRangeTime(itemArr[1] || '') endTime = endTime['time'] === '' ? startTime : endTime var start = date.setHours(+startTime['hour'] || 0, +startTime['minute'] || 0, +startTime['second'] || 0) var end = date.setHours(+endTime['hour'] || 0, +endTime['minute'] || 0, +endTime['second'] || 0) if (time >= start && time <= end) { list.push(timeItem) return true } }) }) list = range.length === 0 ? this.timeList : list return list } getIndex() { const hourIndex = this.hourType === 24 ? this.valueFormatArr.indexOf('HH') : this.valueFormatArr.indexOf('hh') const minuteIndex = this.valueFormatArr.indexOf('mm') const secondsIndex = this.valueFormatArr.indexOf('ss') return { hourIndex: hourIndex, minuteIndex: minuteIndex, secondsIndex: secondsIndex } } toCheck(TimepickerBox, isSelectRange, activeFlag, flag) { let domArr = TimepickerBox.querySelectorAll('.lu-timepicker-active') if (!isSelectRange || !activeFlag) { domArr = TimepickerBox.querySelectorAll('.lu-timepicker-unrange') } for (var i = 0; i < domArr.length; i++) { const parent = this.combination ? domArr[i].parentNode : domArr[i].parentNode.parentNode const scrollTop = domArr[i].offsetTop - parent.offsetTop - (parent.clientHeight - domArr[i].clientHeight) / 2 if (flag) { parent.scrollTo({ top: scrollTop, behavior: 'smooth' }) } else { parent.scrollTop = scrollTop } } } format(time, typeIndex, range) { let timeTypeIndex = typeIndex this.timeTypeIndexListInit(range) if (time === '') return { timeObject: { time: time, timeTf: time }, timeTypeIndex: timeTypeIndex } let timeInfoArr = time.split(':') let hour = '' let timeHour = '' const hourIndex = this.hourType === 24 ? this.valueFormatArr.indexOf('HH') : this.valueFormatArr.indexOf('hh') timeInfoArr = timeInfoArr.map(item => { item = timeDataHandle(item) return item }) if (this.combination) { time = timeInfoArr.join(':') } if (this.showHour) { timeHour = timeInfoArr[hourIndex] hour = this.hourType === 12 && +timeHour > 12 ? timeDataHandle(+timeHour - 12) : timeDataHandle(timeHour) } timeInfoArr[hourIndex] = hour timeInfoArr[hourIndex] = this.hourType === 12 && +timeInfoArr[hourIndex] === 0 ? 12 : timeInfoArr[hourIndex] const timeFormat = timeInfoArr.join(':') const timeObject = { time: timeFormat, hourType: this.hourType } if (this.hourType === 12) { timeObject['timeType'] = +timeHour >= 12 ? 'PM' : 'AM' timeTypeIndex = +timeHour >= 12 ? 1 : 0 timeTypeIndex = this.timeTypeIndexList.length === 1 ? this.timeTypeIndexList[0] : timeTypeIndex timeObject['timeTf'] = twToTf(timeFormat, timeTypeIndex) } return { timeObject: timeObject, timeTypeIndex: timeTypeIndex } } handleCompare(options) { if (this.combination) { return options.disabledType === 'pre' ? timeStamp(options.disabledTimeData) < timeStamp(options.time) : timeStamp(options.disabledTimeData) > timeStamp(options.time) } const isNoSame = options.disabledTimeData.timeTypeIndex !== options.timeTypeIndex if (this.isShowTimeType && isNoSame) return false switch (options.type) { case 'hour': { const hourCompare = options.disabledType === 'pre' ? +options.disabledTimeData.hour < +options.time : +options.disabledTimeData.hour > +options.time const hour = +this.hourList[options.hourIndex] if (this.isShowTimeType && options.disabledType === 'pre' && +options.disabledTimeData.hour < +hour) { options.handleClick('hourIndex', this.hourList.indexOf(options.disabledTimeData.hour)) } return hourCompare } case 'minutes': { const isHour = +options.disabledTimeData.hour === +this.hourList[options.hourIndex] const minutes = +this.minuteList[options.minuteIndex] if (isHour && options.disabledType === 'pre' && +options.disabledTimeData.minutes < +minutes) { options.handleClick('minuteIndex', this.minuteList.indexOf(options.disabledTimeData.minutes)) } const minuteCompare = options.disabledType === 'pre' ? (isHour || !this.showHour) && +options.disabledTimeData.minutes < +options.time : (isHour || !this.showHour) && +options.disabledTimeData.minutes > +options.time return minuteCompare } case 'seconds': { const isHour = +options.disabledTimeData.hour === +this.hourList[options.hourIndex] const isMinute = +options.disabledTimeData.minutes === +this.minuteList[options.minuteIndex] const seconds = +this.secondsList[options.secondsIndex] const isEqual = (isHour && isMinute) || (isHour && !this.showMinute) || (isMinute && !this.showHour) if (isEqual && options.disabledType === 'pre' && +options.disabledTimeData.seconds < +seconds) { options.handleClick('secondsIndex', this.secondsList.indexOf(options.disabledTimeData.seconds)) } const secondsCompare = options.disabledType === 'pre' ? isEqual && +options.disabledTimeData.seconds < +options.time : isEqual && +options.disabledTimeData.seconds > +options.time return secondsCompare } } } handleDisabled(disabledTime, disabledType, timeTypeIndex) { if (JSON.stringify(disabledTime) === '{}') return const { hourIndex, minuteIndex, secondsIndex } = this.getIndex() const time = disabledTime.time if (this.combination) { this.disabledTimeData = time } else { const disabledTimeArr = time.split(':') this.disabledTimeData = { hour: disabledTimeArr[hourIndex] || 0, minutes: disabledTimeArr[minuteIndex] || 0, seconds: disabledTimeArr[secondsIndex] || 0, timeTypeIndex: disabledTime.timeType === 'AM' ? 0 : 1 } this.disabledTimeData['hour'] = +this.disabledTimeData['hour'] === 12 ? 0 : this.disabledTimeData['hour'] if (disabledType === 'pre') { this.timeTypeIndexList = this.disabledTimeData['timeTypeIndex'] === 0 ? [0] : [1, 0] } else { this.timeTypeIndexList = this.disabledTimeData['timeTypeIndex'] === 1 ? [1] : [1, 0] } } } compareSelectRange(hour, minute, second, range) { let isSelectRange = false range.map(item => { const itemArr = item.split('-') const startTime = this.translateRangeTime(itemArr[0] || '') const endTime = this.translateRangeTime(itemArr[1] || '') var date = new Date() if (this.isShowTimeType) { startTime['hour'] = startTime['TfHour'] endTime['hour'] = endTime['TfHour'] } if (!this.combination) { hour = this.showHour ? hour : startTime['hour'] minute = !this.showHour && !this.showMinute ? startTime['minute'] : minute endTime['hour'] = this.showHour ? endTime['hour'] : startTime['hour'] endTime['minute'] = !this.showHour && !this.showMinute ? startTime['minute'] : endTime['minute'] } var time = date.setHours(+hour || 0, +minute || 0, +second || 0) var start = date.setHours(+startTime['hour'] || 0, +startTime['minute'] || 0, +startTime['second'] || 0) var end = date.setHours(+endTime['hour'] || 0, +endTime['minute'] || 0, +endTime['second'] || 0) if (time >= start && time <= end) { isSelectRange = true } }) return isSelectRange } getHour(hour) { const tHour = this.hourType === 12 && +hour > 12 ? +hour - 12 + '' : hour return tHour } getTimeArr(hour, minute, second) { const timeArr = [] this.valueFormatArr.map((item, index) => { if (item === 'HH' || item === 'hh') { timeArr[index] = hour } else if (item === 'mm') { timeArr[index] = minute } else if (item === 'ss' && !this.combination) { timeArr[index] = second } }) return timeArr } getTimeObject(timeArr, timeTypeIndex) { timeArr[0] = this.isShowTimeType && +timeArr[0] === 0 ? 12 : timeArr[0] const time = timeArr.join(':') const timeObject = { time: time, hourType: this.hourType } if (this.isShowTimeType) { timeObject['timeType'] = this.timeType[timeTypeIndex] timeObject['timeTf'] = twToTf(time, timeTypeIndex) } return timeObject } timeHandle(options) { const object = {} const { hourIndex } = this.getIndex() if (options.nowFlag) { let timeArr = [] timeArr = this.getTimeArr(this.getHour(options.timeInfoArr[0]), options.timeInfoArr[1], options.timeInfoArr[2]) options.disabledTime = { ...options.disabledTime, time: timeArr.join(':') } } if (this.showHour) { const timeHour = options.nowInfo ? options.timeInfoArr[0] : options.timeInfoArr[hourIndex] const hour = this.getHour(timeHour) object['hour'] = hour let timeTypeIndex = 0 if (this.hourType === 12) { timeTypeIndex = +timeHour >= 12 ? 1 : 0 } object['timeTypeIndex'] = timeTypeIndex if (options.nowFlag) { options.disabledTime['timeType'] = this.timeType[timeTypeIndex] } } object['disabledTime'] = options.disabledTime if (this.combination) { const timeIndexInit = options.timeIndex options.timeIndex = this.timeList.findIndex(item => { return item === options.timeInfoArr[0] + ':' + options.timeInfoArr[1] }) if (options.timeIndex !== -1) { options.timeObject.timeIndex = options.timeIndex } object['timeObject'] = options.timeObject const timeIndex = options.timeIndex object['timeIndex'] = options.isSelectRange && timeIndex === -1 ? timeIndexInit : options.timeIndex object['isSelectRange'] = options.isSelectRange && timeIndex === -1 ? false : options.isSelectRange object['activeFlag'] = options.timeObject.timeIndex } return object } } const timeDataHandle = time => { return +time < 10 ? '0' + +time : time + '' } const twToTf = (time, timeTypeIndex) => { const timeArr = time.split(':') timeArr[0] = (timeTypeIndex === 0 && +timeArr[0] !== 0) || (timeTypeIndex === 1 && +timeArr[0] === 12) ? timeArr[0] : +timeArr[0] + 12 + '' timeArr[0] = timeTypeIndex === 0 && +timeArr[0] === 12 ? '00' : timeArr[0] return timeArr.join(':') } const inputFormat = (val, hourType) => { if (hourType === 24 || val.time === '') return val.time const str = val.timeType + ' ' + val.time return str } const timeStamp = time => { const timeArr = time.split(':') return Number(+timeArr[0] * 3600) + Number(+timeArr[1] * 60) } export { TimePicker, timeDataHandle, twToTf, inputFormat }