2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-05-17 04:29:39 +03:00

feat: add the prop time-select-options (#227)

This commit is contained in:
mengxiong10
2019-06-25 17:12:33 +08:00
parent e134442bc7
commit a55b4b6f95
5 changed files with 175 additions and 100 deletions
+8
View File
@@ -102,6 +102,7 @@ export default {
| disabled-days | Disable Days | `(date) => boolean` | - |
| shortcuts | the shortcuts for the range picker | [shortcuts](#shortcuts) | true |
| time-picker-options | custom time-picker | [time-picker-options](#time-picker-options) | null |
| time-select-options | custom time-select | [time-select-options](#time-select-options) | null |
| minute-step | if > 0 don't show the second picker | 0 - 60 | 0 |
| first-day-of-week | set the first day of week | 1 - 7 | 7 |
| input-class | the input class name | `string` | 'mx-input' |
@@ -151,6 +152,13 @@ custom time-picker
| {start: '00:00', step:'00:30' , end: '23:30'} |
| () => Array<{ label: string; values: { hours: number; minutes: number } }> |
#### time-select-options
custom time-select for columns
| Type |
|------|
| {hours: [9, 10, 11], minutes: [10, 20], seconds: [10, 20] } |
### Events
| Name | Description | Callback Arguments |
|-----------------|--------------------------------------------------------|------------------------|
+8
View File
@@ -102,6 +102,7 @@ export default {
| disabled-days | 自定义禁止的日期 | `(date) => boolean` | - |
| shortcuts | 自定义范围选择的时候快捷选项 | [shortcuts](#shortcuts) | true |
| time-picker-options | 自定义时间选择的开始,结束,步进 | [time-picker-options](#time-picker-options) | null |
| time-select-options | 自定义时间列的选择 | [time-select-options](#time-select-options) | null |
| minute-step | 设置分钟的步进, 设置大于0不显示秒的选择(0-60) | 0 - 60 | 0 |
| first-day-of-week | 设置日历星期几开头 | 1 - 7 | 7 |
| input-class | 自定义input元素的类名 | `string` | 'mx-input' |
@@ -150,6 +151,13 @@ export default {
| {start: '00:00', step:'00:30' , end: '23:30'} |
| () => Array<{ label: string; values: { hours: number; minutes: number } }> |
#### time-select-options
自定义时间选择列
| 可选值 |
|------|
| {hours: [9, 10, 11], minutes: [10, 20], seconds: [10, 20] } |
### 事件
| Name | 说明 | 回调参数
|-----------------|----------------------------- |----------------
+14 -1
View File
@@ -19,7 +19,8 @@ new Vue({
value9: '',
value10: new Date(),
value11: new Date(),
value12: ''
value12: '',
value13: ''
}
},
methods: {
@@ -80,6 +81,18 @@ new Vue({
format="YYYY-MM-DD hh:mm:ss a"
:minute-step="10"
></date-picker>`,
'datetime with time-select-options': `
<date-picker
v-model="value13"
lang="en"
type="datetime"
format="YYYY-MM-DD hh:mm:ss a"
:time-select-options="{
hours: [9, 10, 11, 12, 13, 14, 15, 16],
minutes: [0, 10,20,30,40,50],
seconds: []
}"
></date-picker>`,
'datetime range': `
<date-picker
v-model="value5"
+72 -44
View File
@@ -1,38 +1,22 @@
<template>
<div class="mx-calendar"
:class="'mx-calendar-panel-' + panel.toLowerCase()">
<div class="mx-calendar" :class="'mx-calendar-panel-' + panel.toLowerCase()">
<div class="mx-calendar-header">
<a
v-show="panel !== 'TIME'"
class="mx-icon-last-year"
@click="handleIconYear(-1)">&#171;</a>
<a
v-show="panel === 'DATE'"
class="mx-icon-last-month"
@click="handleIconMonth(-1)">&#8249;</a>
<a
v-show="panel !== 'TIME'"
class="mx-icon-next-year"
@click="handleIconYear(1)">&#187;</a>
<a
v-show="panel === 'DATE'"
class="mx-icon-next-month"
@click="handleIconMonth(1)">&#8250;</a>
<a v-show="panel !== 'TIME'" class="mx-icon-last-year" @click="handleIconYear(-1)">&#171;</a>
<a v-show="panel === 'DATE'" class="mx-icon-last-month" @click="handleIconMonth(-1)">&#8249;</a>
<a v-show="panel !== 'TIME'" class="mx-icon-next-year" @click="handleIconYear(1)">&#187;</a>
<a v-show="panel === 'DATE'" class="mx-icon-next-month" @click="handleIconMonth(1)">&#8250;</a>
<a
v-show="panel === 'DATE'"
class="mx-current-month"
@click="handleBtnMonth">{{months[calendarMonth]}}</a>
@click="handleBtnMonth"
>{{months[calendarMonth]}}</a>
<a
v-show="panel === 'DATE' || panel === 'MONTH'"
class="mx-current-year"
@click="handleBtnYear">{{calendarYear}}</a>
<a
v-show="panel === 'YEAR'"
class="mx-current-year">{{yearHeader}}</a>
<a
v-show="panel === 'TIME'"
class="mx-time-header"
@click="handleTimeHeader">{{timeHeader}}</a>
@click="handleBtnYear"
>{{calendarYear}}</a>
<a v-show="panel === 'YEAR'" class="mx-current-year">{{yearHeader}}</a>
<a v-show="panel === 'TIME'" class="mx-time-header" @click="handleTimeHeader">{{timeHeader}}</a>
</div>
<div class="mx-calendar-content">
<panel-date
@@ -45,28 +29,33 @@
:end-at="endAt"
:first-day-of-week="firstDayOfWeek"
:disabled-date="isDisabledDate"
@select="selectDate"/>
@select="selectDate"
/>
<panel-year
v-show="panel === 'YEAR'"
:value="value"
:disabled-year="isDisabledYear"
:first-year="firstYear"
@select="selectYear" />
@select="selectYear"
/>
<panel-month
v-show="panel === 'MONTH'"
:value="value"
:disabled-month="isDisabledMonth"
:calendar-year="calendarYear"
@select="selectMonth" />
@select="selectMonth"
/>
<panel-time
v-show="panel === 'TIME'"
:minute-step="minuteStep"
:time-picker-options="timePickerOptions"
:time-select-options="timeSelectOptions"
:value="value"
:disabled-time="isDisabledTime"
:time-type="timeType"
@select="selectTime"
@pick="pickTime" />
@pick="pickTime"
/>
</div>
</div>
</template>
@@ -141,6 +130,12 @@ export default {
default: 0,
validator: val => val >= 0 && val <= 60
},
timeSelectOptions: {
type: Object,
default () {
return null
}
},
timePickerOptions: {
type: [Object, Function],
default () {
@@ -242,16 +237,21 @@ export default {
}
},
getNow (value) {
return value ? new Date(value) : (
(this.defaultValue && isValidDate(this.defaultValue)) ? new Date(this.defaultValue) : new Date()
)
return value
? new Date(value)
: this.defaultValue && isValidDate(this.defaultValue)
? new Date(this.defaultValue)
: new Date()
},
// 根据value更新日历
updateNow (value) {
const oldNow = this.now
this.now = this.getNow(value)
if (this.visible && this.now !== oldNow) {
this.dispatch('DatePicker', 'calendar-change', [new Date(this.now), new Date(oldNow)])
this.dispatch('DatePicker', 'calendar-change', [
new Date(this.now),
new Date(oldNow)
])
}
},
getCriticalTime (value) {
@@ -272,15 +272,19 @@ export default {
if (startAt === undefined) {
startAt = this.startAt
}
return (this.notBeforeTime && time < this.notBeforeTime) ||
return (
(this.notBeforeTime && time < this.notBeforeTime) ||
(startAt && time < this.getCriticalTime(startAt))
)
},
inAfter (time, endAt) {
if (endAt === undefined) {
endAt = this.endAt
}
return (this.notAfterTime && time > this.notAfterTime) ||
return (
(this.notAfterTime && time > this.notAfterTime) ||
(endAt && time > this.getCriticalTime(endAt))
)
},
inDisabledDays (time) {
if (Array.isArray(this.disabledDays)) {
@@ -293,21 +297,37 @@ export default {
isDisabledYear (year) {
const time = new Date(year, 0).getTime()
const maxTime = new Date(year + 1, 0).getTime() - 1
return this.inBefore(maxTime) || this.inAfter(time) || (this.type === 'year' && this.inDisabledDays(time))
return (
this.inBefore(maxTime) ||
this.inAfter(time) ||
(this.type === 'year' && this.inDisabledDays(time))
)
},
isDisabledMonth (month) {
const time = new Date(this.calendarYear, month).getTime()
const maxTime = new Date(this.calendarYear, month + 1).getTime() - 1
return this.inBefore(maxTime) || this.inAfter(time) || (this.type === 'month' && this.inDisabledDays(time))
return (
this.inBefore(maxTime) ||
this.inAfter(time) ||
(this.type === 'month' && this.inDisabledDays(time))
)
},
isDisabledDate (date) {
const time = new Date(date).getTime()
const maxTime = new Date(date).setHours(23, 59, 59, 999)
return this.inBefore(maxTime) || this.inAfter(time) || this.inDisabledDays(time)
return (
this.inBefore(maxTime) ||
this.inAfter(time) ||
this.inDisabledDays(time)
)
},
isDisabledTime (date, startAt, endAt) {
const time = new Date(date).getTime()
return this.inBefore(time, startAt) || this.inAfter(time, endAt) || this.inDisabledDays(time)
return (
this.inBefore(time, startAt) ||
this.inAfter(time, endAt) ||
this.inDisabledDays(time)
)
},
selectDate (date) {
if (this.type === 'datetime') {
@@ -321,10 +341,16 @@ export default {
}
if (this.isDisabledTime(time)) {
time.setHours(0, 0, 0, 0)
if (this.notBefore && time.getTime() < new Date(this.notBefore).getTime()) {
if (
this.notBefore &&
time.getTime() < new Date(this.notBefore).getTime()
) {
time = new Date(this.notBefore)
}
if (this.startAt && time.getTime() < new Date(this.startAt).getTime()) {
if (
this.startAt &&
time.getTime() < new Date(this.startAt).getTime()
) {
time = new Date(this.startAt)
}
}
@@ -363,7 +389,9 @@ export default {
this.updateNow(new Date(this.calendarYear, month))
},
getSibling () {
const calendars = this.$parent.$children.filter(v => v.$options.name === this.$options.name)
const calendars = this.$parent.$children.filter(
v => v.$options.name === this.$options.name
)
const index = calendars.indexOf(this)
const sibling = calendars[index ^ 1]
return sibling
+73 -55
View File
@@ -9,6 +9,12 @@ export default {
return null
}
},
timeSelectOptions: {
type: Object,
default () {
return null
}
},
minuteStep: {
type: Number,
default: 0,
@@ -50,7 +56,7 @@ export default {
}
this.$emit('pick', new Date(time))
},
getTimeSelectOptions () {
getTimePickerOptions () {
const result = []
const options = this.timePickerOptions
if (!options) {
@@ -91,7 +97,7 @@ export default {
const disabledTime =
typeof this.disabledTime === 'function' && this.disabledTime
let pickers = this.getTimeSelectOptions()
let pickers = this.getTimePickerOptions()
if (Array.isArray(pickers) && pickers.length) {
pickers = pickers.map(picker => {
const pickHours = picker.value.hours
@@ -120,62 +126,74 @@ export default {
)
}
const hours = Array.apply(null, { length: 24 }).map((_, i) => {
const time = new Date(date).setHours(i)
return (
<li
class={{
cell: true,
actived: i === this.currentHours,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(i)}
</li>
)
})
const minuteStep = this.minuteStep || 1
const minuteLength = parseInt(60 / minuteStep)
let hours = Array.apply(null, { length: 24 }).map((_, i) => i)
let minutes = Array.apply(null, { length: minuteLength }).map(
(_, i) => i * minuteStep
)
let seconds =
this.minuteStep === 0
? Array.apply(null, { length: 60 }).map((_, i) => i)
: []
let columns = { hours, minutes, seconds }
const step = this.minuteStep || 1
const length = parseInt(60 / step)
const minutes = Array.apply(null, { length }).map((_, i) => {
const value = i * step
const time = new Date(date).setMinutes(value)
return (
<li
class={{
cell: true,
actived: value === this.currentMinutes,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(value)}
</li>
)
})
const seconds = Array.apply(null, { length: 60 }).map((_, i) => {
const time = new Date(date).setSeconds(i)
return (
<li
class={{
cell: true,
actived: i === this.currentSeconds,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(i)}
</li>
)
})
let times = [hours, minutes]
if (this.minuteStep === 0) {
times.push(seconds)
if (this.timeSelectOptions && typeof this.timeSelectOptions === 'object') {
columns = { ...columns, ...this.timeSelectOptions }
}
const hoursColumn = columns.hours.map(v => {
const time = new Date(date).setHours(v)
return (
<li
class={{
cell: true,
actived: v === this.currentHours,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(v)}
</li>
)
})
const minutesColumn = columns.minutes.map(v => {
const time = new Date(date).setMinutes(v)
return (
<li
class={{
cell: true,
actived: v === this.currentMinutes,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(v)}
</li>
)
})
const secondsColumn = columns.seconds.map(v => {
const time = new Date(date).setSeconds(v)
return (
<li
class={{
cell: true,
actived: v === this.currentSeconds,
disabled: disabledTime && disabledTime(time)
}}
onClick={this.selectTime.bind(this, time)}
>
{this.stringifyText(v)}
</li>
)
})
let times = [hoursColumn, minutesColumn, secondsColumn].filter(
v => v.length > 0
)
times = times.map(list => (
<ul class="mx-time-list" style={{ width: 100 / times.length + '%' }}>
{list}