- Bugfix selecting days from previous or next month from the current viewed month.
- Bugfix adding keys to children in year and month view.
- Feature adding different modes to be able to have datepicker, timepicker, or datetimepicker.
1 files added
8 files modified
| | |
| | | var Basic = React.createClass({ |
| | | |
| | | render: function() { |
| | | return <div className="container"> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | <h1>React Bootstrap DateTimePicker</h1> |
| | | This project is a port of <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">https://github.com/Eonasdan/bootstrap-datetimepicker</a> for React.js |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | Default Basic Example |
| | | <DateTimeField /> |
| | | <pre> {'<DateTimeField />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | Example with default Text |
| | | <DateTimeField |
| | | defaultText="Please select a date" |
| | | /> |
| | | <pre> {'<DateTimeField defaultText="Please select a date" />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | ViewMode set to years view with custom inputFormat |
| | | <DateTimeField |
| | | inputFormat='DD-MM-YYYY' |
| | | viewMode='years' |
| | | return ( |
| | | <div className="container"> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | <h1>React Bootstrap DateTimePicker</h1> |
| | | This project is a port of <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">https://github.com/Eonasdan/bootstrap-datetimepicker</a> for React.js |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | Default Basic Example |
| | | <DateTimeField /> |
| | | <pre> {'<DateTimeField />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | Example with default Text |
| | | <DateTimeField |
| | | defaultText="Please select a date" |
| | | /> |
| | | <pre> {'<DateTimeField viewMode="years" inputFormat="DD-MM-YYYY" />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | daysOfWeekDisabled |
| | | <DateTimeField |
| | | daysOfWeekDisabled={[0,1,2]} |
| | | <pre> {'<DateTimeField defaultText="Please select a date" />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | ViewMode set to years view with custom inputFormat |
| | | <DateTimeField |
| | | inputFormat='DD-MM-YYYY' |
| | | viewMode='years' |
| | | /> |
| | | <pre> {'<DateTimeField daysOfWeekDisabled={[0,1,2]} />'} </pre> |
| | | |
| | | </div> |
| | | </div> |
| | | </div>; |
| | | <pre> {'<DateTimeField viewMode="years" inputFormat="DD-MM-YYYY" />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | daysOfWeekDisabled |
| | | <DateTimeField |
| | | daysOfWeekDisabled={[0,1,2]} |
| | | /> |
| | | <pre> {'<DateTimeField daysOfWeekDisabled={[0,1,2]} />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | daysOfWeekDisabled |
| | | <DateTimeField |
| | | mode="time" |
| | | /> |
| | | <pre> {'<DateTimeField mode="time" />'} </pre> |
| | | </div> |
| | | </div> |
| | | <div className="row"> |
| | | <div className="col-xs-12"> |
| | | daysOfWeekDisabled |
| | | <DateTimeField |
| | | mode="date" |
| | | /> |
| | | <pre> {'<DateTimeField mode="date" />'} </pre> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | ); |
| | | } |
| | | |
| | | }); |
| | | |
| | | |
New file |
| | |
| | | module.exports = { |
| | | MODE_DATE: 'date', |
| | | MODE_DATETIME: 'datetime', |
| | | MODE_TIME: 'time' |
| | | }; |
| | |
| | | |
| | | Glyphicon = require('react-bootstrap').Glyphicon; |
| | | |
| | | Constants = require('./Constants'); |
| | | |
| | | DateTimeField = React.createClass({ |
| | | propTypes: { |
| | | dateTime: React.PropTypes.string, |
| | | onChange: React.PropTypes.func, |
| | | format: React.PropTypes.string, |
| | | inputFormat: React.PropTypes.string, |
| | | inputProps: React.PropTypes.object, |
| | | defaultText: React.PropTypes.string |
| | | inputFormat: React.PropTypes.string, |
| | | defaultText: React.PropTypes.string, |
| | | mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]) |
| | | }, |
| | | getDefaultProps: function() { |
| | | return { |
| | | dateTime: moment().format('x'), |
| | | format: 'x', |
| | | inputFormat: "MM/DD/YY h:mm A", |
| | | showToday: true, |
| | | viewMode: 'days', |
| | | daysOfWeekDisabled: [], |
| | | onChange: function (x) { |
| | | console.log(x); |
| | | } |
| | | mode: Constants.MODE_DATETIME, |
| | | onChange: function (x) {} |
| | | }; |
| | | }, |
| | | resolvePropsInputFormat: function() { |
| | | if(this.props.inputFormat) return this.props.inputFormat; |
| | | switch(this.props.mode) { |
| | | case Constants.MODE_TIME: |
| | | return "h:mm A"; |
| | | case Constants.MODE_DATE: |
| | | return "MM/DD/YY"; |
| | | default: |
| | | return "MM/DD/YY h:mm A"; |
| | | } |
| | | }, |
| | | getInitialState: function() { |
| | | return { |
| | | showDatePicker: true, |
| | | showTimePicker: false, |
| | | showDatePicker: this.props.mode !== Constants.MODE_TIME, |
| | | showTimePicker: this.props.mode === Constants.MODE_TIME, |
| | | inputFormat: this.resolvePropsInputFormat(), |
| | | buttonIcon: this.props.mode === Constants.MODE_TIME ? "time" : "calendar", |
| | | widgetStyle: { |
| | | display: 'block', |
| | | position: 'absolute', |
| | |
| | | }, |
| | | viewDate: moment(this.props.dateTime, this.props.format, true).startOf("month"), |
| | | selectedDate: moment(this.props.dateTime, this.props.format, true), |
| | | inputValue: typeof this.props.defaultText != 'undefined' ? this.props.defaultText : moment(this.props.dateTime, this.props.format, true).format(this.props.inputFormat) |
| | | inputValue: typeof this.props.defaultText != 'undefined' ? this.props.defaultText : moment(this.props.dateTime, this.props.format, true).format(this.resolvePropsInputFormat()) |
| | | }; |
| | | }, |
| | | componentWillReceiveProps: function(nextProps) { |
| | |
| | | }, |
| | | onChange: function(event) { |
| | | var value = event.target == null ? event : event.target.value; |
| | | if (moment(value, this.props.inputFormat, true).isValid()) { |
| | | if (moment(value, this.state.inputFormat, true).isValid()) { |
| | | this.setState({ |
| | | selectedDate: moment(value, this.props.inputFormat, true), |
| | | viewDate: moment(value, this.props.inputFormat, true).startOf("month") |
| | | selectedDate: moment(value, this.state.inputFormat, true), |
| | | viewDate: moment(value, this.state.inputFormat, true).startOf("month") |
| | | }); |
| | | } |
| | | |
| | | return this.setState({ |
| | | inputValue: value |
| | | }, function() { |
| | | return this.props.onChange(moment(this.state.inputValue, this.props.inputFormat, true).format(this.props.format)); |
| | | return this.props.onChange(moment(this.state.inputValue, this.state.inputFormat, true).format(this.props.format)); |
| | | }); |
| | | |
| | | }, |
| | | setSelectedDate: function(e) { |
| | | var target = e.target; |
| | | var month; |
| | | if(target.className.includes("new")) month = this.state.viewDate.month() + 1; |
| | | else if(target.className.includes("old")) month = this.state.viewDate.month() - 1; |
| | | else month = this.state.viewDate.month(); |
| | | return this.setState({ |
| | | selectedDate: this.state.viewDate.clone().date(parseInt(e.target.innerHTML)).hour(this.state.selectedDate.hours()).minute(this.state.selectedDate.minutes()) |
| | | selectedDate: this.state.viewDate.clone().month(month).date(parseInt(e.target.innerHTML)).hour(this.state.selectedDate.hours()).minute(this.state.selectedDate.minutes()) |
| | | }, function() { |
| | | this.closePicker(); |
| | | this.props.onChange(this.state.selectedDate.format(this.props.format)); |
| | | return this.setState({ |
| | | inputValue: this.state.selectedDate.format(this.props.inputFormat) |
| | | inputValue: this.state.selectedDate.format(this.state.inputFormat) |
| | | }); |
| | | }); |
| | | }, |
| | |
| | | this.closePicker(); |
| | | this.props.onChange(this.state.selectedDate.format(this.props.format)); |
| | | return this.setState({ |
| | | inputValue: this.state.selectedDate.format(this.props.inputFormat) |
| | | inputValue: this.state.selectedDate.format(this.state.inputFormat) |
| | | }); |
| | | }); |
| | | }, |
| | |
| | | this.closePicker(); |
| | | this.props.onChange(this.state.selectedDate.format(this.props.format)); |
| | | return this.setState({ |
| | | inputValue: this.state.selectedDate.format(this.props.inputFormat) |
| | | inputValue: this.state.selectedDate.format(this.state.inputFormat) |
| | | }); |
| | | }); |
| | | }, |
| | |
| | | }, |
| | | togglePeriod: function() { |
| | | if (this.state.selectedDate.hour() > 12) { |
| | | return this.onChange(this.state.selectedDate.clone().subtract(12, 'hours').format(this.props.inputFormat)); |
| | | return this.onChange(this.state.selectedDate.clone().subtract(12, 'hours').format(this.state.inputFormat)); |
| | | } else { |
| | | return this.onChange(this.state.selectedDate.clone().add(12, 'hours').format(this.props.inputFormat)); |
| | | return this.onChange(this.state.selectedDate.clone().add(12, 'hours').format(this.state.inputFormat)); |
| | | } |
| | | }, |
| | | togglePicker: function() { |
| | |
| | | showToday={this.props.showToday} |
| | | viewMode={this.props.viewMode} |
| | | daysOfWeekDisabled={this.props.daysOfWeekDisabled} |
| | | mode={this.props.mode} |
| | | addDecade={this.addDecade} |
| | | addYear={this.addYear} |
| | | addMonth={this.addMonth} |
| | |
| | | /> |
| | | <div className="input-group date" ref="datetimepicker"> |
| | | <input type="text" className="form-control" onChange={this.onChange} value={this.state.inputValue} {...this.props.inputProps}/> |
| | | <span className="input-group-addon" onClick={this.onClick} onBlur={this.onBlur} ref="dtpbutton"><Glyphicon glyph="calendar" /></span> |
| | | <span className="input-group-addon" onClick={this.onClick} onBlur={this.onBlur} ref="dtpbutton"><Glyphicon glyph={this.state.buttonIcon} /></span> |
| | | </div> |
| | | </div> |
| | | ); |
| | |
| | | |
| | | Glyphicon = require('react-bootstrap').Glyphicon; |
| | | |
| | | Constants = require('./Constants'); |
| | | |
| | | DateTimePicker = React.createClass({ |
| | | propTypes: { |
| | | showDatePicker: React.PropTypes.bool, |
| | |
| | | React.PropTypes.string, |
| | | React.PropTypes.number |
| | | ]), |
| | | mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]), |
| | | daysOfWeekDisabled: React.PropTypes.array, |
| | | setSelectedDate: React.PropTypes.func.isRequired, |
| | | subtractYear: React.PropTypes.func.isRequired, |
| | |
| | | addMinute={this.props.addMinute} |
| | | subtractMinute={this.props.subtractMinute} |
| | | togglePeriod={this.props.togglePeriod} |
| | | mode={this.props.mode} |
| | | /> |
| | | </li> |
| | | ); |
| | | } |
| | | }, |
| | | renderSwitchButton: function() { |
| | | return this.props.mode === Constants.MODE_DATETIME ? |
| | | ( |
| | | <li> |
| | | <span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.togglePicker}><Glyphicon glyph={this.props.showTimePicker ? 'calendar' : 'time'} /></span> |
| | | </li> |
| | | ) : |
| | | null; |
| | | }, |
| | | render: function() { |
| | | return ( |
| | |
| | | |
| | | {this.renderDatePicker()} |
| | | |
| | | <li> |
| | | <span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.togglePicker}><Glyphicon glyph={this.props.showTimePicker ? 'calendar' : 'time'} /></span> |
| | | </li> |
| | | {this.renderSwitchButton()} |
| | | |
| | | {this.renderTimePicker()} |
| | | |
| | |
| | | var DateTimePickerHours, React; |
| | | |
| | | React = require('react'); |
| | | Glyphicon = require('react-bootstrap').Glyphicon; |
| | | |
| | | DateTimePickerHours = React.createClass({ |
| | | propTypes: { |
| | | setSelectedHour: React.PropTypes.func.isRequired |
| | | setSelectedHour: React.PropTypes.func.isRequired, |
| | | onSwitch: React.PropTypes.func.isRequired |
| | | }, |
| | | renderSwitchButton: function() { |
| | | return this.props.mode === Constants.MODE_TIME ? |
| | | ( |
| | | <ul className="list-unstyled"> |
| | | <li> |
| | | <span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.onSwitch}><Glyphicon glyph="time" /></span> |
| | | </li> |
| | | </ul> |
| | | ) : |
| | | null; |
| | | }, |
| | | render: function() { |
| | | return ( |
| | | <div className="timepicker-hours" data-action="selectHour" style={{display: 'block'}}> |
| | | {this.renderSwitchButton()} |
| | | <table className="table-condensed"> |
| | | <tbody> |
| | | <tr> |
| | |
| | | var DateTimePickerMinutes, React; |
| | | |
| | | React = require('react'); |
| | | Glyphicon = require('react-bootstrap').Glyphicon; |
| | | |
| | | DateTimePickerMinutes = React.createClass({ |
| | | propTypes: { |
| | | setSelectedMinute: React.PropTypes.func.isRequired |
| | | setSelectedMinute: React.PropTypes.func.isRequired, |
| | | onSwitch: React.PropTypes.func.isRequired |
| | | }, |
| | | renderSwitchButton: function() { |
| | | return this.props.mode === Constants.MODE_TIME ? |
| | | ( |
| | | <ul className="list-unstyled"> |
| | | <li> |
| | | <span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.onSwitch}><Glyphicon glyph="time" /></span> |
| | | </li> |
| | | </ul> |
| | | ) : |
| | | null; |
| | | }, |
| | | render: function() { |
| | | return ( |
| | | <div className="timepicker-minutes" data-action="selectMinute" style={{display: 'block'}}> |
| | | {this.renderSwitchButton()} |
| | | <table className="table-condensed"> |
| | | <tbody> |
| | | <tr> |
| | |
| | | month: true, |
| | | 'active': i === month && this.props.viewDate.year() === this.props.selectedDate.year() |
| | | }; |
| | | months.push(<span className={React.addons.classSet(classes)} onClick={this.props.setViewMonth}>{monthsShort[i]}</span>); |
| | | months.push(<span key={i} className={React.addons.classSet(classes)} onClick={this.props.setViewMonth}>{monthsShort[i]}</span>); |
| | | i++; |
| | | } |
| | | return months; |
| | |
| | | |
| | | Glyphicon = require('react-bootstrap').Glyphicon; |
| | | |
| | | Constants = require('./Constants'); |
| | | |
| | | DateTimePickerTime = React.createClass({ |
| | | propTypes: { |
| | | setSelectedHour: React.PropTypes.func.isRequired, |
| | |
| | | addMinute: React.PropTypes.func.isRequired, |
| | | viewDate: React.PropTypes.object.isRequired, |
| | | selectedDate: React.PropTypes.object.isRequired, |
| | | togglePeriod: React.PropTypes.func.isRequired |
| | | togglePeriod: React.PropTypes.func.isRequired, |
| | | mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]) |
| | | }, |
| | | getInitialState: function() { |
| | | return { |
| | | minutesDisplayed: false, |
| | | hoursDisplayed: false |
| | | }; |
| | | }, |
| | | goBack: function() { |
| | | return this.setState({ |
| | | minutesDisplayed: false, |
| | | hoursDisplayed: false |
| | | }); |
| | | }, |
| | | showMinutes: function() { |
| | | return this.setState({ |
| | |
| | | }, |
| | | renderMinutes: function() { |
| | | if (this.state.minutesDisplayed) { |
| | | return (<DateTimePickerMinutes |
| | | setSelectedMinute={this.props.setSelectedMinute} |
| | | /> |
| | | ); |
| | | return <DateTimePickerMinutes {...this.props} onSwitch={this.goBack} />; |
| | | } else { |
| | | return null; |
| | | } |
| | | }, |
| | | renderHours: function() { |
| | | if (this.state.hoursDisplayed) { |
| | | return (<DateTimePickerHours |
| | | setSelectedHour={this.props.setSelectedHour} |
| | | /> |
| | | ); |
| | | return <DateTimePickerHours {...this.props} onSwitch={this.goBack} />; |
| | | } else { |
| | | return null; |
| | | } |
| | |
| | | old: i === -1 | i === 10, |
| | | active: this.props.selectedDate.year() === year |
| | | }; |
| | | years.push(<span className={React.addons.classSet(classes)} onClick={this.props.setViewYear}>{year}</span>); |
| | | years.push(<span key={year} className={React.addons.classSet(classes)} onClick={this.props.setViewYear}>{year}</span>); |
| | | year++; |
| | | i++; |
| | | } |