mirror of
https://github.com/tenrok/vue2-datepicker.git
synced 2026-06-24 15:10:37 +03:00
feat: add prop date-format
This commit is contained in:
@@ -92,6 +92,7 @@ export default {
|
|||||||
| input-name | String | 'date' | the input name attr |
|
| input-name | String | 'date' | the input name attr |
|
||||||
| confirm-text | String | 'OK' | the default text to display on confirm button |
|
| confirm-text | String | 'OK' | the default text to display on confirm button |
|
||||||
| range-separator | String | '~' | the range separator text |
|
| range-separator | String | '~' | the range separator text |
|
||||||
|
| date-format | String | '' | format the time header and tooltip |
|
||||||
|
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ export default {
|
|||||||
| input-name | String | 'date' | 自定义input 的 name 属性
|
| input-name | String | 'date' | 自定义input 的 name 属性
|
||||||
| confirm-text | String | 'OK' | 确认按钮的名称
|
| confirm-text | String | 'OK' | 确认按钮的名称
|
||||||
| range-separator | String | '~' | range 分隔符
|
| range-separator | String | '~' | range 分隔符
|
||||||
|
| date-format | String | '' | 格式化时间组件头部和日历的tooltip,默认是format字段去除时间的格式化
|
||||||
|
|
||||||
#### lang
|
#### lang
|
||||||
* String (en/zh/es/pt-br/fr/ru/de/it/cs)
|
* String (en/zh/es/pt-br/fr/ru/de/it/cs)
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ new Vue({ // eslint-disable-line
|
|||||||
v-model="value3"
|
v-model="value3"
|
||||||
lang="en"
|
lang="en"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
format="YYYY-MM-DD HH:mm:ss"></date-picker>`,
|
format="[on] MM-DD-YYYY [at] HH:mm"></date-picker>`,
|
||||||
'datetime with time-picker-options': `
|
'datetime with time-picker-options': `
|
||||||
<date-picker
|
<date-picker
|
||||||
v-model="value4"
|
v-model="value4"
|
||||||
|
|||||||
+9
-5
@@ -37,6 +37,7 @@
|
|||||||
<panel-date
|
<panel-date
|
||||||
v-show="panel === 'DATE'"
|
v-show="panel === 'DATE'"
|
||||||
:value="value"
|
:value="value"
|
||||||
|
:date-format="dateFormat"
|
||||||
:calendar-month="calendarMonth"
|
:calendar-month="calendarMonth"
|
||||||
:calendar-year="calendarYear"
|
:calendar-year="calendarYear"
|
||||||
:start-at="startAt"
|
:start-at="startAt"
|
||||||
@@ -68,7 +69,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { isValidDate, isDateObejct } from '@/utils/index'
|
import { isValidDate, isDateObejct, formatDate } from '@/utils/index'
|
||||||
import locale from '@/mixins/locale'
|
import locale from '@/mixins/locale'
|
||||||
import scrollIntoView from '@/utils/scroll-into-view'
|
import scrollIntoView from '@/utils/scroll-into-view'
|
||||||
import PanelDate from '@/panel/date'
|
import PanelDate from '@/panel/date'
|
||||||
@@ -93,12 +94,15 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
// below user set
|
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'date' // ['date', 'datetime'] zendy added 'month', 'year'
|
default: 'date'
|
||||||
},
|
},
|
||||||
|
dateFormat: {
|
||||||
|
type: String,
|
||||||
|
default: 'YYYY-MM-DD'
|
||||||
|
},
|
||||||
|
// below user set
|
||||||
firstDayOfWeek: {
|
firstDayOfWeek: {
|
||||||
default: 7,
|
default: 7,
|
||||||
type: Number,
|
type: Number,
|
||||||
@@ -159,7 +163,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
timeHeader () {
|
timeHeader () {
|
||||||
return this.value && new Date(this.value).toLocaleDateString()
|
return this.value && formatDate(this.value, this.dateFormat)
|
||||||
},
|
},
|
||||||
yearHeader () {
|
yearHeader () {
|
||||||
return this.firstYear + ' ~ ' + (this.firstYear + 10)
|
return this.firstYear + ' ~ ' + (this.firstYear + 10)
|
||||||
|
|||||||
+28
-16
@@ -49,11 +49,11 @@
|
|||||||
ref="calendar">
|
ref="calendar">
|
||||||
<slot name="header">
|
<slot name="header">
|
||||||
<div class="mx-shortcuts-wrapper"
|
<div class="mx-shortcuts-wrapper"
|
||||||
v-if="range && innnerShortcuts.length">
|
v-if="range && innerShortcuts.length">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="mx-shortcuts"
|
class="mx-shortcuts"
|
||||||
v-for="(range, index) in innnerShortcuts"
|
v-for="(range, index) in innerShortcuts"
|
||||||
:key="index"
|
:key="index"
|
||||||
@click="selectRange(range)">{{range.text}}</button>
|
@click="selectRange(range)">{{range.text}}</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,6 +61,8 @@
|
|||||||
<calendar-panel
|
<calendar-panel
|
||||||
v-if="!range"
|
v-if="!range"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:type="type"
|
||||||
|
:date-format="innerDateFormat"
|
||||||
:value="currentValue"
|
:value="currentValue"
|
||||||
:visible="popupVisible"
|
:visible="popupVisible"
|
||||||
@select-date="selectDate"
|
@select-date="selectDate"
|
||||||
@@ -70,6 +72,8 @@
|
|||||||
<calendar-panel
|
<calendar-panel
|
||||||
style="box-shadow:1px 0 rgba(0, 0, 0, .1)"
|
style="box-shadow:1px 0 rgba(0, 0, 0, .1)"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:type="type"
|
||||||
|
:date-format="innerDateFormat"
|
||||||
:value="currentValue[0]"
|
:value="currentValue[0]"
|
||||||
:end-at="currentValue[1]"
|
:end-at="currentValue[1]"
|
||||||
:start-at="null"
|
:start-at="null"
|
||||||
@@ -78,6 +82,8 @@
|
|||||||
@select-time="selectStartTime"></calendar-panel>
|
@select-time="selectStartTime"></calendar-panel>
|
||||||
<calendar-panel
|
<calendar-panel
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:type="type"
|
||||||
|
:date-format="innerDateFormat"
|
||||||
:value="currentValue[1]"
|
:value="currentValue[1]"
|
||||||
:start-at="currentValue[0]"
|
:start-at="currentValue[0]"
|
||||||
:end-at="null"
|
:end-at="null"
|
||||||
@@ -100,7 +106,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import fecha from 'fecha'
|
import fecha from 'fecha'
|
||||||
import clickoutside from '@/directives/clickoutside'
|
import clickoutside from '@/directives/clickoutside'
|
||||||
import { isValidDate, isValidRange, isDateObejct, isPlainObject } from '@/utils/index'
|
import { isValidDate, isValidRange, isDateObejct, isPlainObject, formatDate, parseDate } from '@/utils/index'
|
||||||
import CalendarPanel from './calendar.vue'
|
import CalendarPanel from './calendar.vue'
|
||||||
import locale from '@/mixins/locale'
|
import locale from '@/mixins/locale'
|
||||||
import Languages from '@/locale/languages'
|
import Languages from '@/locale/languages'
|
||||||
@@ -127,6 +133,13 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'YYYY-MM-DD'
|
default: 'YYYY-MM-DD'
|
||||||
},
|
},
|
||||||
|
dateFormat: {
|
||||||
|
type: String // format the time header and date tooltip
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'date' // ['date', 'datetime'] zendy added 'month', 'year'
|
||||||
|
},
|
||||||
range: {
|
range: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@@ -226,7 +239,7 @@ export default {
|
|||||||
showClearIcon () {
|
showClearIcon () {
|
||||||
return !this.disabled && this.clearable && (this.range ? isValidRange(this.value) : isValidDate(this.value))
|
return !this.disabled && this.clearable && (this.range ? isValidRange(this.value) : isValidDate(this.value))
|
||||||
},
|
},
|
||||||
innnerShortcuts () {
|
innerShortcuts () {
|
||||||
if (Array.isArray(this.shortcuts)) {
|
if (Array.isArray(this.shortcuts)) {
|
||||||
return this.shortcuts
|
return this.shortcuts
|
||||||
}
|
}
|
||||||
@@ -265,6 +278,15 @@ export default {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
return arr
|
return arr
|
||||||
|
},
|
||||||
|
innerDateFormat () {
|
||||||
|
if (this.dateFormat) {
|
||||||
|
return this.dateFormat
|
||||||
|
}
|
||||||
|
if (this.type === 'date') {
|
||||||
|
return this.format
|
||||||
|
}
|
||||||
|
return this.format.replace(/[Hh]+.*[msSaAZ]|\[.*?\]/g, '').trim() || 'YYYY-MM-DD'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -273,20 +295,10 @@ export default {
|
|||||||
this.displayPopup()
|
this.displayPopup()
|
||||||
},
|
},
|
||||||
stringify (date, format) {
|
stringify (date, format) {
|
||||||
try {
|
return formatDate(date, format || this.format)
|
||||||
format = format || this.format
|
|
||||||
return fecha.format(new Date(date), format)
|
|
||||||
} catch (e) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
parseDate (value, format) {
|
parseDate (value, format) {
|
||||||
try {
|
return parseDate(value, format || this.format)
|
||||||
format = format || this.format
|
|
||||||
return fecha.parse(value, format)
|
|
||||||
} catch (e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
dateEqual (a, b) {
|
dateEqual (a, b) {
|
||||||
return isDateObejct(a) && isDateObejct(b) && a.getTime() === b.getTime()
|
return isDateObejct(a) && isDateObejct(b) && a.getTime() === b.getTime()
|
||||||
|
|||||||
+6
-2
@@ -1,4 +1,5 @@
|
|||||||
import locale from '@/mixins/locale'
|
import locale from '@/mixins/locale'
|
||||||
|
import { formatDate } from '@/utils/index'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'panelDate',
|
name: 'panelDate',
|
||||||
@@ -7,6 +8,10 @@ export default {
|
|||||||
value: null,
|
value: null,
|
||||||
startAt: null,
|
startAt: null,
|
||||||
endAt: null,
|
endAt: null,
|
||||||
|
dateFormat: {
|
||||||
|
type: String,
|
||||||
|
default: 'YYYY-MM-DD'
|
||||||
|
},
|
||||||
calendarMonth: {
|
calendarMonth: {
|
||||||
default: new Date().getMonth()
|
default: new Date().getMonth()
|
||||||
},
|
},
|
||||||
@@ -96,11 +101,10 @@ export default {
|
|||||||
classes.push('inrange')
|
classes.push('inrange')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return classes
|
return classes
|
||||||
},
|
},
|
||||||
getCellTitle ({ year, month, day }) {
|
getCellTitle ({ year, month, day }) {
|
||||||
return new Date(year, month, day).toLocaleDateString()
|
return formatDate(new Date(year, month, day), this.dateFormat)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
render (h) {
|
render (h) {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import fecha from 'fecha'
|
||||||
|
|
||||||
export function isPlainObject (obj) {
|
export function isPlainObject (obj) {
|
||||||
return Object.prototype.toString.call(obj) === '[object Object]'
|
return Object.prototype.toString.call(obj) === '[object Object]'
|
||||||
}
|
}
|
||||||
@@ -47,3 +49,19 @@ export function formatTime (time, type = '24') {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatDate (date, format) {
|
||||||
|
try {
|
||||||
|
return fecha.format(new Date(date), format)
|
||||||
|
} catch (e) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseDate (value, format) {
|
||||||
|
try {
|
||||||
|
return fecha.parse(value, format)
|
||||||
|
} catch (e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+25
-4
@@ -77,12 +77,12 @@ describe('datepicker', () => {
|
|||||||
expect(td2.at(13).classes()).toContain('disabled')
|
expect(td2.at(13).classes()).toContain('disabled')
|
||||||
expect(td2.at(14).classes()).not.toContain('disabled')
|
expect(td2.at(14).classes()).not.toContain('disabled')
|
||||||
|
|
||||||
const date1 = new Date(td1.at(14).element.title)
|
const date1 = new Date(td1.at(14).element.title).setHours(0, 0, 0, 0)
|
||||||
td2.at(16).trigger('click')
|
td2.at(16).trigger('click')
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
emitted = wrapper.emittedByOrder()
|
emitted = wrapper.emittedByOrder()
|
||||||
|
|
||||||
const date2 = new Date(td2.at(16).element.title)
|
const date2 = new Date(td2.at(16).element.title).setHours(0, 0, 0, 0)
|
||||||
|
|
||||||
expect(td2.at(16).classes()).toContain('actived')
|
expect(td2.at(16).classes()).toContain('actived')
|
||||||
expect(td1.at(15).classes()).toContain('inrange')
|
expect(td1.at(15).classes()).toContain('inrange')
|
||||||
@@ -90,7 +90,7 @@ describe('datepicker', () => {
|
|||||||
expect(td1.at(17).classes()).toContain('disabled')
|
expect(td1.at(17).classes()).toContain('disabled')
|
||||||
|
|
||||||
expect(emitted).toHaveLength(2)
|
expect(emitted).toHaveLength(2)
|
||||||
expect(emitted[0].args[0]).toEqual([date1, date2])
|
expect(emitted[0].args[0]).toEqual([new Date(date1), new Date(date2)])
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -259,6 +259,27 @@ describe('datepicker', () => {
|
|||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('prop: dateFormat', () => {
|
||||||
|
wrapper = mount(DatePicker, {
|
||||||
|
propsData: {
|
||||||
|
value: new Date('2018-08-08'),
|
||||||
|
format: '[on] MM-DD-YYYY [at] HH:mm',
|
||||||
|
type: 'datetime'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let ss = '08-08-2018'
|
||||||
|
const cell = wrapper.find('.mx-panel-date .actived')
|
||||||
|
const timeHeader = wrapper.find('.mx-time-header')
|
||||||
|
expect(cell.element.title).toBe(ss)
|
||||||
|
expect(timeHeader.text()).toBe(ss)
|
||||||
|
wrapper.setProps({
|
||||||
|
dateFormat: 'YYYY-MM-DD'
|
||||||
|
})
|
||||||
|
ss = '2018-08-08'
|
||||||
|
expect(cell.element.title).toBe(ss)
|
||||||
|
expect(timeHeader.text()).toBe(ss)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('calendar-panel', () => {
|
describe('calendar-panel', () => {
|
||||||
@@ -358,7 +379,7 @@ describe('calendar-panel', () => {
|
|||||||
const tds = wrapper.findAll('.mx-panel-date td.disabled')
|
const tds = wrapper.findAll('.mx-panel-date td.disabled')
|
||||||
expect(tds.length).toBe(disabledDays.length)
|
expect(tds.length).toBe(disabledDays.length)
|
||||||
for (let i = 0, len = tds.length; i < len; i++) {
|
for (let i = 0, len = tds.length; i < len; i++) {
|
||||||
const tdDate = new Date(tds.at(i).element.title).getTime()
|
const tdDate = new Date(tds.at(i).element.title).setHours(0, 0, 0, 0)
|
||||||
const expectDate = new Date(disabledDays[i]).setHours(0, 0, 0, 0)
|
const expectDate = new Date(disabledDays[i]).setHours(0, 0, 0, 0)
|
||||||
expect(tdDate).toBe(expectDate)
|
expect(tdDate).toBe(expectDate)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user