|
|
|
|
@ -42,6 +42,7 @@ export class DatePicker {
|
|
|
|
|
private dom: IDatePickerDom
|
|
|
|
|
private renderOptions: IRenderOption | null
|
|
|
|
|
private isDatePicker: boolean
|
|
|
|
|
private pickDate: Date | null
|
|
|
|
|
|
|
|
|
|
constructor(options: IDatePickerOption = {}) {
|
|
|
|
|
this.options = {
|
|
|
|
|
@ -52,6 +53,7 @@ export class DatePicker {
|
|
|
|
|
this.dom = this._createDom()
|
|
|
|
|
this.renderOptions = null
|
|
|
|
|
this.isDatePicker = true
|
|
|
|
|
this.pickDate = null
|
|
|
|
|
this._bindEvent()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -117,6 +119,7 @@ export class DatePicker {
|
|
|
|
|
for (let i = 0; i < endIndex; i++) {
|
|
|
|
|
const time = document.createElement('li')
|
|
|
|
|
time.innerText = `${String(i).padStart(2, '0')}`
|
|
|
|
|
time.setAttribute('data-id', `${i}`)
|
|
|
|
|
ol.append(time)
|
|
|
|
|
}
|
|
|
|
|
if (isHour) {
|
|
|
|
|
@ -197,6 +200,30 @@ export class DatePicker {
|
|
|
|
|
this.dom.menu.submit.onclick = () => {
|
|
|
|
|
this.dispose()
|
|
|
|
|
}
|
|
|
|
|
this.dom.time.hour.onclick = (evt) => {
|
|
|
|
|
if (!this.pickDate) return
|
|
|
|
|
const li = <HTMLLIElement>evt.target
|
|
|
|
|
const id = li.dataset.id
|
|
|
|
|
if (!id) return
|
|
|
|
|
this.pickDate.setHours(Number(id))
|
|
|
|
|
this._setTimePick(false)
|
|
|
|
|
}
|
|
|
|
|
this.dom.time.minute.onclick = (evt) => {
|
|
|
|
|
if (!this.pickDate) return
|
|
|
|
|
const li = <HTMLLIElement>evt.target
|
|
|
|
|
const id = li.dataset.id
|
|
|
|
|
if (!id) return
|
|
|
|
|
this.pickDate.setMinutes(Number(id))
|
|
|
|
|
this._setTimePick(false)
|
|
|
|
|
}
|
|
|
|
|
this.dom.time.second.onclick = (evt) => {
|
|
|
|
|
if (!this.pickDate) return
|
|
|
|
|
const li = <HTMLLIElement>evt.target
|
|
|
|
|
const id = li.dataset.id
|
|
|
|
|
if (!id) return
|
|
|
|
|
this.pickDate.setSeconds(Number(id))
|
|
|
|
|
this._setTimePick(false)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _setPosition() {
|
|
|
|
|
@ -215,8 +242,19 @@ export class DatePicker {
|
|
|
|
|
this.dom.container.style.top = `${top + startTop + lineHeight}px`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _setNow() {
|
|
|
|
|
this.now = new Date()
|
|
|
|
|
public isInvalidDate(value: Date): boolean {
|
|
|
|
|
return value.toDateString() === 'Invalid Date'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _setValue() {
|
|
|
|
|
const value = this.renderOptions?.value
|
|
|
|
|
if (value) {
|
|
|
|
|
const setDate = new Date(value)
|
|
|
|
|
this.now = this.isInvalidDate(setDate) ? new Date() : setDate
|
|
|
|
|
} else {
|
|
|
|
|
this.now = new Date()
|
|
|
|
|
}
|
|
|
|
|
this.pickDate = new Date(this.now)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _update() {
|
|
|
|
|
@ -225,10 +263,18 @@ export class DatePicker {
|
|
|
|
|
const localYear = localDate.getFullYear()
|
|
|
|
|
const localMonth = localDate.getMonth() + 1
|
|
|
|
|
const localDay = localDate.getDate()
|
|
|
|
|
// 选择年月日
|
|
|
|
|
let pickYear: number | null = null
|
|
|
|
|
let pickMonth: number | null = null
|
|
|
|
|
let pickDay: number | null = null
|
|
|
|
|
if (this.pickDate) {
|
|
|
|
|
pickYear = this.pickDate.getFullYear()
|
|
|
|
|
pickMonth = this.pickDate.getMonth() + 1
|
|
|
|
|
pickDay = this.pickDate.getDate()
|
|
|
|
|
}
|
|
|
|
|
// 当前年月日
|
|
|
|
|
const year = this.now.getFullYear()
|
|
|
|
|
const month = this.now.getMonth() + 1
|
|
|
|
|
const day = this.now.getDate()
|
|
|
|
|
this.dom.title.now.innerText = `${year}年 ${String(month).padStart(2, '0')}月`
|
|
|
|
|
// 日期补差
|
|
|
|
|
const curDate = new Date(year, month, 0) // 当月日期
|
|
|
|
|
@ -246,8 +292,9 @@ export class DatePicker {
|
|
|
|
|
dayDom.classList.add('disable')
|
|
|
|
|
dayDom.innerText = `${i}`
|
|
|
|
|
dayDom.onclick = () => {
|
|
|
|
|
this.now = new Date(year, month - 2, i)
|
|
|
|
|
this._update()
|
|
|
|
|
const newMonth = month - 2
|
|
|
|
|
this.now = new Date(year, newMonth, i)
|
|
|
|
|
this._setDatePick(year, newMonth, i)
|
|
|
|
|
}
|
|
|
|
|
this.dom.day.append(dayDom)
|
|
|
|
|
}
|
|
|
|
|
@ -257,13 +304,14 @@ export class DatePicker {
|
|
|
|
|
if (localYear === year && localMonth === month && localDay === i) {
|
|
|
|
|
dayDom.classList.add('active')
|
|
|
|
|
}
|
|
|
|
|
if (i === day) {
|
|
|
|
|
if (this.pickDate && pickYear === year && pickMonth === month && pickDay === i) {
|
|
|
|
|
dayDom.classList.add('select')
|
|
|
|
|
}
|
|
|
|
|
dayDom.innerText = `${i}`
|
|
|
|
|
dayDom.onclick = () => {
|
|
|
|
|
this.now = new Date(year, month - 1, i)
|
|
|
|
|
this._update()
|
|
|
|
|
const newMonth = month - 1
|
|
|
|
|
this.now = new Date(year, newMonth, i)
|
|
|
|
|
this._setDatePick(year, newMonth, i)
|
|
|
|
|
}
|
|
|
|
|
this.dom.day.append(dayDom)
|
|
|
|
|
}
|
|
|
|
|
@ -275,7 +323,7 @@ export class DatePicker {
|
|
|
|
|
dayDom.innerText = `${i}`
|
|
|
|
|
dayDom.onclick = () => {
|
|
|
|
|
this.now = new Date(year, month, i)
|
|
|
|
|
this._update()
|
|
|
|
|
this._setDatePick(year, month, i)
|
|
|
|
|
}
|
|
|
|
|
this.dom.day.append(dayDom)
|
|
|
|
|
}
|
|
|
|
|
@ -290,9 +338,40 @@ export class DatePicker {
|
|
|
|
|
this.dom.dateWrap.classList.remove('active')
|
|
|
|
|
this.dom.timeWrap.classList.add('active')
|
|
|
|
|
this.dom.menu.time.innerText = `返回日期`
|
|
|
|
|
// 设置时分秒选择
|
|
|
|
|
this._setTimePick()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _setDatePick(year: number, month: number, day: number) {
|
|
|
|
|
this.now = new Date(year, month, day)
|
|
|
|
|
this.pickDate?.setFullYear(year)
|
|
|
|
|
this.pickDate?.setMonth(month)
|
|
|
|
|
this.pickDate?.setDate(day)
|
|
|
|
|
this._update()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _setTimePick(isIntoView = true) {
|
|
|
|
|
const hour = this.pickDate?.getHours() || 0
|
|
|
|
|
const minute = this.pickDate?.getMinutes() || 0
|
|
|
|
|
const second = this.pickDate?.getSeconds() || 0
|
|
|
|
|
const { hour: hourDom, minute: minuteDom, second: secondDom } = this.dom.time
|
|
|
|
|
const timeDomList = [hourDom, minuteDom, secondDom]
|
|
|
|
|
// 清空
|
|
|
|
|
timeDomList.forEach(timeDom => {
|
|
|
|
|
timeDom.querySelectorAll('li')
|
|
|
|
|
.forEach(li => li.classList.remove('active'))
|
|
|
|
|
})
|
|
|
|
|
const pickList: [HTMLOListElement, number][] = [[hourDom, hour], [minuteDom, minute], [secondDom, second]]
|
|
|
|
|
pickList.forEach(([dom, time]) => {
|
|
|
|
|
const pickDom = dom.querySelector(`[data-id='${time}']`)!
|
|
|
|
|
pickDom.classList.add('active')
|
|
|
|
|
if (isIntoView) {
|
|
|
|
|
pickDom.scrollIntoView()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _preMonth() {
|
|
|
|
|
this.now.setMonth(this.now.getMonth() - 1)
|
|
|
|
|
this._update()
|
|
|
|
|
@ -314,8 +393,8 @@ export class DatePicker {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _now() {
|
|
|
|
|
this.now = new Date()
|
|
|
|
|
this._update()
|
|
|
|
|
this.pickDate = new Date()
|
|
|
|
|
this.dispose()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _toggleVisible(isVisible: boolean) {
|
|
|
|
|
@ -328,7 +407,7 @@ export class DatePicker {
|
|
|
|
|
|
|
|
|
|
public render(option: IRenderOption) {
|
|
|
|
|
this.renderOptions = option
|
|
|
|
|
this._setNow()
|
|
|
|
|
this._setValue()
|
|
|
|
|
this._update()
|
|
|
|
|
this._setPosition()
|
|
|
|
|
this.isDatePicker = true
|
|
|
|
|
@ -338,7 +417,7 @@ export class DatePicker {
|
|
|
|
|
|
|
|
|
|
public dispose() {
|
|
|
|
|
this._toggleVisible(false)
|
|
|
|
|
return this.now
|
|
|
|
|
return this.pickDate
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|