Skip to content
This repository was archived by the owner on Nov 16, 2018. It is now read-only.

Commit aca70af

Browse files
author
Alejandro Sellero
committed
- 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 parent 5476f28 commit aca70af

File tree

9 files changed

+164
-79
lines changed

9 files changed

+164
-79
lines changed

examples/basic/basic.jsx

Lines changed: 61 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,52 +4,70 @@ var DateTimeField = require('react-bootstrap-datetimepicker');
44
var Basic = React.createClass({
55

66
render: function() {
7-
return <div className="container">
8-
<div className="row">
9-
<div className="col-xs-12">
10-
<h1>React Bootstrap DateTimePicker</h1>
11-
This project is a port of <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">https://github.com/Eonasdan/bootstrap-datetimepicker</a> for React.js
12-
</div>
13-
</div>
14-
<div className="row">
15-
<div className="col-xs-12">
16-
Default Basic Example
17-
<DateTimeField />
18-
<pre> {'<DateTimeField />'} </pre>
19-
</div>
20-
</div>
21-
<div className="row">
22-
<div className="col-xs-12">
23-
Example with default Text
24-
<DateTimeField
25-
defaultText="Please select a date"
26-
/>
27-
<pre> {'<DateTimeField defaultText="Please select a date" />'} </pre>
28-
</div>
29-
</div>
30-
<div className="row">
31-
<div className="col-xs-12">
32-
ViewMode set to years view with custom inputFormat
33-
<DateTimeField
34-
inputFormat='DD-MM-YYYY'
35-
viewMode='years'
7+
return (
8+
<div className="container">
9+
<div className="row">
10+
<div className="col-xs-12">
11+
<h1>React Bootstrap DateTimePicker</h1>
12+
This project is a port of <a href="https://github.com/Eonasdan/bootstrap-datetimepicker">https://github.com/Eonasdan/bootstrap-datetimepicker</a> for React.js
13+
</div>
14+
</div>
15+
<div className="row">
16+
<div className="col-xs-12">
17+
Default Basic Example
18+
<DateTimeField />
19+
<pre> {'<DateTimeField />'} </pre>
20+
</div>
21+
</div>
22+
<div className="row">
23+
<div className="col-xs-12">
24+
Example with default Text
25+
<DateTimeField
26+
defaultText="Please select a date"
3627
/>
37-
<pre> {'<DateTimeField viewMode="years" inputFormat="DD-MM-YYYY" />'} </pre>
38-
</div>
39-
</div>
40-
<div className="row">
41-
<div className="col-xs-12">
42-
daysOfWeekDisabled
43-
<DateTimeField
44-
daysOfWeekDisabled={[0,1,2]}
28+
<pre> {'<DateTimeField defaultText="Please select a date" />'} </pre>
29+
</div>
30+
</div>
31+
<div className="row">
32+
<div className="col-xs-12">
33+
ViewMode set to years view with custom inputFormat
34+
<DateTimeField
35+
inputFormat='DD-MM-YYYY'
36+
viewMode='years'
4537
/>
46-
<pre> {'<DateTimeField daysOfWeekDisabled={[0,1,2]} />'} </pre>
47-
48-
</div>
49-
</div>
50-
</div>;
38+
<pre> {'<DateTimeField viewMode="years" inputFormat="DD-MM-YYYY" />'} </pre>
39+
</div>
40+
</div>
41+
<div className="row">
42+
<div className="col-xs-12">
43+
daysOfWeekDisabled
44+
<DateTimeField
45+
daysOfWeekDisabled={[0,1,2]}
46+
/>
47+
<pre> {'<DateTimeField daysOfWeekDisabled={[0,1,2]} />'} </pre>
48+
</div>
49+
</div>
50+
<div className="row">
51+
<div className="col-xs-12">
52+
daysOfWeekDisabled
53+
<DateTimeField
54+
mode="time"
55+
/>
56+
<pre> {'<DateTimeField mode="time" />'} </pre>
57+
</div>
58+
</div>
59+
<div className="row">
60+
<div className="col-xs-12">
61+
daysOfWeekDisabled
62+
<DateTimeField
63+
mode="date"
64+
/>
65+
<pre> {'<DateTimeField mode="date" />'} </pre>
66+
</div>
67+
</div>
68+
</div>
69+
);
5170
}
52-
5371
});
5472

