211 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Vue
		
	
	
| 
 | |
| import PropTypes from '../_util/vue-types'
 | |
| import BaseMixin from '../_util/BaseMixin'
 | |
| import moment from 'moment'
 | |
| import { getComponentFromProp } from '../_util/props-util'
 | |
| 
 | |
| const Header = {
 | |
|   mixins: [BaseMixin],
 | |
|   props: {
 | |
|     format: PropTypes.string,
 | |
|     prefixCls: PropTypes.string,
 | |
|     disabledDate: PropTypes.func,
 | |
|     placeholder: PropTypes.string,
 | |
|     clearText: PropTypes.string,
 | |
|     value: PropTypes.object,
 | |
|     inputReadOnly: PropTypes.bool.def(false),
 | |
|     hourOptions: PropTypes.array,
 | |
|     minuteOptions: PropTypes.array,
 | |
|     secondOptions: PropTypes.array,
 | |
|     disabledHours: PropTypes.func,
 | |
|     disabledMinutes: PropTypes.func,
 | |
|     disabledSeconds: PropTypes.func,
 | |
|     // onChange: PropTypes.func,
 | |
|     // onClear: PropTypes.func,
 | |
|     // onEsc: PropTypes.func,
 | |
|     allowEmpty: PropTypes.bool,
 | |
|     defaultOpenValue: PropTypes.object,
 | |
|     currentSelectPanel: PropTypes.string,
 | |
|     focusOnOpen: PropTypes.bool,
 | |
|     // onKeyDown: PropTypes.func,
 | |
|     showStr: PropTypes.bool.def(true),
 | |
|     clearIcon: PropTypes.any,
 | |
|   },
 | |
|   data () {
 | |
|     const { value, format } = this
 | |
|     return {
 | |
|       str: value && value.format(format) || '',
 | |
|       invalid: false,
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   mounted () {
 | |
|     if (this.focusOnOpen) {
 | |
|       // Wait one frame for the panel to be positioned before focusing
 | |
|       const requestAnimationFrame = (window.requestAnimationFrame || window.setTimeout)
 | |
|       requestAnimationFrame(() => {
 | |
|         this.$refs.input.focus()
 | |
|         this.$refs.input.select()
 | |
|       })
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     '$props': {
 | |
|       handler: function (nextProps) {
 | |
|         const { value, format } = nextProps
 | |
|         this.setState({
 | |
|           str: value && value.format(format) || '',
 | |
|           invalid: false,
 | |
|         })
 | |
|       },
 | |
|       deep: true,
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     onInputChange (event) {
 | |
|       const str = event.target.value
 | |
|       this.showStr = true
 | |
|       this.setState({
 | |
|         str,
 | |
|       })
 | |
|       const {
 | |
|         format, hourOptions, minuteOptions, secondOptions,
 | |
|         disabledHours, disabledMinutes,
 | |
|         disabledSeconds, allowEmpty,
 | |
|         value: originalValue,
 | |
|       } = this
 | |
| 
 | |
|       if (str) {
 | |
|         const value = this.getProtoValue().clone()
 | |
|         const parsed = moment(str, format, true)
 | |
|         if (!parsed.isValid()) {
 | |
|           this.setState({
 | |
|             invalid: true,
 | |
|           })
 | |
|           return
 | |
|         }
 | |
|         value.hour(parsed.hour()).minute(parsed.minute()).second(parsed.second())
 | |
| 
 | |
|         // if time value not allowed, response warning.
 | |
|         if (
 | |
|           hourOptions.indexOf(value.hour()) < 0 ||
 | |
|         minuteOptions.indexOf(value.minute()) < 0 ||
 | |
|         secondOptions.indexOf(value.second()) < 0
 | |
|         ) {
 | |
|           this.setState({
 | |
|             invalid: true,
 | |
|           })
 | |
|           return
 | |
|         }
 | |
| 
 | |
|         // if time value is disabled, response warning.
 | |
|         const disabledHourOptions = disabledHours()
 | |
|         const disabledMinuteOptions = disabledMinutes(value.hour())
 | |
|         const disabledSecondOptions = disabledSeconds(value.hour(), value.minute())
 | |
|         if (
 | |
|           (disabledHourOptions && disabledHourOptions.indexOf(value.hour()) >= 0) ||
 | |
|         (disabledMinuteOptions && disabledMinuteOptions.indexOf(value.minute()) >= 0) ||
 | |
|         (disabledSecondOptions && disabledSecondOptions.indexOf(value.second()) >= 0)
 | |
|         ) {
 | |
|           this.setState({
 | |
|             invalid: true,
 | |
|           })
 | |
|           return
 | |
|         }
 | |
| 
 | |
|         if (originalValue) {
 | |
|           if (
 | |
|             originalValue.hour() !== value.hour() ||
 | |
|           originalValue.minute() !== value.minute() ||
 | |
|           originalValue.second() !== value.second()
 | |
|           ) {
 | |
|           // keep other fields for rc-calendar
 | |
|             const changedValue = originalValue.clone()
 | |
|             changedValue.hour(value.hour())
 | |
|             changedValue.minute(value.minute())
 | |
|             changedValue.second(value.second())
 | |
|             this.__emit('change', changedValue)
 | |
|           }
 | |
|         } else if (originalValue !== value) {
 | |
|           this.__emit('change', value)
 | |
|         }
 | |
|       } else if (allowEmpty) {
 | |
|         this.__emit('change', null)
 | |
|       } else {
 | |
|         this.setState({
 | |
|           invalid: true,
 | |
|         })
 | |
|         return
 | |
|       }
 | |
| 
 | |
|       this.setState({
 | |
|         invalid: false,
 | |
|       })
 | |
|     },
 | |
| 
 | |
|     onKeyDown (e) {
 | |
|       if (e.keyCode === 27) {
 | |
|         this.__emit('esc')
 | |
|       }
 | |
|       this.__emit('keydown', e)
 | |
|     },
 | |
| 
 | |
|     onClear () {
 | |
|       this.__emit('clear')
 | |
|       this.setState({ str: '' })
 | |
|     },
 | |
| 
 | |
|     getClearButton () {
 | |
|       const { prefixCls, allowEmpty, clearText } = this
 | |
|       const clearIcon = getComponentFromProp(this, 'clearIcon')
 | |
|       if (!allowEmpty) {
 | |
|         return null
 | |
|       }
 | |
|       return (
 | |
|         <a
 | |
|           role='button'
 | |
|           class={`${prefixCls}-clear-btn`}
 | |
|           title={clearText}
 | |
|           onMousedown={this.onClear}
 | |
|         >
 | |
|           {clearIcon || <i class={`${prefixCls}-clear-btn-icon`} />}
 | |
|         </a>
 | |
|       )
 | |
|     },
 | |
| 
 | |
|     getProtoValue () {
 | |
|       return this.value || this.defaultOpenValue
 | |
|     },
 | |
| 
 | |
|     getInput () {
 | |
|       const { prefixCls, placeholder, inputReadOnly, invalid, str, showStr } = this
 | |
|       const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''
 | |
|       return (
 | |
|         <input
 | |
|           class={`${prefixCls}-input ${invalidClass}`}
 | |
|           ref='input'
 | |
|           onKeydown={this.onKeyDown}
 | |
|           value={showStr ? str : ''}
 | |
|           placeholder={placeholder}
 | |
|           onInput={this.onInputChange}
 | |
|           readOnly={!!inputReadOnly}
 | |
|         />
 | |
|       )
 | |
|     },
 | |
|   },
 | |
| 
 | |
|   render () {
 | |
|     const { prefixCls } = this
 | |
|     return (
 | |
|       <div class={`${prefixCls}-input-wrap`}>
 | |
|         {this.getInput()}
 | |
|         {this.getClearButton()}
 | |
|       </div>
 | |
|     )
 | |
|   },
 | |
| }
 | |
| 
 | |
| export default Header
 | |
| 
 |