diff --git a/README.md b/README.md
index b78a8bd..c9d20b8 100755
--- a/README.md
+++ b/README.md
@@ -126,10 +126,10 @@ DatePicker component. Renders as a [React-Bootstrap InputGroup](https://react-bo
* **Callback Arguments:**
* `event` - Blur event.
* **Type:** `Event`
- * `dateFormat` - Date format. Any combination of DD, MM, YYYY and separator.
+ * `dateFormat` - Date format. Any combination of D/DD, M/MM, YYYY and separator.
* **Optional**
* **Type:** `string`
- * **Examples:** `"MM/DD/YYYY"`, `"YYYY/MM/DD"`, `"MM-DD-YYYY"`, or `"DD MM YYYY"`
+ * **Examples:** `"MM/DD/YYYY"`, `"YYYY/M/D"`, `"MM-DD-YYYY"`, or `"DD MM YYYY"`
* `clearButtonElement` - Character or component to use for the clear button.
* **Optional**
* **Type:** `string` or `ReactClass`
diff --git a/example/app.jsx b/example/app.jsx
index 36e0d9e..3e322c5 100755
--- a/example/app.jsx
+++ b/example/app.jsx
@@ -147,8 +147,8 @@ const App = React.createClass({
- YYYY/MM/DD
-
+ YYYY/M/D
+
Help
diff --git a/lib/index.js b/lib/index.js
index 04f36fc..4f32802 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -14,9 +14,15 @@ var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactBootstrap = require('react-bootstrap');
+var _moment = require('moment');
+
+var _moment2 = _interopRequireDefault(_moment);
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-var instanceCount = 0; // See http://jszen.blogspot.com/2007/03/how-to-build-simple-calendar-with.html for calendar logic.
+// See http://jszen.blogspot.com/2007/03/how-to-build-simple-calendar-with.html for calendar logic.
+
+var instanceCount = 0;
var CalendarHeader = _react2.default.createClass({
displayName: 'DatePickerHeader',
@@ -30,14 +36,12 @@ var CalendarHeader = _react2.default.createClass({
},
handleClickPrevious: function handleClickPrevious() {
- var newDisplayDate = new Date(this.props.displayDate);
- newDisplayDate.setMonth(newDisplayDate.getMonth() - 1);
- this.props.onChange(newDisplayDate);
+ var date = this.props.displayDate;
+ this.props.onChange(date.month(date.month() - 1));
},
handleClickNext: function handleClickNext() {
- var newDisplayDate = new Date(this.props.displayDate);
- newDisplayDate.setMonth(newDisplayDate.getMonth() + 1);
- this.props.onChange(newDisplayDate);
+ var date = this.props.displayDate;
+ this.props.onChange(date.month(date.month() + 1));
},
render: function render() {
return _react2.default.createElement(
@@ -51,9 +55,9 @@ var CalendarHeader = _react2.default.createClass({
_react2.default.createElement(
'span',
null,
- this.props.monthLabels[this.props.displayDate.getMonth()],
+ this.props.monthLabels[this.props.displayDate.month()],
' ',
- this.props.displayDate.getFullYear()
+ this.props.displayDate.year()
),
_react2.default.createElement(
'div',
@@ -81,36 +85,27 @@ var Calendar = _react2.default.createClass({
},
handleClick: function handleClick(day) {
- var newSelectedDate = new Date(this.props.displayDate);
- newSelectedDate.setHours(12);
- newSelectedDate.setMinutes(0);
- newSelectedDate.setSeconds(0);
- newSelectedDate.setMilliseconds(0);
- newSelectedDate.setDate(day);
+ var newSelectedDate = (0, _moment2.default)(this.props.displayDate).date(day);
this.props.onChange(newSelectedDate);
},
handleClickToday: function handleClickToday() {
- var newSelectedDate = new Date();
- newSelectedDate.setHours(12);
- newSelectedDate.setMinutes(0);
- newSelectedDate.setSeconds(0);
- newSelectedDate.setMilliseconds(0);
+ var newSelectedDate = (0, _moment2.default)().startOf('day').hour(12);
this.props.onChange(newSelectedDate);
},
render: function render() {
var _this = this;
- var currentDate = new Date();
- var currentDay = currentDate.getDate();
- var currentMonth = currentDate.getMonth();
- var currentYear = currentDate.getFullYear();
- var selectedDay = this.props.selectedDate ? this.props.selectedDate.getDate() : null;
- var selectedMonth = this.props.selectedDate ? this.props.selectedDate.getMonth() : null;
- var selectedYear = this.props.selectedDate ? this.props.selectedDate.getFullYear() : null;
- var year = this.props.displayDate.getFullYear();
- var month = this.props.displayDate.getMonth();
- var firstDay = new Date(year, month, 1);
- var startingDay = this.props.weekStartsOnMonday ? firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1 : firstDay.getDay();
+ var currentDate = (0, _moment2.default)();
+ var currentDay = currentDate.date();
+ var currentMonth = currentDate.month();
+ var currentYear = currentDate.year();
+ var selectedDay = this.props.selectedDate ? this.props.selectedDate.date() : null;
+ var selectedMonth = this.props.selectedDate ? this.props.selectedDate.month() : null;
+ var selectedYear = this.props.selectedDate ? this.props.selectedDate.year() : null;
+ var year = this.props.displayDate.year();
+ var month = this.props.displayDate.month();
+ var firstDay = (0, _moment2.default)([year, month, 1]);
+ var startingDay = this.props.weekStartsOnMonday ? firstDay.day() === 0 ? 6 : firstDay.day() - 1 : firstDay.day();
var monthLength = daysInMonth[month];
if (month == 1) {
@@ -282,17 +277,12 @@ exports.default = _react2.default.createClass({
return state;
},
makeDateValues: function makeDateValues(isoString) {
- var displayDate = void 0;
- var selectedDate = isoString ? new Date(isoString.slice(0, 10) + 'T12:00:00.000Z') : null;
+ var selectedDate = isoString ? (0, _moment2.default)(isoString.slice(0, 10) + 'T12:00:00.000Z') : null;
var inputValue = isoString ? this.makeInputValueString(selectedDate) : null;
- if (selectedDate) {
- displayDate = new Date(selectedDate);
- } else {
- displayDate = new Date(new Date().toISOString().slice(0, 10) + 'T12:00:00.000Z');
- }
+ var displayDate = selectedDate || (0, _moment2.default)();
return {
- value: selectedDate ? selectedDate.toISOString() : null,
+ value: selectedDate ? selectedDate.format() : null,
displayDate: displayDate,
selectedDate: selectedDate,
inputValue: inputValue
@@ -372,22 +362,11 @@ exports.default = _react2.default.createClass({
return this.state.displayDate ? this.state.inputValue : null;
},
makeInputValueString: function makeInputValueString(date) {
- var month = date.getMonth() + 1;
- var day = date.getDate();
-
- //this method is executed during intialState setup... handle a missing state properly
- var separator = this.state ? this.state.separator : this.props.dateFormat.match(/[^A-Z]/)[0];
- if (this.props.dateFormat.match(/MM.DD.YYYY/)) {
- return (month > 9 ? month : '0' + month) + separator + (day > 9 ? day : '0' + day) + separator + date.getFullYear();
- } else if (this.props.dateFormat.match(/DD.MM.YYYY/)) {
- return (day > 9 ? day : '0' + day) + separator + (month > 9 ? month : '0' + month) + separator + date.getFullYear();
- } else {
- return date.getFullYear() + separator + (month > 9 ? month : '0' + month) + separator + (day > 9 ? day : '0' + day);
- }
+ return date.format(this.props.dateFormat);
},
handleBadInput: function handleBadInput(originalValue) {
var parts = originalValue.replace(new RegExp('[^0-9' + this.state.separator + ']'), '').split(this.state.separator);
- if (this.props.dateFormat.match(/MM.DD.YYYY/) || this.props.dateFormat.match(/DD.MM.YYYY/)) {
+ if (this.props.dateFormat.match(/MM?.DD?.YYYY/) || this.props.dateFormat.match(/DD?.MM?.YYYY/)) {
if (parts[0] && parts[0].length > 2) {
parts[1] = parts[0].slice(2) + (parts[1] || '');
parts[0] = parts[0].slice(0, 2);
@@ -421,58 +400,19 @@ exports.default = _react2.default.createClass({
var originalValue = _reactDom2.default.findDOMNode(this.refs.input).value;
var inputValue = originalValue.replace(/(-|\/\/)/g, this.state.separator).slice(0, 10);
- var month = void 0,
- day = void 0,
- year = void 0;
- if (this.props.dateFormat.match(/MM.DD.YYYY/)) {
- if (!inputValue.match(/[0-1][0-9].[0-3][0-9].[1-2][0-9][0-9][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- month = inputValue.slice(0, 2).replace(/[^0-9]/g, '');
- day = inputValue.slice(3, 5).replace(/[^0-9]/g, '');
- year = inputValue.slice(6, 10).replace(/[^0-9]/g, '');
- } else if (this.props.dateFormat.match(/DD.MM.YYYY/)) {
- if (!inputValue.match(/[0-3][0-9].[0-1][0-9].[1-2][0-9][0-9][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- day = inputValue.slice(0, 2).replace(/[^0-9]/g, '');
- month = inputValue.slice(3, 5).replace(/[^0-9]/g, '');
- year = inputValue.slice(6, 10).replace(/[^0-9]/g, '');
- } else {
- if (!inputValue.match(/[1-2][0-9][0-9][0-9].[0-1][0-9].[0-3][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- year = inputValue.slice(0, 4).replace(/[^0-9]/g, '');
- month = inputValue.slice(5, 7).replace(/[^0-9]/g, '');
- day = inputValue.slice(8, 10).replace(/[^0-9]/g, '');
- }
-
- var monthInteger = parseInt(month, 10);
- var dayInteger = parseInt(day, 10);
- var yearInteger = parseInt(year, 10);
- if (monthInteger > 12 || dayInteger > 31) {
+ var selectedDate = (0, _moment2.default)(inputValue, this.props.dateFormat, true);
+ if (!selectedDate.isValid()) {
return this.handleBadInput(originalValue);
}
-
- if (!isNaN(monthInteger) && !isNaN(dayInteger) && !isNaN(yearInteger) && monthInteger <= 12 && dayInteger <= 31 && yearInteger > 999) {
- var selectedDate = new Date(yearInteger, monthInteger - 1, dayInteger, 12, 0, 0, 0);
- this.setState({
- selectedDate: selectedDate,
- displayDate: selectedDate,
- value: selectedDate.toISOString()
- });
-
- if (this.props.onChange) {
- this.props.onChange(selectedDate.toISOString(), inputValue);
- }
- }
-
this.setState({
- inputValue: inputValue
+ displayDate: selectedDate,
+ inputValue: inputValue,
+ selectedDate: selectedDate,
+ value: selectedDate.format()
});
+ if (this.props.onChange) {
+ this.props.onChange(selectedDate.format(), inputValue);
+ }
},
onChangeMonth: function onChangeMonth(newDisplayDate) {
this.setState({
diff --git a/package.json b/package.json
index 0637665..83c7cf5 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,9 @@
"directories": {
"test": "test"
},
+ "dependencies": {
+ "moment": "^2.17.0"
+ },
"peerDependencies": {
"react": ">=0.14.0",
"react-bootstrap": "^0.30.2"
diff --git a/src/index.jsx b/src/index.jsx
index 540f1a8..408fe31 100644
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -9,6 +9,7 @@ import {
Overlay,
Popover,
} from 'react-bootstrap';
+import moment from 'moment';
let instanceCount = 0;
@@ -30,21 +31,19 @@ const CalendarHeader = React.createClass({
},
handleClickPrevious() {
- const newDisplayDate = new Date(this.props.displayDate);
- newDisplayDate.setMonth(newDisplayDate.getMonth() - 1);
- this.props.onChange(newDisplayDate);
+ const date = this.props.displayDate;
+ this.props.onChange(date.month(date.month() - 1));
},
handleClickNext() {
- const newDisplayDate = new Date(this.props.displayDate);
- newDisplayDate.setMonth(newDisplayDate.getMonth() + 1);
- this.props.onChange(newDisplayDate);
+ const date = this.props.displayDate;
+ this.props.onChange(date.month(date.month() + 1));
},
render() {
return
{this.props.previousButtonElement}
-
{this.props.monthLabels[this.props.displayDate.getMonth()]} {this.props.displayDate.getFullYear()}
+
{this.props.monthLabels[this.props.displayDate.month()]} {this.props.displayDate.year()}
{this.props.nextButtonElement}
;
}
@@ -67,36 +66,27 @@ const Calendar = React.createClass({
},
handleClick(day) {
- const newSelectedDate = new Date(this.props.displayDate);
- newSelectedDate.setHours(12);
- newSelectedDate.setMinutes(0);
- newSelectedDate.setSeconds(0);
- newSelectedDate.setMilliseconds(0);
- newSelectedDate.setDate(day);
+ const newSelectedDate = moment(this.props.displayDate).date(day);
this.props.onChange(newSelectedDate);
},
handleClickToday() {
- const newSelectedDate = new Date();
- newSelectedDate.setHours(12);
- newSelectedDate.setMinutes(0);
- newSelectedDate.setSeconds(0);
- newSelectedDate.setMilliseconds(0);
+ const newSelectedDate = moment().startOf('day').hour(12);
this.props.onChange(newSelectedDate);
},
render() {
- const currentDate = new Date();
- const currentDay = currentDate.getDate();
- const currentMonth = currentDate.getMonth();
- const currentYear = currentDate.getFullYear();
- const selectedDay = this.props.selectedDate ? this.props.selectedDate.getDate() : null;
- const selectedMonth = this.props.selectedDate ? this.props.selectedDate.getMonth() : null;
- const selectedYear = this.props.selectedDate ? this.props.selectedDate.getFullYear() : null;
- const year = this.props.displayDate.getFullYear();
- const month = this.props.displayDate.getMonth();
- const firstDay = new Date(year, month, 1);
- const startingDay = this.props.weekStartsOnMonday ? (firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1) : firstDay.getDay();
+ const currentDate = moment();
+ const currentDay = currentDate.date();
+ const currentMonth = currentDate.month();
+ const currentYear = currentDate.year();
+ const selectedDay = this.props.selectedDate ? this.props.selectedDate.date() : null;
+ const selectedMonth = this.props.selectedDate ? this.props.selectedDate.month() : null;
+ const selectedYear = this.props.selectedDate ? this.props.selectedDate.year() : null;
+ const year = this.props.displayDate.year();
+ const month = this.props.displayDate.month();
+ const firstDay = moment([year, month, 1]);
+ const startingDay = this.props.weekStartsOnMonday ? (firstDay.day() === 0 ? 6 : firstDay.day() - 1) : firstDay.day();
let monthLength = daysInMonth[month];
if (month == 1) {
@@ -253,17 +243,12 @@ export default React.createClass({
},
makeDateValues(isoString) {
- let displayDate;
- const selectedDate = isoString ? new Date(`${isoString.slice(0,10)}T12:00:00.000Z`) : null;
+ const selectedDate = isoString ? moment(`${isoString.slice(0,10)}T12:00:00.000Z`) : null;
const inputValue = isoString ? this.makeInputValueString(selectedDate) : null;
- if (selectedDate) {
- displayDate = new Date(selectedDate);
- } else {
- displayDate = new Date(`${(new Date().toISOString().slice(0,10))}T12:00:00.000Z`);
- }
+ const displayDate = selectedDate || moment();
return {
- value: selectedDate ? selectedDate.toISOString() : null,
+ value: selectedDate ? selectedDate.format() : null,
displayDate: displayDate,
selectedDate: selectedDate,
inputValue: inputValue
@@ -350,25 +335,12 @@ export default React.createClass({
},
makeInputValueString(date) {
- const month = date.getMonth() + 1;
- const day = date.getDate();
-
- //this method is executed during intialState setup... handle a missing state properly
- const separator = (this.state ? this.state.separator : this.props.dateFormat.match(/[^A-Z]/)[0]);
- if (this.props.dateFormat.match(/MM.DD.YYYY/)) {
- return (month > 9 ? month : `0${month}`) + separator + (day > 9 ? day : `0${day}`) + separator + date.getFullYear();
- }
- else if (this.props.dateFormat.match(/DD.MM.YYYY/)) {
- return (day > 9 ? day : `0${day}`) + separator + (month > 9 ? month : `0${month}`) + separator + date.getFullYear();
- }
- else {
- return date.getFullYear() + separator + (month > 9 ? month : `0${month}`) + separator + (day > 9 ? day : `0${day}`);
- }
+ return date.format(this.props.dateFormat)
},
handleBadInput(originalValue) {
const parts = originalValue.replace(new RegExp(`[^0-9${this.state.separator}]`), '').split(this.state.separator);
- if (this.props.dateFormat.match(/MM.DD.YYYY/) || this.props.dateFormat.match(/DD.MM.YYYY/)) {
+ if (this.props.dateFormat.match(/MM?.DD?.YYYY/) || this.props.dateFormat.match(/DD?.MM?.YYYY/)) {
if (parts[0] && parts[0].length > 2) {
parts[1] = parts[0].slice(2) + (parts[1] || '');
parts[0] = parts[0].slice(0, 2);
@@ -403,56 +375,19 @@ export default React.createClass({
const originalValue = ReactDOM.findDOMNode(this.refs.input).value;
const inputValue = originalValue.replace(/(-|\/\/)/g, this.state.separator).slice(0,10);
- let month, day, year;
- if (this.props.dateFormat.match(/MM.DD.YYYY/)) {
- if (!inputValue.match(/[0-1][0-9].[0-3][0-9].[1-2][0-9][0-9][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- month = inputValue.slice(0,2).replace(/[^0-9]/g, '');
- day = inputValue.slice(3,5).replace(/[^0-9]/g, '');
- year = inputValue.slice(6,10).replace(/[^0-9]/g, '');
- } else if (this.props.dateFormat.match(/DD.MM.YYYY/)) {
- if (!inputValue.match(/[0-3][0-9].[0-1][0-9].[1-2][0-9][0-9][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- day = inputValue.slice(0,2).replace(/[^0-9]/g, '');
- month = inputValue.slice(3,5).replace(/[^0-9]/g, '');
- year = inputValue.slice(6,10).replace(/[^0-9]/g, '');
- } else {
- if (!inputValue.match(/[1-2][0-9][0-9][0-9].[0-1][0-9].[0-3][0-9]/)) {
- return this.handleBadInput(originalValue);
- }
-
- year = inputValue.slice(0,4).replace(/[^0-9]/g, '');
- month = inputValue.slice(5,7).replace(/[^0-9]/g, '');
- day = inputValue.slice(8,10).replace(/[^0-9]/g, '');
- }
-
- const monthInteger = parseInt(month, 10);
- const dayInteger = parseInt(day, 10);
- const yearInteger = parseInt(year, 10);
- if (monthInteger > 12 || dayInteger > 31) {
+ const selectedDate = moment(inputValue, this.props.dateFormat, true);
+ if (!selectedDate.isValid()) {
return this.handleBadInput(originalValue);
}
-
- if (!isNaN(monthInteger) && !isNaN(dayInteger) && !isNaN(yearInteger) && monthInteger <= 12 && dayInteger <= 31 && yearInteger > 999) {
- const selectedDate = new Date(yearInteger, monthInteger - 1, dayInteger, 12, 0, 0, 0);
- this.setState({
- selectedDate: selectedDate,
- displayDate: selectedDate,
- value: selectedDate.toISOString()
- });
-
- if (this.props.onChange) {
- this.props.onChange(selectedDate.toISOString(), inputValue);
- }
- }
-
this.setState({
- inputValue: inputValue
+ displayDate: selectedDate,
+ inputValue: inputValue,
+ selectedDate: selectedDate,
+ value: selectedDate.format()
});
+ if (this.props.onChange) {
+ this.props.onChange(selectedDate.format(), inputValue);
+ }
},
onChangeMonth(newDisplayDate) {