| | |
| | | 'use strict'; |
| | | |
| | | var assign = require('object-assign'), |
| | | PropTypes = require('prop-types'), |
| | | createClass = require('create-react-class'), |
| | | moment = require('moment'), |
| | | React = require('react'), |
| | | CalendarContainer = require('./src/CalendarContainer') |
| | | ; |
| | | ; |
| | | |
| | | var TYPES = React.PropTypes; |
| | | var Datetime = React.createClass({ |
| | | var TYPES = PropTypes; |
| | | var Datetime = createClass({ |
| | | propTypes: { |
| | | // value: TYPES.object | TYPES.string, |
| | | // defaultValue: TYPES.object | TYPES.string, |
| | | onFocus: TYPES.func, |
| | | onBlur: TYPES.func, |
| | | onChange: TYPES.func, |
| | | onViewModeChange: TYPES.func, |
| | | locale: TYPES.string, |
| | | utc: TYPES.bool, |
| | | input: TYPES.bool, |
| | |
| | | strictParsing: TYPES.bool, |
| | | closeOnSelect: TYPES.bool, |
| | | closeOnTab: TYPES.bool |
| | | }, |
| | | |
| | | getDefaultProps: function() { |
| | | var nof = function() {}; |
| | | return { |
| | | className: '', |
| | | defaultValue: '', |
| | | inputProps: {}, |
| | | input: true, |
| | | onFocus: nof, |
| | | onBlur: nof, |
| | | onChange: nof, |
| | | timeFormat: true, |
| | | timeConstraints: {}, |
| | | dateFormat: true, |
| | | strictParsing: true, |
| | | closeOnSelect: false, |
| | | closeOnTab: true, |
| | | utc: false |
| | | }; |
| | | }, |
| | | |
| | | getInitialState: function() { |
| | |
| | | var formats = this.getFormats( props ), |
| | | date = props.value || props.defaultValue, |
| | | selectedDate, viewDate, updateOn, inputValue |
| | | ; |
| | | ; |
| | | |
| | | if ( date && typeof date === 'string' ) |
| | | selectedDate = this.localMoment( date, formats.datetime ); |
| | |
| | | getUpdateOn: function( formats ) { |
| | | if ( formats.date.match(/[lLD]/) ) { |
| | | return 'days'; |
| | | } |
| | | else if ( formats.date.indexOf('M') !== -1 ) { |
| | | } else if ( formats.date.indexOf('M') !== -1 ) { |
| | | return 'months'; |
| | | } |
| | | else if ( formats.date.indexOf('Y') !== -1 ) { |
| | | } else if ( formats.date.indexOf('Y') !== -1 ) { |
| | | return 'years'; |
| | | } |
| | | |
| | |
| | | time: props.timeFormat || '' |
| | | }, |
| | | locale = this.localMoment( props.date, null, props ).localeData() |
| | | ; |
| | | ; |
| | | |
| | | if ( formats.date === true ) { |
| | | formats.date = locale.longDateFormat('L'); |
| | |
| | | } |
| | | |
| | | if ( updatedState.open === undefined ) { |
| | | if ( this.props.closeOnSelect && this.state.currentView !== 'time' ) { |
| | | if ( typeof nextProps.open !== 'undefined' ) { |
| | | updatedState.open = nextProps.open; |
| | | } else if ( this.props.closeOnSelect && this.state.currentView !== 'time' ) { |
| | | updatedState.open = false; |
| | | } else { |
| | | updatedState.open = this.state.open; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | //we should only show a valid date if we are provided a isValidDate function. Removed in 2.10.3 |
| | | /*if (this.props.isValidDate) { |
| | | updatedState.viewDate = updatedState.viewDate || this.state.viewDate; |
| | | while (!this.props.isValidDate(updatedState.viewDate)) { |
| | | updatedState.viewDate = updatedState.viewDate.add(1, 'day'); |
| | | } |
| | | }*/ |
| | | this.setState( updatedState ); |
| | | }, |
| | | |
| | |
| | | var value = e.target === null ? e : e.target.value, |
| | | localMoment = this.localMoment( value, this.state.inputFormat ), |
| | | update = { inputValue: value } |
| | | ; |
| | | ; |
| | | |
| | | if ( localMoment.isValid() && !this.props.value ) { |
| | | update.selectedDate = localMoment; |
| | | update.viewDate = localMoment.clone().startOf('month'); |
| | | } |
| | | else { |
| | | } else { |
| | | update.selectedDate = null; |
| | | } |
| | | |
| | |
| | | showView: function( view ) { |
| | | var me = this; |
| | | return function() { |
| | | me.state.currentView !== view && me.props.onViewModeChange( view ); |
| | | me.setState({ currentView: view }); |
| | | }; |
| | | }, |
| | |
| | | viewDate: me.state.viewDate.clone()[ type ]( parseInt(e.target.getAttribute('data-value'), 10) ).startOf( type ), |
| | | currentView: nextViews[ type ] |
| | | }); |
| | | me.props.onViewModeChange( nextViews[ type ] ); |
| | | }; |
| | | }, |
| | | |
| | |
| | | state = this.state, |
| | | date = (state.selectedDate || state.viewDate).clone(), |
| | | nextType |
| | | ; |
| | | ; |
| | | |
| | | // It is needed to set all the time properties |
| | | // to not to reset the time |
| | |
| | | viewDate = this.state.viewDate, |
| | | currentDate = this.state.selectedDate || viewDate, |
| | | date |
| | | ; |
| | | ; |
| | | |
| | | if (target.className.indexOf('rdtDay') !== -1) { |
| | | if (target.className.indexOf('rdtNew') !== -1) |
| | |
| | | this.props.onChange( date ); |
| | | }, |
| | | |
| | | openCalendar: function() { |
| | | if (!this.state.open) { |
| | | openCalendar: function( e ) { |
| | | if ( !this.state.open ) { |
| | | this.setState({ open: true }, function() { |
| | | this.props.onFocus(); |
| | | this.props.onFocus( e ); |
| | | }); |
| | | } |
| | | }, |
| | |
| | | componentProps: { |
| | | fromProps: ['value', 'isValidDate', 'renderDay', 'renderMonth', 'renderYear', 'timeConstraints'], |
| | | fromState: ['viewDate', 'selectedDate', 'updateOn'], |
| | | fromThis: ['setDate', 'setTime', 'showView', 'addTime', 'subtractTime', 'updateSelectedDate', 'localMoment'] |
| | | fromThis: ['setDate', 'setTime', 'showView', 'addTime', 'subtractTime', 'updateSelectedDate', 'localMoment', 'handleClickOutside'] |
| | | }, |
| | | |
| | | getComponentProps: function() { |
| | | var me = this, |
| | | formats = this.getFormats( this.props ), |
| | | props = {dateFormat: formats.date, timeFormat: formats.time} |
| | | ; |
| | | ; |
| | | |
| | | this.componentProps.fromProps.forEach( function( name ) { |
| | | props[ name ] = me.props[ name ]; |
| | |
| | | }, |
| | | |
| | | render: function() { |
| | | var DOM = React.DOM, |
| | | className = 'rdt' + (this.props.className ? |
| | | // TODO: Make a function or clean up this code, |
| | | // logic right now is really hard to follow |
| | | var className = 'rdt' + (this.props.className ? |
| | | ( Array.isArray( this.props.className ) ? |
| | | ' ' + this.props.className.join( ' ' ) : ' ' + this.props.className) : ''), |
| | | children = [] |
| | | ; |
| | | children = []; |
| | | |
| | | if ( this.props.input ) { |
| | | children = [ DOM.input( assign({ |
| | | key: 'i', |
| | | var finalInputProps = assign({ |
| | | type: 'text', |
| | | className: 'form-control', |
| | | onClick: this.openCalendar, |
| | | onFocus: this.openCalendar, |
| | | onChange: this.onInputChange, |
| | | onKeyDown: this.onInputKey, |
| | | value: this.state.inputValue |
| | | }, this.props.inputProps ))]; |
| | | value: this.state.inputValue, |
| | | }, this.props.inputProps); |
| | | if ( this.props.renderInput ) { |
| | | children = [ React.createElement('div', { key: 'i' }, this.props.renderInput( finalInputProps, this.openCalendar, this.closeCalendar )) ]; |
| | | } else { |
| | | children = [ React.createElement('input', assign({ key: 'i' }, finalInputProps ))]; |
| | | } |
| | | } else { |
| | | className += ' rdtStatic'; |
| | | } |
| | |
| | | if ( this.state.open ) |
| | | className += ' rdtOpen'; |
| | | |
| | | return DOM.div({className: className}, children.concat( |
| | | DOM.div( |
| | | return React.createElement( 'div', { className: className }, children.concat( |
| | | React.createElement( 'div', |
| | | { key: 'dt', className: 'rdtPicker' }, |
| | | React.createElement( CalendarContainer, {view: this.state.currentView, viewProps: this.getComponentProps(), onClickOutside: this.handleClickOutside }) |
| | | React.createElement( CalendarContainer, { view: this.state.currentView, viewProps: this.getComponentProps(), onClickOutside: this.handleClickOutside }) |
| | | ) |
| | | )); |
| | | } |
| | | }); |
| | | |
| | | Datetime.defaultProps = { |
| | | className: '', |
| | | defaultValue: '', |
| | | inputProps: {}, |
| | | input: true, |
| | | onFocus: function() {}, |
| | | onBlur: function() {}, |
| | | onChange: function() {}, |
| | | onViewModeChange: function() {}, |
| | | timeFormat: true, |
| | | timeConstraints: {}, |
| | | dateFormat: true, |
| | | strictParsing: true, |
| | | closeOnSelect: false, |
| | | closeOnTab: true, |
| | | utc: false |
| | | }; |
| | | |
| | | // Make moment accessible through the Datetime class |
| | | Datetime.moment = moment; |
| | | |