UNPKG

ldx-widgets

Version:

widgets

238 lines (197 loc) 6 kB
React = require 'react' require 'classlist-polyfill' ReactDatepicker = React.createFactory(require 'react-datepicker') SelectInput = React.createFactory(require './select_input_2') moment = require 'moment' {div, span, input} = React.DOM DatePicker = React.createClass displayName: 'DatePicker' propTypes: placeholderText: React.PropTypes.oneOfType [ React.PropTypes.string React.PropTypes.number ] dateFormat: React.PropTypes.string className: React.PropTypes.string minDate: React.PropTypes.object maxDate: React.PropTypes.object onChange: React.PropTypes.func.isRequired tabIndex: React.PropTypes.number selected: React.PropTypes.oneOfType [ React.PropTypes.string React.PropTypes.object ] getDefaultProps: -> placeholderText: 'Select a date' dateFormat: 'MM/DD/YYYY' className: null includeTime: no # yes to include time selection returnDateString: null # pass a date format string to get that format from the getValue method getInitialState: -> {selected} = @props @getDateState selected getDateState: (selected = moment()) -> { selected: moment(selected.format('YYYYMMDD'), 'YYYYMMDD') inputDate: '' hours: selected.format('h') minutes: selected.format('mm') ampm: selected.format('a') } componentWillMount: -> {includeTime} = @props return unless includeTime @hoursOptions = [{ label: '12' value: '12' }] @hoursOptions.push( label: hour value: hour ) for hour in [1..11] @minuteOptions = [] for minute in [0..59] if minute < 10 then minute = "0#{minute}" @minuteOptions.push( label: minute value: minute ) @ampmOptions = [ { label: 'am' value: 'am' } { label: 'pm' value: 'pm' } ] componentWillReceiveProps: (nextProps) -> {selected} = @props if selected?.format('YYYYMMDDhmma') isnt nextProps.selected?.format('YYYYMMDDhmma') @setState(@getDateState(nextProps.selected)) render: -> {placeholderText, className, dateFormat, minDate, maxDate, onChange, tabIndex, includeTime} = @props {selected, inputDate, hours, minutes, ampm} = @state if selected # Allow the value to be set from either a Moment object or a string switch typeof selected when 'string' value = moment(selected).format(dateFormat) selected = moment(selected, dateFormat) when 'object' value = selected.format(dateFormat) mainClass = 'datepicker-wrapper' mainClass += ' include-time' if includeTime mainClass += " #{className}" if className? div { className: mainClass }, [ input { key: 'input' ref: 'input' type: 'text' placeholder: placeholderText value: inputDate or value onChange: @handleChange onKeyDown: @handleKeyDown onBlur: @handleBlur onFocus: @handleFocus tabIndex: tabIndex } ReactDatepicker { key: 'datepicker' ref: 'datepicker' selected: selected onChange: @handleDateChange dateFormat: dateFormat minDate: minDate maxDate: maxDate } div { key: 'time' className: 'time-wrapper' }, [ SelectInput { key: 'hours' ref: 'hours' value: hours className: 'time-sel' options: @hoursOptions onChange: @handleChange } span {key: 'colon', className: 'colon'}, ':' SelectInput { key: 'minutes' ref: 'minutes' value: minutes className: 'time-sel' options: @minuteOptions onChange: @handleChange } SelectInput { key: 'ampm' ref: 'ampm' value: ampm className: 'time-sel ampm' options: @ampmOptions onChange: @handleChange } ] if includeTime ] hideCalendar: -> # Hide the datepicker popup @refs.datepicker.setOpen no handleFocus: -> # Show the datepicker popup @refs.datepicker.handleFocus() handleChange: (cb, blur) -> {includeTime, onChange} = @props setData = inputDate: @refs.input.value if includeTime setData.hours = @refs.hours.getValue() setData.minutes = @refs.minutes.getValue() setData.ampm = @refs.ampm.getValue() @setState setData, -> cb?(null, blur) onChange?() handleBlur: -> @handleChange(@handleKeyDown, true) handleKeyDown: (e, blur) -> {value} = @refs.input {minDate, maxDate, dateFormat} = @props inputDate = moment(value, dateFormat) unixInputDate = inputDate.unix() state = {} # Validate the value and enter key was pressed if inputDate.isValid() and (e?.key in ['Enter', 'Tab'] or not e?) # Check to make sure the date is in the valid range if minDate? and unixInputDate <= minDate.unix() inputAdjusted = true inputDate = minDate if maxDate? and unixInputDate >= maxDate.unix() inputAdjusted = true inputDate = maxDate if inputAdjusted then state.inputDate = inputDate.format(dateFormat) state.selected = inputDate @setState state , -> @props.onChange?() @hideCalendar() unless blur handleDateChange: (date) -> @setState selected: date inputDate: '' , -> @props.onChange?() getValue: -> {returnDateString, includeTime} = @props {selected} = @state if includeTime {hours, minutes, ampm} = @state dateString = selected.format 'YYYYMMDD' dateString += "#{hours}:#{minutes}#{ampm}" selected = moment(dateString, 'YYYYMMDDh:mma') if returnDateString? then selected.format(returnDateString) else selected module.exports = DatePicker