@dingdaoos/lucid-utils
Version:
Lucid utils
520 lines (514 loc) • 20 kB
text/typescript
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 }