5573

src/Constants.jsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
MODE_DATE: 'date',
3+
MODE_DATETIME: 'datetime',
4+
MODE_TIME: 'time'
5+
};

src/DateTimeField.jsx

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,46 @@ moment = require('moment');
88

99
Glyphicon = require('react-bootstrap').Glyphicon;
1010

11+
Constants = require('./Constants');
12+
1113
DateTimeField = React.createClass({
1214
propTypes: {
1315
dateTime: React.PropTypes.string,
1416
onChange: React.PropTypes.func,
1517
format: React.PropTypes.string,
16-
inputFormat: React.PropTypes.string,
1718
inputProps: React.PropTypes.object,
18-
defaultText: React.PropTypes.string
19+
inputFormat: React.PropTypes.string,
20+
defaultText: React.PropTypes.string,
21+
mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME])
1922
},
2023
getDefaultProps: function() {
2124
return {
2225
dateTime: moment().format('x'),
2326
format: 'x',
24-
inputFormat: "MM/DD/YY h:mm A",
2527
showToday: true,
2628
viewMode: 'days',
2729
daysOfWeekDisabled: [],
28-
onChange: function (x) {
29-
console.log(x);
30-
}
30+
mode: Constants.MODE_DATETIME,
31+
onChange: function (x) {}
3132
};
3233
},
34+
resolvePropsInputFormat: function() {
35+
if(this.props.inputFormat) return this.props.inputFormat;
36+
switch(this.props.mode) {
37+
case Constants.MODE_TIME:
38+
return "h:mm A";
39+
case Constants.MODE_DATE:
40+
return "MM/DD/YY";
41+
default:
42+
return "MM/DD/YY h:mm A";
43+
}
44+
},
3345
getInitialState: function() {
3446
return {
35-
showDatePicker: true,
36-
showTimePicker: false,
47+
showDatePicker: this.props.mode !== Constants.MODE_TIME,
48+
showTimePicker: this.props.mode === Constants.MODE_TIME,
49+
inputFormat: this.resolvePropsInputFormat(),
50+
buttonIcon: this.props.mode === Constants.MODE_TIME ? "time" : "calendar",
3751
widgetStyle: {
3852
display: 'block',
3953
position: 'absolute',
@@ -42,7 +56,7 @@ DateTimeField = React.createClass({
4256
},
4357
viewDate: moment(this.props.dateTime, this.props.format, true).startOf("month"),
4458
selectedDate: moment(this.props.dateTime, this.props.format, true),
45-
inputValue: typeof this.props.defaultText != 'undefined' ? this.props.defaultText : moment(this.props.dateTime, this.props.format, true).format(this.props.inputFormat)
59+
inputValue: typeof this.props.defaultText != 'undefined' ? this.props.defaultText : moment(this.props.dateTime, this.props.format, true).format(this.resolvePropsInputFormat())
4660
};
4761
},
4862
componentWillReceiveProps: function(nextProps) {
@@ -56,28 +70,33 @@ DateTimeField = React.createClass({
5670
},
5771
onChange: function(event) {
5872
var value = event.target == null ? event : event.target.value;
59-
if (moment(value, this.props.inputFormat, true).isValid()) {
73+
if (moment(value, this.state.inputFormat, true).isValid()) {
6074
this.setState({
61-
selectedDate: moment(value, this.props.inputFormat, true),
62-
viewDate: moment(value, this.props.inputFormat, true).startOf("month")
75+
selectedDate: moment(value, this.state.inputFormat, true),
76+
viewDate: moment(value, this.state.inputFormat, true).startOf("month")
6377
});
6478
}
6579

6680
return this.setState({
6781
inputValue: value
6882
}, function() {
69-
return this.props.onChange(moment(this.state.inputValue, this.props.inputFormat, true).format(this.props.format));
83+
return this.props.onChange(moment(this.state.inputValue, this.state.inputFormat, true).format(this.props.format));
7084
});
7185

7286
},
7387
setSelectedDate: function(e) {
88+
var target = e.target;
89+
var month;
90+
if(target.className.includes("new")) month = this.state.viewDate.month() + 1;
91+
else if(target.className.includes("old")) month = this.state.viewDate.month() - 1;
92+
else month = this.state.viewDate.month();
7493
return this.setState({
75-
selectedDate: this.state.viewDate.clone().date(parseInt(e.target.innerHTML)).hour(this.state.selectedDate.hours()).minute(this.state.selectedDate.minutes())
94+
selectedDate: this.state.viewDate.clone().month(month).date(parseInt(e.target.innerHTML)).hour(this.state.selectedDate.hours()).minute(this.state.selectedDate.minutes())
7695
}, function() {
7796
this.closePicker();
7897
this.props.onChange(this.state.selectedDate.format(this.props.format));
7998
return this.setState({
80-
inputValue: this.state.selectedDate.format(this.props.inputFormat)
99+
inputValue: this.state.selectedDate.format(this.state.inputFormat)
81100
});
82101
});
83102
},
@@ -88,7 +107,7 @@ DateTimeField = React.createClass({
88107
this.closePicker();
89108
this.props.onChange(this.state.selectedDate.format(this.props.format));
90109
return this.setState({
91-
inputValue: this.state.selectedDate.format(this.props.inputFormat)
110+
inputValue: this.state.selectedDate.format(this.state.inputFormat)
92111
});
93112
});
94113
},
@@ -99,7 +118,7 @@ DateTimeField = React.createClass({
99118
this.closePicker();
100119
this.props.onChange(this.state.selectedDate.format(this.props.format));
101120
return this.setState({
102-
inputValue: this.state.selectedDate.format(this.props.inputFormat)
121+
inputValue: this.state.selectedDate.format(this.state.inputFormat)
103122
});
104123
});
105124
},
@@ -173,9 +192,9 @@ DateTimeField = React.createClass({
173192
},
174193
togglePeriod: function() {
175194
if (this.state.selectedDate.hour() > 12) {
176-
return this.onChange(this.state.selectedDate.clone().subtract(12, 'hours').format(this.props.inputFormat));
195+
return this.onChange(this.state.selectedDate.clone().subtract(12, 'hours').format(this.state.inputFormat));
177196
} else {
178-
return this.onChange(this.state.selectedDate.clone().add(12, 'hours').format(this.props.inputFormat));
197+
return this.onChange(this.state.selectedDate.clone().add(12, 'hours').format(this.state.inputFormat));
179198
}
180199
},
181200
togglePicker: function() {
@@ -268,6 +287,7 @@ DateTimeField = React.createClass({
268287
showToday={this.props.showToday}
269288
viewMode={this.props.viewMode}
270289
daysOfWeekDisabled={this.props.daysOfWeekDisabled}
290+
mode={this.props.mode}
271291
addDecade={this.addDecade}
272292
addYear={this.addYear}
273293
addMonth={this.addMonth}
@@ -288,7 +308,7 @@ DateTimeField = React.createClass({
288308
/>
289309
<div className="input-group date" ref="datetimepicker">
290310
<input type="text" className="form-control" onChange={this.onChange} value={this.state.inputValue} {...this.props.inputProps}/>
291-
<span className="input-group-addon" onClick={this.onClick} onBlur={this.onBlur} ref="dtpbutton"><Glyphicon glyph="calendar" /></span>
311+
<span className="input-group-addon" onClick={this.onClick} onBlur={this.onBlur} ref="dtpbutton"><Glyphicon glyph={this.state.buttonIcon} /></span>
292312
</div>
293313
</div>
294314
);

src/DateTimePicker.jsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ DateTimePickerTime = require('./DateTimePickerTime');
88

99
Glyphicon = require('react-bootstrap').Glyphicon;
1010

11+
Constants = require('./Constants');
12+
1113
DateTimePicker = React.createClass({
1214
propTypes: {
1315
showDatePicker: React.PropTypes.bool,
@@ -21,6 +23,7 @@ DateTimePicker = React.createClass({
2123
React.PropTypes.string,
2224
React.PropTypes.number
2325
]),
26+
mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]),
2427
daysOfWeekDisabled: React.PropTypes.array,
2528
setSelectedDate: React.PropTypes.func.isRequired,
2629
subtractYear: React.PropTypes.func.isRequired,
@@ -73,11 +76,21 @@ DateTimePicker = React.createClass({
7376
addMinute={this.props.addMinute}
7477
subtractMinute={this.props.subtractMinute}
7578
togglePeriod={this.props.togglePeriod}
79+
mode={this.props.mode}
7680
/>
7781
</li>
7882
);
7983
}
8084
},
85+
renderSwitchButton: function() {
86+
return this.props.mode === Constants.MODE_DATETIME ?
87+
(
88+
<li>
89+
<span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.togglePicker}><Glyphicon glyph={this.props.showTimePicker ? 'calendar' : 'time'} /></span>
90+
</li>
91+
) :
92+
null;
93+
},
8194
render: function() {
8295
return (
8396
<div className={React.addons.classSet(this.props.widgetClasses)} style={this.props.widgetStyle}>
@@ -86,9 +99,7 @@ DateTimePicker = React.createClass({
8699

87100
{this.renderDatePicker()}
88101

89-
<li>
90-
<span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.togglePicker}><Glyphicon glyph={this.props.showTimePicker ? 'calendar' : 'time'} /></span>
91-
</li>
102+
{this.renderSwitchButton()}
92103

93104
{this.renderTimePicker()}
94105

src/DateTimePickerHours.jsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
var DateTimePickerHours, React;
22

33
React = require('react');
4+
Glyphicon = require('react-bootstrap').Glyphicon;
45

56
DateTimePickerHours = React.createClass({
67
propTypes: {
7-
setSelectedHour: React.PropTypes.func.isRequired
8+
setSelectedHour: React.PropTypes.func.isRequired,
9+
onSwitch: React.PropTypes.func.isRequired
10+
},
11+
renderSwitchButton: function() {
12+
return this.props.mode === Constants.MODE_TIME ?
13+
(
14+
<ul className="list-unstyled">
15+
<li>
16+
<span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.onSwitch}><Glyphicon glyph="time" /></span>
17+
</li>
18+
</ul>
19+
) :
20+
null;
821
},
922
render: function() {
1023
return (
1124
<div className="timepicker-hours" data-action="selectHour" style={{display: 'block'}}>
25+
{this.renderSwitchButton()}
1226
<table className="table-condensed">
1327
<tbody>
1428
<tr>

src/DateTimePickerMinutes.jsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
var DateTimePickerMinutes, React;
22

33
React = require('react');
4+
Glyphicon = require('react-bootstrap').Glyphicon;
45

56
DateTimePickerMinutes = React.createClass({
67
propTypes: {
7-
setSelectedMinute: React.PropTypes.func.isRequired
8+
setSelectedMinute: React.PropTypes.func.isRequired,
9+
onSwitch: React.PropTypes.func.isRequired
10+
},
11+
renderSwitchButton: function() {
12+
return this.props.mode === Constants.MODE_TIME ?
13+
(
14+
<ul className="list-unstyled">
15+
<li>
16+
<span className="btn picker-switch" style={{width:'100%'}} onClick={this.props.onSwitch}><Glyphicon glyph="time" /></span>
17+
</li>
18+
</ul>
19+
) :
20+
null;
821
},
922
render: function() {
1023
return (
1124
<div className="timepicker-minutes" data-action="selectMinute" style={{display: 'block'}}>
25+
{this.renderSwitchButton()}
1226
<table className="table-condensed">
1327
<tbody>
1428
<tr>

src/DateTimePickerMonths.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ DateTimePickerMonths = React.createClass({
2424
month: true,
2525
'active': i === month && this.props.viewDate.year() === this.props.selectedDate.year()
2626
};
27-
months.push(<span className={React.addons.classSet(classes)} onClick={this.props.setViewMonth}>{monthsShort[i]}</span>);
27+
months.push(<span key={i} className={React.addons.classSet(classes)} onClick={this.props.setViewMonth}>{monthsShort[i]}</span>);
2828
i++;
2929
}
3030
return months;

0 commit comments

Comments
 (0)