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:
@@ -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 |
|
||||
|-----------------|--------------------------------------------------------|------------------------|
|
||||
|
||||
@@ -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
@@ -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
@@ -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)">«</a>
|
||||
<a
|
||||
v-show="panel === 'DATE'"
|
||||
class="mx-icon-last-month"
|
||||
@click="handleIconMonth(-1)">‹</a>
|
||||
<a
|
||||
v-show="panel !== 'TIME'"
|
||||
class="mx-icon-next-year"
|
||||
@click="handleIconYear(1)">»</a>
|
||||
<a
|
||||
v-show="panel === 'DATE'"
|
||||
class="mx-icon-next-month"
|
||||
@click="handleIconMonth(1)">›</a>
|
||||
<a v-show="panel !== 'TIME'" class="mx-icon-last-year" @click="handleIconYear(-1)">«</a>
|
||||
<a v-show="panel === 'DATE'" class="mx-icon-last-month" @click="handleIconMonth(-1)">‹</a>
|
||||
<a v-show="panel !== 'TIME'" class="mx-icon-next-year" @click="handleIconYear(1)">»</a>
|
||||
<a v-show="panel === 'DATE'" class="mx-icon-next-month" @click="handleIconMonth(1)">›</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
@@ -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}
|
||||
|
||||
Reference in New Issue
Block a user