2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-06-24 09:30:36 +03:00

feat: add prop date-format

This commit is contained in:
mxie
2018-08-07 12:04:53 +08:00
parent a2e4230d8d
commit 3c27647ff3
8 changed files with 90 additions and 29 deletions
+1
View File
@@ -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
+2 -1
View File
@@ -91,7 +91,8 @@ export default {
| input-class | String | 'mx-input' | 自定义输入框的类名 | input-class | String | 'mx-input' | 自定义输入框的类名
| 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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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) {
+18
View File
@@ -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
View File
@@ -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)
} }