feat: add multiFormats

pull/398/head
tangjinzhou 2018-12-27 22:14:32 +08:00
parent 2596c9732c
commit a47c6ef75b
7 changed files with 140 additions and 72 deletions

View File

@ -1,21 +1,21 @@
export default { export default {
directives: { // directives: {
ref: { // ref: {
bind: function (el, binding, vnode) { // bind: function (el, binding, vnode) {
binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) // binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm)
}, // },
update: function (el, binding, vnode) { // update: function (el, binding, vnode) {
binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm) // binding.value(vnode.componentInstance ? vnode.componentInstance : vnode.elm)
}, // },
unbind: function (el, binding, vnode) { // unbind: function (el, binding, vnode) {
binding.value(null) // binding.value(null)
}, // },
}, // },
}, // },
methods: { methods: {
setState (state, callback) { setState (state, callback) {
const newState = typeof state === 'function' ? state(this.$data) : state const newState = typeof state === 'function' ? state(this.$data, this.$props) : state
// if (this.getDerivedStateFromProps) { // if (this.getDerivedStateFromProps) {
// Object.assign(newState, this.getDerivedStateFromProps(getOptionProps(this), { ...this.$data, ...newState }, true) || {}) // Object.assign(newState, this.getDerivedStateFromProps(getOptionProps(this), { ...this.$data, ...newState }, true) || {})
// } // }

View File

@ -183,6 +183,39 @@ const Demo = {
}, },
} }
const multiFormats = ['DD/MM/YYYY', 'DD/MM/YY', 'DDMMYY', 'D/M/YY']
const DemoMultiFormat = {
data: () => ({
value: now,
}),
methods: {
onChange (value) {
console.log('Calendar change: ', (value && value.format(format)))
this.value = value
},
},
render () {
const state = this.$data
return (<div style={{ width: '400px', margin: '20px' }}>
<div style={{ marginBottom: '10px' }}>
Accepts multiple input formats
<br/>
<small>{multiFormats.join(', ')}</small>
</div>
<Calendar
locale={cn ? zhCN : enUS}
style={{ zIndex: 1000 }}
dateInputPlaceholder='please input'
format={multiFormats}
value={state.value}
onChange={this.onChange}
/>
</div>)
},
}
function onStandaloneSelect (value) { function onStandaloneSelect (value) {
console.log('onStandaloneSelect') console.log('onStandaloneSelect')
console.log(value && value.format(format)) console.log(value && value.format(format))
@ -212,7 +245,7 @@ export default {
defaultValue={now} defaultValue={now}
disabledTime={disabledTime} disabledTime={disabledTime}
showToday showToday
formatter={getFormat(true)} format={getFormat(true)}
showOk={false} showOk={false}
timePicker={timePickerElement(h)} timePicker={timePickerElement(h)}
onChange={onStandaloneChange} onChange={onStandaloneChange}
@ -228,6 +261,9 @@ export default {
<Demo defaultCalendarValue={defaultCalendarValue} /> <Demo defaultCalendarValue={defaultCalendarValue} />
</div> </div>
<div style={{ clear: 'both' }}></div> <div style={{ clear: 'both' }}></div>
<div>
<DemoMultiFormat />
</div>
</div> </div>
</div> </div>
) )

View File

@ -1,3 +1,3 @@
// based on rc-calendar 9.7.9 // based on rc-calendar 9.8.2
import Calendar from './src/' import Calendar from './src/'
export default Calendar export default Calendar

View File

@ -26,7 +26,7 @@ const MomentType = PropTypes.custom(isMoment)
const Calendar = { const Calendar = {
props: { props: {
locale: PropTypes.object.def(enUs), locale: PropTypes.object.def(enUs),
format: PropTypes.string, format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
visible: PropTypes.bool.def(true), visible: PropTypes.bool.def(true),
prefixCls: PropTypes.string.def('rc-calendar'), prefixCls: PropTypes.string.def('rc-calendar'),
// prefixCls: PropTypes.string, // prefixCls: PropTypes.string,
@ -295,7 +295,9 @@ const Calendar = {
selectedValue={sSelectedValue} selectedValue={sSelectedValue}
value={sValue} value={sValue}
disabledDate={disabledDate} disabledDate={disabledDate}
okDisabled={!this.isAllowedDate(sSelectedValue)} okDisabled={
props.showOk !== false && (!sSelectedValue || !this.isAllowedDate(sSelectedValue))
}
onOk={this.onOk} onOk={this.onOk}
onSelect={this.onSelect} onSelect={this.onSelect}
onToday={this.onToday} onToday={this.onToday}

View File

@ -3,6 +3,7 @@ import PropTypes from '../../../_util/vue-types'
import BaseMixin from '../../../_util/BaseMixin' import BaseMixin from '../../../_util/BaseMixin'
import { getComponentFromProp } from '../../../_util/props-util' import { getComponentFromProp } from '../../../_util/props-util'
import moment from 'moment' import moment from 'moment'
import { formatDate } from '../util'
const DateInput = { const DateInput = {
mixins: [BaseMixin], mixins: [BaseMixin],
@ -11,7 +12,7 @@ const DateInput = {
timePicker: PropTypes.object, timePicker: PropTypes.object,
value: PropTypes.object, value: PropTypes.object,
disabledTime: PropTypes.any, disabledTime: PropTypes.any,
format: PropTypes.string, format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
locale: PropTypes.object, locale: PropTypes.object,
disabledDate: PropTypes.func, disabledDate: PropTypes.func,
// onChange: PropTypes.func, // onChange: PropTypes.func,
@ -25,8 +26,9 @@ const DateInput = {
data () { data () {
const selectedValue = this.selectedValue const selectedValue = this.selectedValue
return { return {
str: selectedValue && selectedValue.format(this.format) || '', str: formatDate(selectedValue, this.format),
invalid: false, invalid: false,
hasFocus: false,
} }
}, },
watch: { watch: {
@ -40,7 +42,7 @@ const DateInput = {
updated () { updated () {
this.$nextTick(() => { this.$nextTick(() => {
if (!this.invalid && if (this.$data.hasFocus && !this.invalid &&
!(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) { !(this.cachedSelectionStart === 0 && this.cachedSelectionEnd === 0)) {
this.$refs.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd) this.$refs.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd)
} }
@ -52,27 +54,36 @@ const DateInput = {
this.cachedSelectionEnd = this.$refs.dateInputInstance.selectionEnd this.cachedSelectionEnd = this.$refs.dateInputInstance.selectionEnd
// when popup show, click body will call this, bug! // when popup show, click body will call this, bug!
const selectedValue = this.selectedValue const selectedValue = this.selectedValue
if (!this.$data.hasFocus) {
this.setState({ this.setState({
str: selectedValue && selectedValue.format(this.format) || '', str: formatDate(selectedValue, this.format),
invalid: false, invalid: false,
}) })
}
}, },
onInputChange (event) { onInputChange (event) {
const str = event.target.value const str = event.target.value
const { disabledDate, format, selectedValue } = this.$props
// 退
if (!str) {
this.__emit('change', null)
this.setState({ this.setState({
invalid: false,
str, str,
}) })
let value return
const { disabledDate, format } = this }
if (str) {
const parsed = moment(str, format, true) const parsed = moment(str, format, true)
if (!parsed.isValid()) { if (!parsed.isValid()) {
this.setState({ this.setState({
invalid: true, invalid: true,
str,
}) })
return return
} }
value = this.value.clone() const value = this.value.clone()
value value
.year(parsed.year()) .year(parsed.year())
.month(parsed.month()) .month(parsed.month())
@ -81,27 +92,22 @@ const DateInput = {
.minute(parsed.minute()) .minute(parsed.minute())
.second(parsed.second()) .second(parsed.second())
if (value && (!disabledDate || !disabledDate(value))) { if (!value || (disabledDate && disabledDate(value))) {
const originalValue = this.selectedValue
if (originalValue && value) {
if (!originalValue.isSame(value)) {
this.__emit('change', value)
}
} else if (originalValue !== value) {
this.__emit('change', value)
}
} else {
this.setState({ this.setState({
invalid: true, invalid: true,
str,
}) })
return return
} }
} else {
this.__emit('change', null) if (selectedValue !== value || (
} selectedValue && value && !selectedValue.isSame(value)
)) {
this.setState({ this.setState({
invalid: false, str,
}) })
this.__emit('change', value)
}
}, },
onClear () { onClear () {
@ -120,6 +126,16 @@ const DateInput = {
this.$refs.dateInputInstance.focus() this.$refs.dateInputInstance.focus()
} }
}, },
onFocus () {
this.setState({ hasFocus: true })
},
onBlur () {
this.setState((prevState, prevProps) => ({
hasFocus: false,
str: formatDate(prevProps.value, prevProps.format),
}))
},
}, },
render () { render () {
@ -135,6 +151,8 @@ const DateInput = {
disabled={disabled} disabled={disabled}
placeholder={placeholder} placeholder={placeholder}
onInput={this.onInputChange} onInput={this.onInputChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
/> />
</div> </div>
{showClear ? <a {showClear ? <a

View File

@ -1,16 +1,16 @@
export default { export default {
today: 'Oggi', today: 'Oggi',
now: 'adesso', now: 'Adesso',
backToToday: 'Torna ad oggi', backToToday: 'Torna ad oggi',
ok: 'Ok', ok: 'Ok',
clear: 'Chiaro', clear: 'Cancella',
month: 'Mese', month: 'Mese',
year: 'Anno', year: 'Anno',
timeSelect: 'Seleziona il tempo', timeSelect: 'Seleziona l\'ora',
dateSelect: 'Select date', dateSelect: 'Seleziona la data',
monthSelect: 'Seleziona la data', monthSelect: 'Seleziona il mese',
yearSelect: 'Scegli un anno', yearSelect: 'Seleziona l\'anno',
decadeSelect: 'Scegli un decennio', decadeSelect: 'Seleziona il decennio',
yearFormat: 'YYYY', yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY', dateFormat: 'D/M/YYYY',
dayFormat: 'D', dayFormat: 'D',

View File

@ -89,3 +89,15 @@ export function isAllowedDate (value, disabledDate, disabledTime) {
} }
return true return true
} }
export function formatDate (value, format) {
if (!value) {
return ''
}
if (Array.isArray(format)) {
format = format[0]
}
return value.format(format)
}