From ec4e7174fccaa9951f9ffa2cd3a9bcf660e9bd7b Mon Sep 17 00:00:00 2001 From: gReis89 Date: Wed, 12 Apr 2017 16:12:39 -0300 Subject: [PATCH 1/3] Adding new property todayDate --- README.md | 4 ++++ example/app.jsx | 22 ++++++++++++++++------ src/index.jsx | 12 ++++++++---- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 245643b..77220e7 100755 --- a/README.md +++ b/README.md @@ -198,6 +198,10 @@ DatePicker component. Renders as a [React-Bootstrap InputGroup](https://react-bo * **Optional** * **Type:** `React.Component` * **Example:** `` + * `todayDate` - Change today's date to a past or future date + * **Optional** + * **Type:** `string` + * **Example:** `"MM/DD/YYYY"`, `"YYYY/MM/DD"`, `"MM-DD-YYYY"`, or `"DD MM YYYY"` * **Methods:** diff --git a/example/app.jsx b/example/app.jsx index 463db13..4510256 100755 --- a/example/app.jsx +++ b/example/app.jsx @@ -24,7 +24,8 @@ const App = React.createClass({ previousDate: null, minDate: null, maxDate: null, - focused: false + focused: false, + todayDate: new Date('2017', '0', '1').toISOString() }; }, handleChange(value) { @@ -59,7 +60,6 @@ const App = React.createClass({ } }, render() { - const LabelISOString = new Date().toISOString(); return @@ -207,7 +207,7 @@ const App = React.createClass({ Min - {`Configure Example minDate`} + Configure Example minDate {`value: ${this.state.minDate}`} @@ -215,7 +215,7 @@ const App = React.createClass({ Max - {`Configure Example maxDate`} + Configure Example maxDate {`value: ${this.state.maxDate}`} @@ -286,12 +286,19 @@ const App = React.createClass({ - + Control Element } /> + + + Today Date + + Today's date is set to 01/01/2017 + + @@ -428,7 +435,10 @@ const App = React.createClass({ const CustomControl = React.createClass({ displayName: 'CustomControl', - + propTypes: { + value: React.PropTypes.string, + placeholder: React.PropTypes.string + }, render() { const { value, diff --git a/src/index.jsx b/src/index.jsx index 29a2744..6b0d85b 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -88,7 +88,8 @@ const Calendar = React.createClass({ weekStartsOn: React.PropTypes.number, showTodayButton: React.PropTypes.bool, todayButtonLabel: React.PropTypes.string, - roundedCorners: React.PropTypes.bool + roundedCorners: React.PropTypes.bool, + todayDate: React.PropTypes.string }, handleClick(day) { @@ -98,7 +99,7 @@ const Calendar = React.createClass({ }, handleClickToday() { - const newSelectedDate = this.setTimeToNoon(new Date()); + const newSelectedDate = this.setTimeToNoon(this.props.todayDate ? new Date(this.props.todayDate) : new Date()); this.props.onChange(newSelectedDate); }, @@ -268,7 +269,8 @@ export default React.createClass({ children: React.PropTypes.oneOfType([ React.PropTypes.arrayOf(React.PropTypes.node), React.PropTypes.node - ]) + ]), + todayDate: React.PropTypes.string }, getDefaultProps() { @@ -330,7 +332,8 @@ export default React.createClass({ if (selectedDate) { displayDate = new Date(selectedDate); } else { - const today = new Date(`${(new Date().toISOString().slice(0,10))}T12:00:00.000Z`); + const today = this.props.todayDate ? new Date(`${this.props.todayDate.slice(0,10)}T12:00:00.000Z`) + : new Date(`${(new Date().toISOString().slice(0,10))}T12:00:00.000Z`); if (minDate && Date.parse(minDate) >= Date.parse(today)){ displayDate = minDate; } else if (maxDate && Date.parse(maxDate) <= Date.parse(today)){ @@ -657,6 +660,7 @@ export default React.createClass({ minDate={this.props.minDate} maxDate={this.props.maxDate} roundedCorners={this.props.roundedCorners} + todayDate={this.props.todayDate} /> From ff95ccddfa70cb4e29ce7fd08dbe8cd77229600f Mon Sep 17 00:00:00 2001 From: gReis89 Date: Thu, 13 Apr 2017 11:12:56 -0300 Subject: [PATCH 2/3] Adding builded file --- lib/index.js | 72 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/lib/index.js b/lib/index.js index 246382f..b363d86 100644 --- a/lib/index.js +++ b/lib/index.js @@ -41,12 +41,28 @@ var CalendarHeader = _react2.default.createClass({ propTypes: { displayDate: _react2.default.PropTypes.object.isRequired, + minDate: _react2.default.PropTypes.string, + maxDate: _react2.default.PropTypes.string, onChange: _react2.default.PropTypes.func.isRequired, monthLabels: _react2.default.PropTypes.array.isRequired, previousButtonElement: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]).isRequired, nextButtonElement: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]).isRequired }, + displayingMinMonth: function displayingMinMonth() { + if (!this.props.minDate) return false; + + var displayDate = new Date(this.props.displayDate); + var minDate = new Date(this.props.minDate); + return minDate.getFullYear() == displayDate.getFullYear() && minDate.getMonth() == displayDate.getMonth(); + }, + displayingMaxMonth: function displayingMaxMonth() { + if (!this.props.maxDate) return false; + + var displayDate = new Date(this.props.displayDate); + var maxDate = new Date(this.props.maxDate); + return maxDate.getFullYear() == displayDate.getFullYear() && maxDate.getMonth() == displayDate.getMonth(); + }, handleClickPrevious: function handleClickPrevious() { var newDisplayDate = new Date(this.props.displayDate); newDisplayDate.setDate(1); @@ -65,8 +81,8 @@ var CalendarHeader = _react2.default.createClass({ { className: 'text-center' }, _react2.default.createElement( 'div', - { className: 'text-muted pull-left', onClick: this.handleClickPrevious, style: { cursor: 'pointer' } }, - this.props.previousButtonElement + { className: 'text-muted pull-left datepicker-previous-wrapper', onClick: this.handleClickPrevious, style: { cursor: 'pointer' } }, + this.displayingMinMonth() ? null : this.props.previousButtonElement ), _react2.default.createElement( 'span', @@ -77,8 +93,8 @@ var CalendarHeader = _react2.default.createClass({ ), _react2.default.createElement( 'div', - { className: 'text-muted pull-right', onClick: this.handleClickNext, style: { cursor: 'pointer' } }, - this.props.nextButtonElement + { className: 'text-muted pull-right datepicker-next-wrapper', onClick: this.handleClickNext, style: { cursor: 'pointer' } }, + this.displayingMaxMonth() ? null : this.props.nextButtonElement ) ); } @@ -100,7 +116,8 @@ var Calendar = _react2.default.createClass({ weekStartsOn: _react2.default.PropTypes.number, showTodayButton: _react2.default.PropTypes.bool, todayButtonLabel: _react2.default.PropTypes.string, - roundedCorners: _react2.default.PropTypes.bool + roundedCorners: _react2.default.PropTypes.bool, + todayDate: _react2.default.PropTypes.string }, handleClick: function handleClick(day) { @@ -109,7 +126,7 @@ var Calendar = _react2.default.createClass({ this.props.onChange(newSelectedDate); }, handleClickToday: function handleClickToday() { - var newSelectedDate = this.setTimeToNoon(new Date()); + var newSelectedDate = this.setTimeToNoon(this.props.todayDate ? new Date(this.props.todayDate) : new Date()); this.props.onChange(newSelectedDate); }, setTimeToNoon: function setTimeToNoon(date) { @@ -278,7 +295,7 @@ exports.default = _react2.default.createClass({ showClearButton: _react2.default.PropTypes.bool, previousButtonElement: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]), nextButtonElement: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]), - calendarPlacement: _react2.default.PropTypes.string, + calendarPlacement: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.func]), dateFormat: _react2.default.PropTypes.string, // 'MM/DD/YYYY', 'DD/MM/YYYY', 'YYYY/MM/DD', 'DD-MM-YYYY' bsClass: _react2.default.PropTypes.string, bsSize: _react2.default.PropTypes.string, @@ -290,7 +307,8 @@ exports.default = _react2.default.createClass({ instanceCount: _react2.default.PropTypes.number, customControl: _react2.default.PropTypes.object, roundedCorners: _react2.default.PropTypes.bool, - children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.arrayOf(_react2.default.PropTypes.node), _react2.default.PropTypes.node]) + children: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.arrayOf(_react2.default.PropTypes.node), _react2.default.PropTypes.node]), + todayDate: _react2.default.PropTypes.string }, getDefaultProps: function getDefaultProps() { @@ -339,11 +357,21 @@ exports.default = _react2.default.createClass({ makeDateValues: function makeDateValues(isoString) { var displayDate = void 0; var selectedDate = isoString ? new Date(isoString.slice(0, 10) + 'T12:00:00.000Z') : null; + var minDate = this.props.minDate ? new Date(isoString.slice(0, 10) + 'T12:00:00.000Z') : null; + var maxDate = this.props.maxDate ? new Date(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 today = this.props.todayDate ? new Date(this.props.todayDate.slice(0, 10) + 'T12:00:00.000Z') : new Date(new Date().toISOString().slice(0, 10) + 'T12:00:00.000Z'); + if (minDate && Date.parse(minDate) >= Date.parse(today)) { + displayDate = minDate; + } else if (maxDate && Date.parse(maxDate) <= Date.parse(today)) { + displayDate = maxDate; + } else { + displayDate = today; + } } return { @@ -397,9 +425,12 @@ exports.default = _react2.default.createClass({ return; } + var placement = this.getCalendarPlacement(); + this.setState({ inputFocused: true, - focused: true + focused: true, + calendarPlacement: placement }); if (this.props.onFocus) { @@ -426,6 +457,15 @@ exports.default = _react2.default.createClass({ getFormattedValue: function getFormattedValue() { return this.state.displayDate ? this.state.inputValue : null; }, + getCalendarPlacement: function getCalendarPlacement() { + var tag = Object.prototype.toString.call(this.props.calendarPlacement); + var isFunction = tag === '[object AsyncFunction]' || tag === '[object Function]' || tag === '[object GeneratorFunction]' || tag === '[object Proxy]'; + if (isFunction) { + return this.props.calendarPlacement(); + } else { + return this.props.calendarPlacement; + } + }, makeInputValueString: function makeInputValueString(date) { var month = date.getMonth() + 1; var day = date.getDate(); @@ -476,6 +516,11 @@ 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); + if (!inputValue) { + this.clear(); + return; + } + var month = void 0, day = void 0, year = void 0; @@ -568,6 +613,8 @@ exports.default = _react2.default.createClass({ previousButtonElement: this.props.previousButtonElement, nextButtonElement: this.props.nextButtonElement, displayDate: this.state.displayDate, + minDate: this.props.minDate, + maxDate: this.props.maxDate, onChange: this.onChangeMonth, monthLabels: this.props.monthLabels, dateFormat: this.props.dateFormat }); @@ -622,7 +669,7 @@ exports.default = _react2.default.createClass({ target: function target() { return _reactDom2.default.findDOMNode(_this2.refs.input); }, - placement: this.props.calendarPlacement, + placement: this.state.calendarPlacement, delayHide: 200 }, _react2.default.createElement( _Popover2.default, @@ -638,7 +685,8 @@ exports.default = _react2.default.createClass({ todayButtonLabel: this.props.todayButtonLabel, minDate: this.props.minDate, maxDate: this.props.maxDate, - roundedCorners: this.props.roundedCorners + roundedCorners: this.props.roundedCorners, + todayDate: this.props.todayDate }) ) ), From 4891a7e759cddec29a71f80545b56c07b5791928 Mon Sep 17 00:00:00 2001 From: gReis89 Date: Fri, 19 Jan 2018 08:11:41 -0200 Subject: [PATCH 3/3] fixing failing test due to default date format for different areas --- test/core.test.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/core.test.jsx b/test/core.test.jsx index 88f21a5..12e38c6 100755 --- a/test/core.test.jsx +++ b/test/core.test.jsx @@ -56,10 +56,11 @@ describe("Date Picker", function() { it("should render a date picker with a value.", co.wrap(function *(){ const id = UUID.v4(); const value = `${new Date().toISOString().slice(0,10)}T12:00:00.000Z`; + console.log(value) const App = createReactClass({ render: function(){ return
- +
; } }); @@ -67,6 +68,7 @@ describe("Date Picker", function() { ReactDOM.render(, container, resolve); }); const hiddenInputElement = document.getElementById(id); + console.log(hiddenInputElement.value) assertIsoStringsHaveSameDate(hiddenInputElement.value, value); assert.equal(hiddenInputElement.getAttribute('data-formattedvalue'), `${value.slice(5,7)}/${value.slice(8,10)}/${value.slice(0,4)}`); ReactDOM.unmountComponentAtNode(container);