Skip to content

Commit 2b7bd91

Browse files
author
luchunyu
committed
fix(timepicker): update timepicker for range
1 parent e0da6af commit 2b7bd91

1 file changed

Lines changed: 227 additions & 0 deletions

File tree

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
<template lang="pug">
2+
.c-timepicker__timerange(@click="openPanel")
3+
.c-timerange__wrapper
4+
c-input(
5+
v-model="startTime"
6+
@change="startInputChange"
7+
)
8+
span 至
9+
c-input(
10+
v-model="endTime"
11+
@change="endInputChange"
12+
)
13+
.c-timerange__panel(:class="{show: isOpen}")
14+
.c-timerange__container
15+
.c-timepicker__wrap
16+
p 开始时间
17+
c-timepanel(
18+
:isShown="isOpen"
19+
:hour="startHour"
20+
:minute="startMinute"
21+
:second="startSecond"
22+
:format="format"
23+
:secondStep="secondStep"
24+
:minuteStep="minuteStep"
25+
:hourStep="hourStep"
26+
:maxTime="endTime"
27+
@change="startTimeChange"
28+
)
29+
.c-timepicker__wrap
30+
p 结束时间
31+
c-timepanel(
32+
:isShown="isOpen"
33+
:hour="endHour"
34+
:minute="endMinute"
35+
:second="endSecond"
36+
:format="format"
37+
:minTime="startTime"
38+
:secondStep="secondStep"
39+
:minuteStep="minuteStep"
40+
:hourStep="hourStep"
41+
@change="endTimeChange"
42+
)
43+
.c-timerange__btns
44+
c-button(
45+
@click="confirmRange"
46+
size="sm"
47+
outline
48+
primary
49+
) 确定
50+
c-button(
51+
size="sm"
52+
@click="cancel"
53+
outline
54+
) 取消
55+
</template>
56+
<script>
57+
import './index.css'
58+
import { getScrollBarSize } from '@util'
59+
import ZIndexManager from '../../scripts/utils/zIndexManager.js'
60+
export default {
61+
name: 'c-timerange',
62+
props: {
63+
value: Array,
64+
format: String,
65+
hourStep: {
66+
type: Number,
67+
default: 1
68+
},
69+
minuteStep: {
70+
type: Number,
71+
default: 1
72+
},
73+
secondStep: {
74+
type: Number,
75+
default: 1
76+
}
77+
},
78+
data () {
79+
return {
80+
isOpen: false,
81+
startHour: '',
82+
startMinute: '',
83+
startSecond: '',
84+
endHour: '',
85+
endMinute: '',
86+
endSecond: '',
87+
timerange: '',
88+
startTime: '',
89+
endTime: ''
90+
}
91+
},
92+
mounted () {
93+
if (typeof document === 'object') {
94+
this.timerange = this.$el.querySelector('.c-timerange__panel')
95+
document.body.appendChild(this.timerange)
96+
this.resize()
97+
window.addEventListener('resize', this.resize, false)
98+
}
99+
this.initTime()
100+
},
101+
watch: {
102+
value (newVal) {
103+
this.initTime()
104+
},
105+
isOpen () {
106+
if (this.isOpen) {
107+
this.resize()
108+
window.addEventListener('mouseup', this.onBodyClick, true)
109+
} else {
110+
window.removeEventListener('mouseup', this.onBodyClick, true)
111+
}
112+
}
113+
},
114+
methods: {
115+
initTime () {
116+
if (this.value.length === 2) {
117+
this.startTime = this.value[0]
118+
this.endTime = this.value[1]
119+
}
120+
if (this.startTime) {
121+
[this.startHour, this.startMinute, this.startSecond] = this.startTime.split(':')
122+
}
123+
if (this.endTime) {
124+
[this.endHour, this.endMinute, this.endSecond] = this.endTime.split(':')
125+
}
126+
},
127+
confirmRange () {
128+
console.log('confirm')
129+
// 验证数据合法性
130+
if (this.checkValue(this.startTime) && this.checkValue(this.endTime)) {
131+
this.emitEvent()
132+
this.close()
133+
} else {
134+
this.cancel()
135+
}
136+
},
137+
checkValue (value) {
138+
if (!value) return false
139+
const [hour, minute, second] = value
140+
return !(second > 59 || minute > 59 || hour > 23)
141+
},
142+
cancel () {
143+
this.initTime()
144+
this.emitEvent()
145+
this.close()
146+
},
147+
openPanel () {
148+
this.isOpen = true
149+
},
150+
close () {
151+
this.isOpen = false
152+
},
153+
onBodyClick (e) {
154+
const isInPicker = this.$el.contains(e.target)
155+
const isInPanel = this.timerange.contains(e.target)
156+
if (!isInPicker && !isInPanel) {
157+
this.confirmRange()
158+
this.$el.focus()
159+
}
160+
},
161+
getStyle () {
162+
const clientRect = this.$parent.$refs.timepicker.getBoundingClientRect()
163+
const windowH = window.innerHeight
164+
const windowW = window.innerWidth
165+
const marginTop = 2
166+
const scrollHeight = document.body.scrollWidth > window.innerWidth ? 20 : 0
167+
const droplistHeight = this.timerange.clientHeight
168+
const droplistWidth = this.timerange.clientWidth
169+
const defaultTop = clientRect.top + clientRect.height + marginTop + window.pageYOffset
170+
const clientHeight = clientRect.height + marginTop
171+
172+
const clientY = clientRect.y
173+
const compTop = windowH - droplistHeight - scrollHeight
174+
const marginRight = getScrollBarSize() + 5 // scrollbar width
175+
const left = droplistWidth + clientRect.left + marginRight + window.pageXOffset > windowW ? windowW - droplistWidth - marginRight : clientRect.left + window.pageXOffset
176+
const top = droplistHeight + clientHeight + clientY + scrollHeight > windowH ? compTop : defaultTop
177+
const zIndex = ZIndexManager.next()
178+
return `
179+
position: absolute;
180+
top: ${top}px;
181+
left: ${left}px;
182+
z-index: ${zIndex};
183+
`
184+
},
185+
resize () {
186+
this.$nextTick(() => {
187+
this.timerange.style.cssText = this.getStyle()
188+
})
189+
},
190+
generateValue (hour, minute, second) {
191+
const result = []
192+
hour && result.push(hour)
193+
minute && result.push(minute)
194+
second && result.push(second)
195+
return result.join(':')
196+
},
197+
startInputChange (value) {
198+
const regValid = /^\d{2}:\d{2}:\d{2}$/.test(value)
199+
if (regValid && this.checkValue(value)) {
200+
[this.startHour, this.startMinute, this.startSecond] = value.split(':')
201+
}
202+
},
203+
endInputChange (value) {
204+
const regValid = /^\d{2}:\d{2}:\d{2}$/.test(value)
205+
if (regValid && this.checkValue(value)) {
206+
[this.endHour, this.endMinute, this.endSecond] = value.split(':')
207+
}
208+
},
209+
startTimeChange ({ hour, minute, second }) {
210+
this.startHour = hour
211+
this.startMinute = minute
212+
this.startSecond = second
213+
this.startTime = this.generateValue(hour, minute, second)
214+
},
215+
endTimeChange ({ hour, minute, second }) {
216+
this.endHour = hour
217+
this.endMinute = minute
218+
this.endSecond = second
219+
this.endTime = this.generateValue(hour, minute, second)
220+
},
221+
emitEvent () {
222+
// this.$emit('input', [this.startTime, this.endTime])
223+
this.$emit('change', [this.startTime, this.endTime])
224+
}
225+
}
226+
}
227+
</script>

0 commit comments

Comments
 (0)