From c7776a969a04ee4ebd8b93dec250b5bdd6f37227 Mon Sep 17 00:00:00 2001 From: marquex Date: Thu, 18 Jun 2015 23:53:24 +0200 Subject: [PATCH] Some clean up --- css/bootstrap-datetimepicker.css | 188 +++++--- dist/react-bootstrap-datetimepicker.js | 508 ++++++++++---------- package.json | 11 +- src/DateTimeField.jsx | 628 ++++++++++++------------- src/DateTimePicker.jsx | 118 ----- src/DateTimePickerDate.jsx | 143 ------ src/DateTimePickerDays.jsx | 42 +- src/DateTimePickerHours.jsx | 95 ---- src/DateTimePickerMinutes.jsx | 65 --- src/DateTimePickerMonths.jsx | 60 +-- src/DateTimePickerTime.jsx | 246 ++++++---- src/DateTimePickerYears.jsx | 38 +- webpack.config.js | 6 +- 13 files changed, 882 insertions(+), 1266 deletions(-) delete mode 100644 src/DateTimePicker.jsx delete mode 100644 src/DateTimePickerDate.jsx delete mode 100644 src/DateTimePickerHours.jsx delete mode 100644 src/DateTimePickerMinutes.jsx diff --git a/css/bootstrap-datetimepicker.css b/css/bootstrap-datetimepicker.css index 05c1d8c91..ecf5f6055 100644 --- a/css/bootstrap-datetimepicker.css +++ b/css/bootstrap-datetimepicker.css @@ -2,19 +2,23 @@ * Datetimepicker for Bootstrap v3 * https://github.com/Eonasdan/bootstrap-datetimepicker/ */ -.bootstrap-datetimepicker-widget { - top: 0; - left: 0; + +.datetimePicker { + position: relative; +} +.dropdown-menu { width: 250px; padding: 4px; margin-top: 1px; z-index: 99999 !important; - border-radius: 4px; + background: #fff; + box-shadow: 0 1px 3px rgba(0,0,0,.1); + transition: height .5s; } -.bootstrap-datetimepicker-widget.timepicker-sbs { +.dropdown-menu.timepicker-sbs { width: 600px; } -.bootstrap-datetimepicker-widget.bottom:before { +.dropdown-menu.bottom:before { content: ''; display: inline-block; border-left: 7px solid transparent; @@ -25,7 +29,7 @@ top: -7px; left: 7px; } -.bootstrap-datetimepicker-widget.bottom:after { +.dropdown-menu.bottom:after { content: ''; display: inline-block; border-left: 6px solid transparent; @@ -35,7 +39,7 @@ top: -6px; left: 8px; } -.bootstrap-datetimepicker-widget.top:before { +.dropdown-menu.top:before { content: ''; display: inline-block; border-left: 7px solid transparent; @@ -46,7 +50,7 @@ bottom: -7px; left: 6px; } -.bootstrap-datetimepicker-widget.top:after { +.dropdown-menu.top:after { content: ''; display: inline-block; border-left: 6px solid transparent; @@ -56,65 +60,67 @@ bottom: -6px; left: 7px; } -.bootstrap-datetimepicker-widget .dow { +.dropdown-menu .dow { width: 14.2857%; } -.bootstrap-datetimepicker-widget.pull-right:before { +.dropdown-menu.pull-right:before { left: auto; right: 6px; } -.bootstrap-datetimepicker-widget.pull-right:after { +.dropdown-menu.pull-right:after { left: auto; right: 7px; } -.bootstrap-datetimepicker-widget > ul { +.dropdown-menu > ul { list-style-type: none; margin: 0; } -.bootstrap-datetimepicker-widget .timepicker-hour, -.bootstrap-datetimepicker-widget .timepicker-minute, -.bootstrap-datetimepicker-widget .timepicker-second { +.dropdown-menu .timeToggle { + text-align: center; +} +.dropdown-menu .timepicker-hour, +.dropdown-menu .timepicker-minute, +.dropdown-menu .timepicker-second { width: 100%; font-weight: bold; font-size: 1.2em; } -.bootstrap-datetimepicker-widget table[data-hour-format="12"] .separator { +.dropdown-menu table[data-hour-format="12"] .separator { width: 4px; padding: 0; margin: 0; } -.bootstrap-datetimepicker-widget .datepicker > div { +.dropdown-menu .datepicker > div { display: none; } -.bootstrap-datetimepicker-widget .picker-switch { +.dropdown-menu .picker-switch { text-align: center; } -.bootstrap-datetimepicker-widget table { +.dropdown-menu table { width: 100%; margin: 0; } -.bootstrap-datetimepicker-widget td, -.bootstrap-datetimepicker-widget th { +.dropdown-menu td, +.dropdown-menu th { text-align: center; - width: 20px; - height: 20px; - border-radius: 4px; -} -.bootstrap-datetimepicker-widget td.day:hover, -.bootstrap-datetimepicker-widget td.hour:hover, -.bootstrap-datetimepicker-widget td.minute:hover, -.bootstrap-datetimepicker-widget td.second:hover { + height: 28px; +} +.dropdown-menu td.day:hover, +.dropdown-menu td.hour:hover, +.dropdown-menu td.minute:hover, +.dropdown-menu td.second:hover, +.dropdown-menu .timeToggle:hover { background: #eeeeee; cursor: pointer; } -.bootstrap-datetimepicker-widget td.old, -.bootstrap-datetimepicker-widget td.new { +.dropdown-menu td.old, +.dropdown-menu td.new { color: #999999; } -.bootstrap-datetimepicker-widget td.today { +.dropdown-menu td.today { position: relative; } -.bootstrap-datetimepicker-widget td.today:before { +.dropdown-menu td.today:before { content: ''; display: inline-block; border-left: 7px solid transparent; @@ -124,65 +130,49 @@ bottom: 4px; right: 4px; } -.bootstrap-datetimepicker-widget td.active, -.bootstrap-datetimepicker-widget td.active:hover { +.dropdown-menu td.active, +.dropdown-menu td.active:hover { background-color: #428bca; color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } -.bootstrap-datetimepicker-widget td.active.today:before { +.dropdown-menu td.active.today:before { border-bottom-color: #fff; } -.bootstrap-datetimepicker-widget td.disabled, -.bootstrap-datetimepicker-widget td.disabled:hover { +.dropdown-menu td.disabled, +.dropdown-menu td.disabled:hover { background: none; color: #999999; cursor: not-allowed; } -.bootstrap-datetimepicker-widget td span { - display: block; - width: 47px; - height: 54px; - line-height: 54px; - float: left; - margin: 2px; - cursor: pointer; - border-radius: 4px; -} -.bootstrap-datetimepicker-widget td span:hover { - background: #eeeeee; -} -.bootstrap-datetimepicker-widget td span.active { - background-color: #428bca; - color: #fff; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); -} -.bootstrap-datetimepicker-widget td span.old { + +.dropdown-menu td span.old { color: #999999; } -.bootstrap-datetimepicker-widget td span.disabled, -.bootstrap-datetimepicker-widget td span.disabled:hover { +.dropdown-menu td span.disabled, +.dropdown-menu td span.disabled:hover { background: none; color: #999999; cursor: not-allowed; } -.bootstrap-datetimepicker-widget th.switch { +.dropdown-menu th.switch { width: 145px; } -.bootstrap-datetimepicker-widget th.next, -.bootstrap-datetimepicker-widget th.prev { +.dropdown-menu th.next, +.dropdown-menu th.prev { font-size: 21px; + vertical-align: top; } -.bootstrap-datetimepicker-widget th.disabled, -.bootstrap-datetimepicker-widget th.disabled:hover { +.dropdown-menu th.disabled, +.dropdown-menu th.disabled:hover { background: none; color: #999999; cursor: not-allowed; } -.bootstrap-datetimepicker-widget thead tr:first-child th { +.dropdown-menu thead tr:first-child th { cursor: pointer; } -.bootstrap-datetimepicker-widget thead tr:first-child th:hover { +.dropdown-menu thead tr:first-child th:hover { background: #eeeeee; } .input-group.date .input-group-addon span { @@ -191,14 +181,70 @@ width: 16px; height: 16px; } -.bootstrap-datetimepicker-widget.left-oriented:before { +.dropdown-menu.left-oriented:before { left: auto; right: 6px; } -.bootstrap-datetimepicker-widget.left-oriented:after { +.dropdown-menu.left-oriented:after { left: auto; right: 7px; } -.bootstrap-datetimepicker-widget ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td { +.dropdown-menu ul.list-unstyled li div.timepicker div.timepicker-picker table.table-condensed tbody > tr > td { padding: 0px !important; -} \ No newline at end of file +} + +td.month, +td.year { + height: 50px; + width: 25%; + cursor: pointer; +} +td.month:hover, +td.year:hover { + background: #eee; +} + +.dtCounters { + display: inline-block; +} + +.dtCounters > div{ + float: left; +} + +.dtCounter { + height: 100px; +} + +.dtCounter { + width: 40px; +} + +.dtCounterSeparator { + line-height: 100px; +} + +.dtCounter .btn { + height: 40%; + line-height: 40px; + cursor: pointer; +} +.dtCounter .btn:hover { + background: #eee; +} +.dtCounter .dtCount { + height: 20%; + font-size: 1.2em; +} + +.dtMilli { + vertical-align: middle; + padding-left: 8px; + width: 48px; +} + +.dtMilli input { + width: 100%; + font-size: 1.2em; + margin-top: 37px; +} diff --git a/dist/react-bootstrap-datetimepicker.js b/dist/react-bootstrap-datetimepicker.js index 7a4ca773d..878e61116 100644 --- a/dist/react-bootstrap-datetimepicker.js +++ b/dist/react-bootstrap-datetimepicker.js @@ -1,13 +1,13 @@ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(require("React"), require("moment"), require("ReactBootstrap")); + module.exports = factory(require("React"), require("moment")); else if(typeof define === 'function' && define.amd) - define(["React", "moment", "ReactBootstrap"], factory); + define(["React", "moment"], factory); else if(typeof exports === 'object') - exports["ReactBootstrapDatetimepicker"] = factory(require("React"), require("moment"), require("ReactBootstrap")); + exports["Datetime"] = factory(require("React"), require("moment")); else - root["ReactBootstrapDatetimepicker"] = factory(root["React"], root["moment"], root["ReactBootstrap"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_4__) { + root["Datetime"] = factory(root["React"], root["moment"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_6__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -61,17 +61,15 @@ return /******/ (function(modules) { // webpackBootstrap /* 1 */ /***/ function(module, exports, __webpack_require__) { - var DateTimeField, DateTimePicker, Glyphicon, React, moment; + var DateTimeField, DateTimePicker, React, moment; React = __webpack_require__(2); - DateTimePicker = __webpack_require__(5); + DateTimePicker = __webpack_require__(3); - moment = __webpack_require__(3); + moment = __webpack_require__(6); - var Glyphicon = __webpack_require__(4).Glyphicon; - - var Constants = __webpack_require__(6); + var Constants = __webpack_require__(11); DateTimeField = React.createClass({displayName: "DateTimeField", propTypes: { @@ -160,8 +158,8 @@ return /******/ (function(modules) { // webpackBootstrap var target = e.target; if (target.className && !target.className.match(/disabled/g)) { 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; + if(target.className.indexOf("new") >= 0) month = this.state.viewDate.month() + 1; + else if(target.className.indexOf("old") >= 0) month = this.state.viewDate.month() - 1; else month = this.state.viewDate.month(); return this.setState({ selectedDate: this.state.viewDate.clone().month(month).date(parseInt(e.target.innerHTML)).hour(this.state.selectedDate.hours()).minute(this.state.selectedDate.minutes()) @@ -290,46 +288,23 @@ return /******/ (function(modules) { // webpackBootstrap }); }, onClick: function() { - var classes, gBCR, offset, placePosition, scrollTop, styles; + var classes = [], + gBCR, offset, placePosition, scrollTop, styles + ; if (this.state.showPicker) { return this.closePicker(); } else { - this.setState({ - showPicker: true - }); - gBCR = this.refs.dtpbutton.getDOMNode().getBoundingClientRect(); - classes = { - "bootstrap-datetimepicker-widget": true, - "dropdown-menu": true - }; - offset = { - top: gBCR.top + window.pageYOffset - document.documentElement.clientTop, - left: gBCR.left + window.pageXOffset - document.documentElement.clientLeft - }; - offset.top = offset.top + this.refs.datetimepicker.getDOMNode().offsetHeight; - scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; - placePosition = this.props.direction === 'up' ? 'top' : this.props.direction === 'bottom' ? 'bottom' : this.props.direction === 'auto' ? offset.top + this.refs.widget.getDOMNode().offsetHeight > window.offsetHeight + scrollTop && this.refs.widget.offsetHeight + this.refs.datetimepicker.getDOMNode().offsetHeight > offset.top ? 'top' : 'bottom' : void 0; - if (placePosition === 'top') { - offset.top = -this.refs.widget.getDOMNode().offsetHeight - this.getDOMNode().clientHeight - 2; - classes["top"] = true; - classes["bottom"] = false; - classes['pull-right'] = true; - } else { - offset.top = 40; - classes["top"] = false; - classes["bottom"] = true; - classes['pull-right'] = true; - } + classes = [ "bootstrap-datetimepicker-widget", "dropdown-menu", "bottom", "pull-right" ]; styles = { display: 'block', position: 'absolute', - top: offset.top, left: 'auto', right: 40 }; return this.setState({ widgetStyle: styles, - widgetClasses: classes + widgetClasses: classes.join(" "), + showPicker: true }); } }, @@ -363,40 +338,39 @@ return /******/ (function(modules) { // webpackBootstrap return ( React.createElement("div", null, this.renderOverlay(), - React.createElement(DateTimePicker, {ref: "widget", - widgetClasses: this.state.widgetClasses, - widgetStyle: this.state.widgetStyle, - showDatePicker: this.state.showDatePicker, - showTimePicker: this.state.showTimePicker, - viewDate: this.state.viewDate, - selectedDate: this.state.selectedDate, - showToday: this.props.showToday, - viewMode: this.props.viewMode, - daysOfWeekDisabled: this.props.daysOfWeekDisabled, - mode: this.props.mode, - minDate: this.props.minDate, - maxDate: this.props.maxDate, - addDecade: this.addDecade, - addYear: this.addYear, - addMonth: this.addMonth, - addHour: this.addHour, - addMinute: this.addMinute, - subtractDecade: this.subtractDecade, - subtractYear: this.subtractYear, - subtractMonth: this.subtractMonth, - subtractHour: this.subtractHour, - subtractMinute: this.subtractMinute, - setViewYear: this.setViewYear, - setViewMonth: this.setViewMonth, - setSelectedDate: this.setSelectedDate, - setSelectedHour: this.setSelectedHour, - setSelectedMinute: this.setSelectedMinute, - togglePicker: this.togglePicker, - togglePeriod: this.togglePeriod} - ), - React.createElement("div", {className: "input-group date", ref: "datetimepicker"}, + React.createElement(DateTimePicker, { + widgetClasses: this.state.widgetClasses, + widgetStyle: this.state.widgetStyle, + showDatePicker: this.state.showDatePicker, + showTimePicker: this.state.showTimePicker, + viewDate: this.state.viewDate, + selectedDate: this.state.selectedDate, + showToday: this.props.showToday, + viewMode: this.props.viewMode, + daysOfWeekDisabled: this.props.daysOfWeekDisabled, + mode: this.props.mode, + minDate: this.props.minDate, + maxDate: this.props.maxDate, + addDecade: this.addDecade, + addYear: this.addYear, + addMonth: this.addMonth, + addHour: this.addHour, + addMinute: this.addMinute, + subtractDecade: this.subtractDecade, + subtractYear: this.subtractYear, + subtractMonth: this.subtractMonth, + subtractHour: this.subtractHour, + subtractMinute: this.subtractMinute, + setViewYear: this.setViewYear, + setViewMonth: this.setViewMonth, + setSelectedDate: this.setSelectedDate, + setSelectedHour: this.setSelectedHour, + setSelectedMinute: this.setSelectedMinute, + togglePicker: this.togglePicker, + togglePeriod: this.togglePeriod}), + React.createElement("div", {className: "input-group date"}, React.createElement("input", React.__spread({type: "text", className: "form-control", onChange: this.onChange, value: this.state.inputValue}, this.props.inputProps)), - React.createElement("span", {className: "input-group-addon", onClick: this.onClick, onBlur: this.onBlur, ref: "dtpbutton"}, React.createElement(Glyphicon, {glyph: this.state.buttonIcon})) + React.createElement("span", {className: "input-group-addon", onClick: this.onClick, onBlur: this.onBlur}, "But") ) ) ); @@ -408,7 +382,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, /* 2 */ -/***/ function(module, exports, __webpack_require__) { +/***/ function(module, exports) { module.exports = __WEBPACK_EXTERNAL_MODULE_2__; @@ -416,29 +390,15 @@ return /******/ (function(modules) { // webpackBootstrap /* 3 */ /***/ function(module, exports, __webpack_require__) { - module.exports = __WEBPACK_EXTERNAL_MODULE_3__; - -/***/ }, -/* 4 */ -/***/ function(module, exports, __webpack_require__) { - - module.exports = __WEBPACK_EXTERNAL_MODULE_4__; - -/***/ }, -/* 5 */ -/***/ function(module, exports, __webpack_require__) { - - var DateTimePicker, DateTimePickerDate, DateTimePickerTime, Glyphicon, React; + var DateTimePicker, DateTimePickerDate, DateTimePickerTime, React; React = __webpack_require__(2); - DateTimePickerDate = __webpack_require__(7); - - DateTimePickerTime = __webpack_require__(8); + DateTimePickerDate = __webpack_require__(4); - var Glyphicon = __webpack_require__(4).Glyphicon; + DateTimePickerTime = __webpack_require__(9); - var Constants = __webpack_require__(6); + var Constants = __webpack_require__(11); DateTimePicker = React.createClass({displayName: "DateTimePicker", propTypes: { @@ -520,14 +480,17 @@ return /******/ (function(modules) { // webpackBootstrap return this.props.mode === Constants.MODE_DATETIME ? ( React.createElement("li", null, - React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.togglePicker}, React.createElement(Glyphicon, {glyph: this.props.showTimePicker ? 'calendar' : 'time'})) + React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.togglePicker}, "Sw") ) ) : null; }, render: function() { + var className = ''; + if( this.props.widgetClasses ) + className = this.props.widgetClasses.join(' '); return ( - React.createElement("div", {className: React.addons.classSet(this.props.widgetClasses), style: this.props.widgetStyle}, + React.createElement("div", {className: className, style: this.props.widgetStyle}, React.createElement("ul", {className: "list-unstyled"}, @@ -549,28 +512,18 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 6 */ -/***/ function(module, exports, __webpack_require__) { - - module.exports = { - MODE_DATE: 'date', - MODE_DATETIME: 'datetime', - MODE_TIME: 'time' - }; - -/***/ }, -/* 7 */ +/* 4 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerDate, DateTimePickerDays, DateTimePickerMonths, DateTimePickerYears, React; React = __webpack_require__(2); - DateTimePickerDays = __webpack_require__(9); + DateTimePickerDays = __webpack_require__(5); - DateTimePickerMonths = __webpack_require__(10); + DateTimePickerMonths = __webpack_require__(7); - DateTimePickerYears = __webpack_require__(11); + DateTimePickerYears = __webpack_require__(8); DateTimePickerDate = React.createClass({displayName: "DateTimePickerDate", propTypes: { @@ -708,140 +661,14 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 8 */ -/***/ function(module, exports, __webpack_require__) { - - var DateTimePickerHours, DateTimePickerMinutes, DateTimePickerTime, Glyphicon, React; - - React = __webpack_require__(2); - - DateTimePickerMinutes = __webpack_require__(12); - - DateTimePickerHours = __webpack_require__(13); - - var Glyphicon = __webpack_require__(4).Glyphicon; - - var Constants = __webpack_require__(6); - - DateTimePickerTime = React.createClass({displayName: "DateTimePickerTime", - propTypes: { - setSelectedHour: React.PropTypes.func.isRequired, - setSelectedMinute: React.PropTypes.func.isRequired, - subtractHour: React.PropTypes.func.isRequired, - addHour: React.PropTypes.func.isRequired, - subtractMinute: React.PropTypes.func.isRequired, - addMinute: React.PropTypes.func.isRequired, - viewDate: React.PropTypes.object.isRequired, - selectedDate: React.PropTypes.object.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({ - minutesDisplayed: true - }); - }, - showHours: function() { - return this.setState({ - hoursDisplayed: true - }); - }, - renderMinutes: function() { - if (this.state.minutesDisplayed) { - return React.createElement(DateTimePickerMinutes, React.__spread({}, this.props, {onSwitch: this.goBack})); - } else { - return null; - } - }, - renderHours: function() { - if (this.state.hoursDisplayed) { - return React.createElement(DateTimePickerHours, React.__spread({}, this.props, {onSwitch: this.goBack})); - } else { - return null; - } - }, - renderPicker: function() { - if (!this.state.minutesDisplayed && !this.state.hoursDisplayed) { - return ( - React.createElement("div", {className: "timepicker-picker"}, - React.createElement("table", {className: "table-condensed"}, - React.createElement("tbody", null, - React.createElement("tr", null, - React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.addHour}, React.createElement(Glyphicon, {glyph: "chevron-up"}))), - - React.createElement("td", {className: "separator"}), - - React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.addMinute}, React.createElement(Glyphicon, {glyph: "chevron-up"}))), - - React.createElement("td", {className: "separator"}) - ), - - React.createElement("tr", null, - React.createElement("td", null, React.createElement("span", {className: "timepicker-hour", onClick: this.showHours}, this.props.selectedDate.format('h'))), - - React.createElement("td", {className: "separator"}, ":"), - - React.createElement("td", null, React.createElement("span", {className: "timepicker-minute", onClick: this.showMinutes}, this.props.selectedDate.format('mm'))), - - React.createElement("td", {className: "separator"}), - - React.createElement("td", null, React.createElement("button", {className: "btn btn-primary", onClick: this.props.togglePeriod, type: "button"}, this.props.selectedDate.format('A'))) - ), - - React.createElement("tr", null, - React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.subtractHour}, React.createElement(Glyphicon, {glyph: "chevron-down"}))), - - React.createElement("td", {className: "separator"}), - - React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.subtractMinute}, React.createElement(Glyphicon, {glyph: "chevron-down"}))), - - React.createElement("td", {className: "separator"}) - ) - ) - ) - ) - ); - } else { - return ''; - } - }, - render: function() { - return ( - React.createElement("div", {className: "timepicker"}, - this.renderPicker(), - - this.renderHours(), - - this.renderMinutes() - ) - ); - } - }); - - module.exports = DateTimePickerTime; - - -/***/ }, -/* 9 */ +/* 5 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerDays, React, moment; React = __webpack_require__(2); - moment = __webpack_require__(3); + moment = __webpack_require__(6); DateTimePickerDays = React.createClass({displayName: "DateTimePickerDays", propTypes: { @@ -874,40 +701,38 @@ return /******/ (function(modules) { // webpackBootstrap html = []; cells = []; while (prevMonth.isBefore(nextMonth)) { - classes = { - day: true - }; + classes = 'day'; if (prevMonth.year() < year || (prevMonth.year() === year && prevMonth.month() < month)) { - classes['old'] = true; + classes += " old"; } else if (prevMonth.year() > year || (prevMonth.year() === year && prevMonth.month() > month)) { - classes['new'] = true; + classes += " new"; } if (prevMonth.isSame(moment({ y: this.props.selectedDate.year(), M: this.props.selectedDate.month(), d: this.props.selectedDate.date() }))) { - classes['active'] = true; + classes += " active"; } if (this.props.showToday) { if (prevMonth.isSame(moment(), 'day')) { - classes['today'] = true; + classes += " today"; } } if ((minDate && prevMonth.isBefore(minDate)) || (maxDate && prevMonth.isAfter(maxDate))) { - classes['disabled'] = true; + classes += " disabled"; } if (this.props.daysOfWeekDisabled) { _ref = this.props.daysOfWeekDisabled; for (_i = 0, _len = _ref.length; _i < _len; _i++) { i = _ref[_i]; if (prevMonth.day() === this.props.daysOfWeekDisabled[i]) { - classes['disabled'] = true; + classes += " disabled"; break; } } } - cells.push(React.createElement("td", {key: prevMonth.month() + '-' + prevMonth.date(), className: React.addons.classSet(classes), onClick: this.props.setSelectedDate}, prevMonth.date())); + cells.push(React.createElement("td", {key: prevMonth.month() + '-' + prevMonth.date(), className: classes, onClick: this.props.setSelectedDate}, prevMonth.date())); if (prevMonth.weekday() === moment().endOf('week').weekday()) { row = React.createElement("tr", {key: prevMonth.month() + '-' + prevMonth.date()}, cells); html.push(row); @@ -960,14 +785,20 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 10 */ +/* 6 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_6__; + +/***/ }, +/* 7 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerMonths, React, moment; React = __webpack_require__(2); - moment = __webpack_require__(3); + moment = __webpack_require__(6); DateTimePickerMonths = React.createClass({displayName: "DateTimePickerMonths", propTypes: { @@ -985,11 +816,11 @@ return /******/ (function(modules) { // webpackBootstrap i = 0; months = []; while (i < 12) { - classes = { - month: true, - 'active': i === month && this.props.viewDate.year() === this.props.selectedDate.year() - }; - months.push(React.createElement("span", {key: i, className: React.addons.classSet(classes), onClick: this.props.setViewMonth}, monthsShort[i])); + classes = "month"; + if( i === month && this.props.viewDate.year() === this.props.selectedDate.year() ) + classes += " active"; + + months.push(React.createElement("span", {key: i, className: classes, onClick: this.props.setViewMonth}, monthsShort[i])); i++; } return months; @@ -1023,7 +854,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 11 */ +/* 8 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerYears, React; @@ -1045,12 +876,13 @@ return /******/ (function(modules) { // webpackBootstrap year--; i = -1; while (i < 11) { - classes = { - year: true, - old: i === -1 | i === 10, - active: this.props.selectedDate.year() === year - }; - years.push(React.createElement("span", {key: year, className: React.addons.classSet(classes), onClick: this.props.setViewYear}, year)); + classes = 'year'; + if( i === -1 | i === 10 ) + classes += ' old'; + if( this.props.selectedDate.year() === year ) + classes += ' active'; + + years.push(React.createElement("span", {key: year, className: classes, onClick: this.props.setViewYear}, year)); year++; i++; } @@ -1087,15 +919,139 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 12 */ +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var DateTimePickerHours, DateTimePickerMinutes, DateTimePickerTime, React; + + React = __webpack_require__(2); + + DateTimePickerMinutes = __webpack_require__(10); + + DateTimePickerHours = __webpack_require__(12); + + var Constants = __webpack_require__(11); + + DateTimePickerTime = React.createClass({displayName: "DateTimePickerTime", + propTypes: { + setSelectedHour: React.PropTypes.func.isRequired, + setSelectedMinute: React.PropTypes.func.isRequired, + subtractHour: React.PropTypes.func.isRequired, + addHour: React.PropTypes.func.isRequired, + subtractMinute: React.PropTypes.func.isRequired, + addMinute: React.PropTypes.func.isRequired, + viewDate: React.PropTypes.object.isRequired, + selectedDate: React.PropTypes.object.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({ + minutesDisplayed: true + }); + }, + showHours: function() { + return this.setState({ + hoursDisplayed: true + }); + }, + renderMinutes: function() { + if (this.state.minutesDisplayed) { + return React.createElement(DateTimePickerMinutes, React.__spread({}, this.props, {onSwitch: this.goBack})); + } else { + return null; + } + }, + renderHours: function() { + if (this.state.hoursDisplayed) { + return React.createElement(DateTimePickerHours, React.__spread({}, this.props, {onSwitch: this.goBack})); + } else { + return null; + } + }, + renderPicker: function() { + if (!this.state.minutesDisplayed && !this.state.hoursDisplayed) { + return ( + React.createElement("div", {className: "timepicker-picker"}, + React.createElement("table", {className: "table-condensed"}, + React.createElement("tbody", null, + React.createElement("tr", null, + React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.addHour}, "▲")), + + React.createElement("td", {className: "separator"}), + + React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.addMinute}, "▲")), + + React.createElement("td", {className: "separator"}) + ), + + React.createElement("tr", null, + React.createElement("td", null, React.createElement("span", {className: "timepicker-hour", onClick: this.showHours}, this.props.selectedDate.format('h'))), + + React.createElement("td", {className: "separator"}, ":"), + + React.createElement("td", null, React.createElement("span", {className: "timepicker-minute", onClick: this.showMinutes}, this.props.selectedDate.format('mm'))), + + React.createElement("td", {className: "separator"}), + + React.createElement("td", null, React.createElement("button", {className: "btn btn-primary", onClick: this.props.togglePeriod, type: "button"}, this.props.selectedDate.format('A'))) + ), + + React.createElement("tr", null, + React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.subtractHour}, "▼")), + + React.createElement("td", {className: "separator"}), + + React.createElement("td", null, React.createElement("a", {className: "btn", onClick: this.props.subtractMinute}, "▼")), + + React.createElement("td", {className: "separator"}) + ) + ) + ) + ) + ); + } else { + return ''; + } + }, + render: function() { + return ( + React.createElement("div", {className: "timepicker"}, + this.renderPicker(), + + this.renderHours(), + + this.renderMinutes() + ) + ); + } + }); + + module.exports = DateTimePickerTime; + + +/***/ }, +/* 10 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerMinutes, React; React = __webpack_require__(2); - var Glyphicon = __webpack_require__(4).Glyphicon; - var Constants = __webpack_require__(6); - + + var Constants = __webpack_require__(11); + DateTimePickerMinutes = React.createClass({displayName: "DateTimePickerMinutes", propTypes: { setSelectedMinute: React.PropTypes.func.isRequired, @@ -1106,7 +1062,7 @@ return /******/ (function(modules) { // webpackBootstrap ( React.createElement("ul", {className: "list-unstyled"}, React.createElement("li", null, - React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.onSwitch}, React.createElement(Glyphicon, {glyph: "time"})) + React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.onSwitch}, "Time") ) ) ) : @@ -1158,14 +1114,24 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 13 */ +/* 11 */ +/***/ function(module, exports) { + + module.exports = { + MODE_DATE: 'date', + MODE_DATETIME: 'datetime', + MODE_TIME: 'time' + }; + +/***/ }, +/* 12 */ /***/ function(module, exports, __webpack_require__) { var DateTimePickerHours, React; React = __webpack_require__(2); - var Glyphicon = __webpack_require__(4).Glyphicon; - var Constants = __webpack_require__(6); + + var Constants = __webpack_require__(11); DateTimePickerHours = React.createClass({displayName: "DateTimePickerHours", propTypes: { @@ -1177,7 +1143,7 @@ return /******/ (function(modules) { // webpackBootstrap ( React.createElement("ul", {className: "list-unstyled"}, React.createElement("li", null, - React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.onSwitch}, React.createElement(Glyphicon, {glyph: "time"})) + React.createElement("span", {className: "btn picker-switch", style: {width:'100%'}, onClick: this.props.onSwitch}, "Sw") ) ) ) : diff --git a/package.json b/package.json index 1c557a5e0..c7cd07514 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "main": "./lib/DateTimeField.js", "scripts": { "build-npm": "jsx -x jsx ./src/ ./lib/", - "build": "NODE_ENV=production webpack --output-file react-bootstrap-datetimepicker.js", - "build-min": "NODE_ENV=production COMPRESS=1 webpack --output-file react-bootstrap-datetimepicker.min.js", + "build": "webpack --output-file react-bootstrap-datetimepicker.js", + "build-min": "$COMPRESS=1 webpack --output-file react-bootstrap-datetimepicker.min.js", "examples": "webpack-dev-server --config ./examples/webpack.config.js", "test-watch": "./node_modules/.bin/grunt watch 2>&1 >/dev/null & karma start karma.dev.js", "test": "./node_modules/.bin/grunt build && karma start karma.ci.js" @@ -26,7 +26,8 @@ "author": "Loïc CHOLLIER ", "license": "MIT", "peerDependencies": { - "react": ">=0.12" + "react": ">=0.12", + "moment": "^2.8.2" }, "devDependencies": { "envify": "~3.2.0", @@ -50,7 +51,7 @@ "webpack-dev-server": "^1.7.0" }, "dependencies": { - "moment": "^2.8.2", - "react-bootstrap": "^0.16.1" + "object-assign": "^3.0.0", + "react-onclickoutside": "^0.2.4" } } diff --git a/src/DateTimeField.jsx b/src/DateTimeField.jsx index a32d2ec82..a1d8b6f4c 100644 --- a/src/DateTimeField.jsx +++ b/src/DateTimeField.jsx @@ -1,343 +1,291 @@ -var DateTimeField, DateTimePicker, Glyphicon, React, moment; - -React = require('react'); - -DateTimePicker = require('./DateTimePicker'); - -moment = require('moment'); - -var Glyphicon = require('react-bootstrap').Glyphicon; - -var Constants = require('./Constants'); - -DateTimeField = React.createClass({ - propTypes: { - dateTime: React.PropTypes.string, - onChange: React.PropTypes.func, - format: React.PropTypes.string, - inputProps: React.PropTypes.object, - inputFormat: React.PropTypes.string, - defaultText: React.PropTypes.string, - mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]), - minDate: React.PropTypes.object, - maxDate: React.PropTypes.object - }, - getDefaultProps: function() { - return { - dateTime: moment().format('x'), - format: 'x', - showToday: true, - viewMode: 'days', - daysOfWeekDisabled: [], - mode: Constants.MODE_DATETIME, - onChange: function (x) { - console.log(x); - } - }; - }, - getInitialState: function() { - return { - 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', - left: -9999, - zIndex: '9999 !important' - }, - 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.resolvePropsInputFormat()) - }; - }, - componentWillReceiveProps: function(nextProps) { - if(moment(nextProps.dateTime, nextProps.format, true).isValid()) { - return this.setState({ - viewDate: moment(nextProps.dateTime, nextProps.format, true).startOf("month"), - selectedDate: moment(nextProps.dateTime, nextProps.format, true), - inputValue: moment(nextProps.dateTime, nextProps.format, true).format(nextProps.inputFormat) - }); - } - if (nextProps.inputFormat !== this.props.inputFormat) { - return this.setState({ - inputFormat: nextProps.inputFormat - }); - } - }, - 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"; - } - }, - onChange: function(event) { - var value = event.target == null ? event : event.target.value; - if (moment(value, this.state.inputFormat, true).isValid()) { - this.setState({ - 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.state.inputFormat, true).format(this.props.format)); - }); - - }, - setSelectedDate: function(e) { - var target = e.target; - if (target.className && !target.className.match(/disabled/g)) { - var month; - if(target.className.indexOf("new") >= 0) month = this.state.viewDate.month() + 1; - else if(target.className.indexOf("old") >= 0) month = this.state.viewDate.month() - 1; - else month = this.state.viewDate.month(); - return this.setState({ - 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.state.inputFormat) - }); - }); - } - }, - setSelectedHour: function(e) { - return this.setState({ - selectedDate: this.state.selectedDate.clone().hour(parseInt(e.target.innerHTML)).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.state.inputFormat) - }); - }); - }, - setSelectedMinute: function(e) { - return this.setState({ - selectedDate: this.state.selectedDate.clone().hour(this.state.selectedDate.hours()).minute(parseInt(e.target.innerHTML)) - }, function() { - this.closePicker(); - this.props.onChange(this.state.selectedDate.format(this.props.format)); - return this.setState({ - inputValue: this.state.selectedDate.format(this.state.inputFormat) - }); - }); - }, - setViewMonth: function(month) { - return this.setState({ - viewDate: this.state.viewDate.clone().month(month) - }); - }, - setViewYear: function(year) { - return this.setState({ - viewDate: this.state.viewDate.clone().year(year) - }); - }, - addMinute: function() { - return this.setState({ - selectedDate: this.state.selectedDate.clone().add(1, "minutes") - }, function() { - this.props.onChange(this.state.selectedDate.format(this.props.format)); - return this.setState({ - inputValue: this.state.selectedDate.format(this.resolvePropsInputFormat()) - }); - }); - }, - addHour: function() { - return this.setState({ - selectedDate: this.state.selectedDate.clone().add(1, "hours") - }, function() { - this.props.onChange(this.state.selectedDate.format(this.props.format)); - return this.setState({ - inputValue: this.state.selectedDate.format(this.resolvePropsInputFormat()) - }); - }); - }, - addMonth: function() { - return this.setState({ - viewDate: this.state.viewDate.add(1, "months") - }); - }, - addYear: function() { - return this.setState({ - viewDate: this.state.viewDate.add(1, "years") - }); - }, - addDecade: function() { - return this.setState({ - viewDate: this.state.viewDate.add(10, "years") - }); - }, - subtractMinute: function() { - return this.setState({ - selectedDate: this.state.selectedDate.clone().subtract(1, "minutes") - }, function() { - this.props.onChange(this.state.selectedDate.format(this.props.format)); - return this.setState({ - inputValue: this.state.selectedDate.format(this.resolvePropsInputFormat()) - }); - }); - }, - subtractHour: function() { - return this.setState({ - selectedDate: this.state.selectedDate.clone().subtract(1, "hours") - }, function() { - this.props.onChange(this.state.selectedDate.format(this.props.format)); - return this.setState({ - inputValue: this.state.selectedDate.format(this.resolvePropsInputFormat()) - }); - }); - }, - subtractMonth: function() { - return this.setState({ - viewDate: this.state.viewDate.subtract(1, "months") - }); - }, - subtractYear: function() { - return this.setState({ - viewDate: this.state.viewDate.subtract(1, "years") - }); - }, - subtractDecade: function() { - return this.setState({ - viewDate: this.state.viewDate.subtract(10, "years") - }); - }, - togglePeriod: function() { - if (this.state.selectedDate.hour() > 12) { - 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.state.inputFormat)); - } - }, - togglePicker: function() { - return this.setState({ - showDatePicker: !this.state.showDatePicker, - showTimePicker: !this.state.showTimePicker - }); - }, - onClick: function() { - var classes, gBCR, offset, placePosition, scrollTop, styles; - if (this.state.showPicker) { - return this.closePicker(); - } else { - this.setState({ - showPicker: true - }); - gBCR = this.refs.dtpbutton.getDOMNode().getBoundingClientRect(); - classes = { - "bootstrap-datetimepicker-widget": true, - "dropdown-menu": true - }; - offset = { - top: gBCR.top + window.pageYOffset - document.documentElement.clientTop, - left: gBCR.left + window.pageXOffset - document.documentElement.clientLeft - }; - offset.top = offset.top + this.refs.datetimepicker.getDOMNode().offsetHeight; - scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; - placePosition = this.props.direction === 'up' ? 'top' : this.props.direction === 'bottom' ? 'bottom' : this.props.direction === 'auto' ? offset.top + this.refs.widget.getDOMNode().offsetHeight > window.offsetHeight + scrollTop && this.refs.widget.offsetHeight + this.refs.datetimepicker.getDOMNode().offsetHeight > offset.top ? 'top' : 'bottom' : void 0; - if (placePosition === 'top') { - offset.top = -this.refs.widget.getDOMNode().offsetHeight - this.getDOMNode().clientHeight - 2; - classes["top"] = true; - classes["bottom"] = false; - classes['pull-right'] = true; - } else { - offset.top = 40; - classes["top"] = false; - classes["bottom"] = true; - classes['pull-right'] = true; - } - styles = { - display: 'block', - position: 'absolute', - top: offset.top, - left: 'auto', - right: 40 - }; - return this.setState({ - widgetStyle: styles, - widgetClasses: classes - }); - } - }, - closePicker: function(e) { - var style; - style = this.state.widgetStyle; - style['left'] = -9999; - style['display'] = 'none'; - return this.setState({ - showPicker: false, - widgetStyle: style - }); - }, - renderOverlay: function() { - var styles; - styles = { - position: 'fixed', - top: 0, - bottom: 0, - left: 0, - right: 0, - zIndex: '999' - }; - if (this.state.showPicker) { - return (
); - } else { - return ; - } - }, - render: function() { - return ( -
- {this.renderOverlay()} - -
- - -
-
- ); - } +'use strict'; + +var assign = require('object-assign'), +React = require('react'), +DaysView = require('./DateTimePickerDays'), +MonthsView = require('./DateTimePickerMonths'), +YearsView = require('./DateTimePickerYears'), +TimeView = require('./DateTimePickerTime'), +moment = require('moment'), +Constants = require('./Constants') +; + +var noop = function(){}; + +var DateTimeField = React.createClass({ + mixins: [ + require('react-onclickoutside') + ], + viewComponents: { + days: DaysView, + months: MonthsView, + years: YearsView, + time: TimeView + }, + propTypes: { + date: React.PropTypes.string, + onChange: React.PropTypes.func, + dateFormat: React.PropTypes.string, + timeFormat: React.PropTypes.string, + inputProps: React.PropTypes.object, + inputFormat: React.PropTypes.string, + defaultText: React.PropTypes.string, + mode: React.PropTypes.oneOf([Constants.MODE_DATE, Constants.MODE_DATETIME, Constants.MODE_TIME]), + minDate: React.PropTypes.object, + maxDate: React.PropTypes.object + }, + getDefaultProps: function() { + + return { + date: false, + format: 'x', + showToday: true, + viewMode: 'days', + daysOfWeekDisabled: [], + mode: Constants.MODE_DATETIME, + onChange: function (x) { + console.log(x); + } + }; + }, + getInitialState: function() { + var formats = this.getFormats( this.props ), + date = this.props.date || new Date() + ; + return { + currentView: this.props.mode === Constants.MODE_TIME ? 'time' : 'days', + showDatePicker: this.props.mode !== Constants.MODE_TIME, + showTimePicker: this.props.mode === Constants.MODE_TIME, + inputFormat: formats.datetime, + widgetStyle: { + display: 'block', + position: 'absolute', + left: -9999, + zIndex: '9999 !important' + }, + viewDate: moment(date).startOf("month"), + selectedDate: moment(date), + inputValue: typeof this.props.defaultText != 'undefined' ? this.props.defaultText : moment(date).format( formats.datetime ) + }; + }, + + getFormat: function( props ){ + return this.getFormats( props ).datetime; + }, + + getFormats: function( props ){ + var formats = { + date: '', + time: '', + datetime: '' + }; + + if( props.dateFormat ){ + formats.date = props.dateFormat; + } + if( props.timeFormat ){ + formats.time = props.timeFormat; + } + + if( !formats.date && !formats.time ){ + formats.date = 'MM/DD/YY'; + formats.time = 'H:mm'; + formats.datetime = 'MM/DD/YY H:mm'; + } + else { + if( props.dateFormat ){ + formats.date = props.dateFormat; + formats.datetime = formats.date; + } + if( props.timeFormat ){ + if( formats.date ) + formats.datetime += ' '; + formats.time = props.timeFormat; + formats.datetime += formats.time; + } + } + + return formats; + }, + + componentWillReceiveProps: function(nextProps) { + var formats = this.getFormats( nextProps ); + if(moment(nextProps.date).isValid()) { + return this.setState({ + viewDate: moment(nextProps.date).startOf("month"), + selectedDate: moment(nextProps.date), + inputValue: moment(nextProps.date).format(nextProps.inputFormat) + }); + } + if ( formats.datetime !== this.getFormats(this.props).datetime ) { + return this.setState({ + inputFormat: nextProps.inputFormat + }); + } + }, + + onChange: function(event) { + var value = event.target == null ? event : event.target.value; + if (moment(value).isValid()) { + this.setState({ + selectedDate: moment(value), + viewDate: moment(value).startOf("month") + }); + } + + return this.setState({ + inputValue: value + }, function() { + return this.props.onChange(moment(this.state.inputValue, this.state.inputFormat, true).format( this.getFormat( this.props ))); + }); + }, + + showView: function( view ){ + var me = this; + return function( e ){ + me.setState({ currentView: view }); + }; + }, + + setDate: function( type ){ + var me = this, + nextViews = { + month: 'days', + year: 'months' + } + ; + return function( e ){ + me.setState({ + viewDate: me.state.viewDate.clone()[ type ]( e.target.innerHTML ).startOf( type ), + currentView: nextViews[ type ] + }); + } + }, + + addTime: function( amount, type, toSelected ){ + return this.updateTime( 'add', amount, type, toSelected ); + }, + subtractTime: function( amount, type, toSelected ){ + return this.updateTime( 'subtract', amount, type, toSelected ); + }, + updateTime: function( op, amount, type, toSelected ){ + var me = this; + + return function(){ + var update = {}, + date = toSelected ? 'selectedDate' : 'viewDate' + ; + + update[ date ] = me.state[ date ].clone()[ op ]( amount, type ); + + me.setState( update ); + }; + }, + + allowedSetTime: ['hours','minutes','seconds', 'milliseconds'], + setTime: function( type, value ){ + var index = this.allowedSetTime.indexOf( type ) + 1, + date = this.state.selectedDate.clone(), + nextType + ; + + date[ type ]( value ); + for (; index < this.allowedSetTime.length; index++) { + nextType = this.allowedSetTime[index]; + date[ nextType ]( date[nextType]() ); + } + this.setState({ selectedDate: date, inputValue: date.format( this.state.inputFormat ) }, this.callOnChange ); + }, + + callOnChange: function(){ + this.props.onChange(this.state.selectedDate.format( this.getFormat( this.props ))); + }, + + updateDate: function( e ) { + var target = e.target, + modifier = 0, + currentDate = this.state.selectedDate, + date + ; + + if(target.className.indexOf("new") != -1) + modifier = 1; + else if(target.className.indexOf("old") != -1) + modifier = -1; + + date = this.state.viewDate.clone() + .month( this.state.viewDate.month() + modifier ) + .date( parseInt( target.innerHTML ) ) + .hours( currentDate.hours() ) + .minutes( currentDate.minutes() ) + .seconds( currentDate.seconds() ) + .milliseconds( currentDate.milliseconds() ) + ; + + this.setState({ + selectedDate: date, + viewDate: date.clone().startOf('month'), + inputValue: date.format( this.state.inputFormat ) + }); + }, + + openCalendar: function() { + var styles = { + display: 'block', + position: 'absolute' + } + ; + + this.setState({ + widgetStyle: styles, + widgetClasses: 'dropdown-menu bottom pull-right', + showPicker: true + }); + }, + + handleClickOutside: function(){ + this.setState({ + showPicker: false, + widgetStyle: { display: 'none' } + }); + }, + + componentProps: { + fromProps: ['showToday', 'viewMode', 'daysOfWeekDisabled', 'mode', 'minDate', 'maxDate'], + fromState: ['showDatePicker', 'showTimePicker', 'viewDate', 'selectedDate' ], + fromThis: ['setDate', 'setTime', 'showView', 'addTime', 'subtractTime', 'updateDate'] + }, + + getComponentProps: function(){ + var me = this, + formats = this.getFormats( this.props ), + props = {dateFormat: formats.date, timeFormat: formats.time} + ; + + this.componentProps.fromProps.forEach( function( name ){ + props[ name ] = me.props[ name ]; + }); + this.componentProps.fromState.forEach( function( name ){ + props[ name ] = me.state[ name ]; + }); + this.componentProps.fromThis.forEach( function( name ){ + props[ name ] = me[ name ]; + }); + + return props; + }, + + render: function() { + var Component = this.viewComponents[ this.state.currentView ]; + return ( +
+ +
+ +
+
+ ); + } }); module.exports = DateTimeField; diff --git a/src/DateTimePicker.jsx b/src/DateTimePicker.jsx deleted file mode 100644 index 19c70a542..000000000 --- a/src/DateTimePicker.jsx +++ /dev/null @@ -1,118 +0,0 @@ -var DateTimePicker, DateTimePickerDate, DateTimePickerTime, Glyphicon, React; - -React = require('react/addons'); - -DateTimePickerDate = require('./DateTimePickerDate'); - -DateTimePickerTime = require('./DateTimePickerTime'); - -var Glyphicon = require('react-bootstrap').Glyphicon; - -var Constants = require('./Constants'); - -DateTimePicker = React.createClass({ - propTypes: { - showDatePicker: React.PropTypes.bool, - showTimePicker: React.PropTypes.bool, - subtractMonth: React.PropTypes.func.isRequired, - addMonth: React.PropTypes.func.isRequired, - viewDate: React.PropTypes.object.isRequired, - selectedDate: React.PropTypes.object.isRequired, - showToday: React.PropTypes.bool, - viewMode: React.PropTypes.oneOfType([ - 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, - addYear: React.PropTypes.func.isRequired, - setViewMonth: React.PropTypes.func.isRequired, - setViewYear: React.PropTypes.func.isRequired, - subtractHour: React.PropTypes.func.isRequired, - addHour: React.PropTypes.func.isRequired, - subtractMinute: React.PropTypes.func.isRequired, - addMinute: React.PropTypes.func.isRequired, - addDecade: React.PropTypes.func.isRequired, - subtractDecade: React.PropTypes.func.isRequired, - togglePeriod: React.PropTypes.func.isRequired, - minDate: React.PropTypes.object, - maxDate: React.PropTypes.object - }, - renderDatePicker: function() { - if (this.props.showDatePicker) { - return ( -
  • - -
  • - ); - } - }, - renderTimePicker: function() { - if (this.props.showTimePicker) { - return ( -
  • - -
  • - ); - } - }, - renderSwitchButton: function() { - return this.props.mode === Constants.MODE_DATETIME ? - ( -
  • - -
  • - ) : - null; - }, - render: function() { - return ( -
    - -
      - - {this.renderDatePicker()} - - {this.renderSwitchButton()} - - {this.renderTimePicker()} - -
    - -
    - - ); - } -}); - -module.exports = DateTimePicker; diff --git a/src/DateTimePickerDate.jsx b/src/DateTimePickerDate.jsx deleted file mode 100644 index c5e5d0cf2..000000000 --- a/src/DateTimePickerDate.jsx +++ /dev/null @@ -1,143 +0,0 @@ -var DateTimePickerDate, DateTimePickerDays, DateTimePickerMonths, DateTimePickerYears, React; - -React = require('react'); - -DateTimePickerDays = require('./DateTimePickerDays'); - -DateTimePickerMonths = require('./DateTimePickerMonths'); - -DateTimePickerYears = require('./DateTimePickerYears'); - -DateTimePickerDate = React.createClass({ - propTypes: { - subtractMonth: React.PropTypes.func.isRequired, - addMonth: React.PropTypes.func.isRequired, - viewDate: React.PropTypes.object.isRequired, - selectedDate: React.PropTypes.object.isRequired, - showToday: React.PropTypes.bool, - viewMode: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.number - ]), - daysOfWeekDisabled: React.PropTypes.array, - setSelectedDate: React.PropTypes.func.isRequired, - subtractYear: React.PropTypes.func.isRequired, - addYear: React.PropTypes.func.isRequired, - setViewMonth: React.PropTypes.func.isRequired, - setViewYear: React.PropTypes.func.isRequired, - addDecade: React.PropTypes.func.isRequired, - subtractDecade: React.PropTypes.func.isRequired, - minDate: React.PropTypes.object, - maxDate: React.PropTypes.object - }, - getInitialState: function() { - var viewModes = { - 'days': { - daysDisplayed: true, - monthsDisplayed: false, - yearsDisplayed: false - }, - 'months': { - daysDisplayed: false, - monthsDisplayed: true, - yearsDisplayed: false - }, - 'years': { - daysDisplayed: false, - monthsDisplayed: false, - yearsDisplayed: true - } - }; - return viewModes[this.props.viewMode] || viewModes[Object.keys(viewModes)[this.props.viewMode]] || viewModes['days']; - }, - showMonths: function() { - return this.setState({ - daysDisplayed: false, - monthsDisplayed: true - }); - }, - showYears: function() { - return this.setState({ - monthsDisplayed: false, - yearsDisplayed: true - }); - }, - setViewYear: function(e) { - this.props.setViewYear(e.target.innerHTML); - return this.setState({ - yearsDisplayed: false, - monthsDisplayed: true - }); - }, - setViewMonth: function(e) { - this.props.setViewMonth(e.target.innerHTML); - return this.setState({ - monthsDisplayed: false, - daysDisplayed: true - }); - }, - renderDays: function() { - if (this.state.daysDisplayed) { - return ( - - ); - } else { - return null; - } - }, - renderMonths: function() { - if (this.state.monthsDisplayed) { - return ( - - ); - } else { - return null; - } - }, - renderYears: function() { - if (this.state.yearsDisplayed) { - return ( - - ); - } else { - return null; - } - }, - render: function() { - return ( -
    - {this.renderDays()} - - {this.renderMonths()} - - {this.renderYears()} -
    - ); - } -}); - -module.exports = DateTimePickerDate; diff --git a/src/DateTimePickerDays.jsx b/src/DateTimePickerDays.jsx index 61ebb109f..6216b48ec 100644 --- a/src/DateTimePickerDays.jsx +++ b/src/DateTimePickerDays.jsx @@ -1,6 +1,6 @@ var DateTimePickerDays, React, moment; -React = require('react/addons'); +React = require('react'); moment = require('moment'); @@ -35,40 +35,38 @@ DateTimePickerDays = React.createClass({ html = []; cells = []; while (prevMonth.isBefore(nextMonth)) { - classes = { - day: true - }; + classes = 'day'; if (prevMonth.year() < year || (prevMonth.year() === year && prevMonth.month() < month)) { - classes['old'] = true; + classes += " old"; } else if (prevMonth.year() > year || (prevMonth.year() === year && prevMonth.month() > month)) { - classes['new'] = true; + classes += " new"; } if (prevMonth.isSame(moment({ y: this.props.selectedDate.year(), M: this.props.selectedDate.month(), d: this.props.selectedDate.date() }))) { - classes['active'] = true; + classes += " active"; } if (this.props.showToday) { if (prevMonth.isSame(moment(), 'day')) { - classes['today'] = true; + classes += " today"; } } if ((minDate && prevMonth.isBefore(minDate)) || (maxDate && prevMonth.isAfter(maxDate))) { - classes['disabled'] = true; + classes += " disabled"; } if (this.props.daysOfWeekDisabled) { _ref = this.props.daysOfWeekDisabled; for (_i = 0, _len = _ref.length; _i < _len; _i++) { i = _ref[_i]; if (prevMonth.day() === this.props.daysOfWeekDisabled[i]) { - classes['disabled'] = true; + classes += " disabled"; break; } } } - cells.push({prevMonth.date()}); + cells.push({prevMonth.date()}); if (prevMonth.weekday() === moment().endOf('week').weekday()) { row = {cells}; html.push(row); @@ -79,16 +77,17 @@ DateTimePickerDays = React.createClass({ return html; }, render: function() { + var footer = this.renderFooter(); return (
    - + - + - + @@ -111,9 +110,24 @@ DateTimePickerDays = React.createClass({ {this.renderDays()} + + { this.renderFooter() } +
    {moment.months()[this.props.viewDate.month()]} {this.props.viewDate.year()}{moment.months()[this.props.viewDate.month()]} {this.props.viewDate.year()}
    ); + }, + renderFooter: function(){ + if( !this.props.timeFormat ) + return ''; + + return ( + + + ⌚ { this.props.selectedDate.format( this.props.timeFormat ) } + + + ) } }); diff --git a/src/DateTimePickerHours.jsx b/src/DateTimePickerHours.jsx deleted file mode 100644 index 42370d931..000000000 --- a/src/DateTimePickerHours.jsx +++ /dev/null @@ -1,95 +0,0 @@ -var DateTimePickerHours, React; - -React = require('react'); -var Glyphicon = require('react-bootstrap').Glyphicon; -var Constants = require('./Constants'); - -DateTimePickerHours = React.createClass({ - propTypes: { - setSelectedHour: React.PropTypes.func.isRequired, - onSwitch: React.PropTypes.func.isRequired - }, - renderSwitchButton: function() { - return this.props.mode === Constants.MODE_TIME ? - ( -
      -
    • - -
    • -
    - ) : - null; - }, - render: function() { - return ( -
    - {this.renderSwitchButton()} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    01020304
    05060708
    09101112
    13141516
    17181920
    21222324
    -
    - ); - } -}); - -module.exports = DateTimePickerHours; diff --git a/src/DateTimePickerMinutes.jsx b/src/DateTimePickerMinutes.jsx deleted file mode 100644 index da197ce7b..000000000 --- a/src/DateTimePickerMinutes.jsx +++ /dev/null @@ -1,65 +0,0 @@ -var DateTimePickerMinutes, React; - -React = require('react'); -var Glyphicon = require('react-bootstrap').Glyphicon; -var Constants = require('./Constants'); - -DateTimePickerMinutes = React.createClass({ - propTypes: { - setSelectedMinute: React.PropTypes.func.isRequired, - onSwitch: React.PropTypes.func.isRequired - }, - renderSwitchButton: function() { - return this.props.mode === Constants.MODE_TIME ? - ( -
      -
    • - -
    • -
    - ) : - null; - }, - render: function() { - return ( -
    - {this.renderSwitchButton()} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    00051015
    20253035
    40455055
    -
    - ); - } -}); - -module.exports = DateTimePickerMinutes; diff --git a/src/DateTimePickerMonths.jsx b/src/DateTimePickerMonths.jsx index 354bf16a4..77eba7334 100644 --- a/src/DateTimePickerMonths.jsx +++ b/src/DateTimePickerMonths.jsx @@ -1,6 +1,6 @@ var DateTimePickerMonths, React, moment; -React = require('react/addons'); +React = require('react'); moment = require('moment'); @@ -14,42 +14,48 @@ DateTimePickerMonths = React.createClass({ setViewMonth: React.PropTypes.func.isRequired }, renderMonths: function() { - var classes, i, month, months, monthsShort; + var classes, i, month, months, monthsShort, rows; month = this.props.selectedDate.month(); monthsShort = moment.monthsShort(); + rows = [], i = 0; months = []; while (i < 12) { - classes = { - month: true, - 'active': i === month && this.props.viewDate.year() === this.props.selectedDate.year() - }; - months.push({monthsShort[i]}); + if( i && i % 4 == 0 ){ + rows.push( { months } ); + months = []; + } + + classes = "month"; + if( i === month && this.props.viewDate.year() === this.props.selectedDate.year() ) + classes += " active"; + + months.push({monthsShort[i]}); i++; } - return months; + rows.push( { months } ); + return rows; }, render: function() { return ( -
    - - - - - - - - - - - - - - - - -
    {this.props.viewDate.year()}
    {this.renderMonths()}
    -
    +
    + + + + + + + + + + +
    {this.props.viewDate.year()}
    + + + {this.renderMonths()} + +
    +
    ); } }); diff --git a/src/DateTimePickerTime.jsx b/src/DateTimePickerTime.jsx index 88674e47a..24ef8f916 100644 --- a/src/DateTimePickerTime.jsx +++ b/src/DateTimePickerTime.jsx @@ -1,120 +1,174 @@ -var DateTimePickerHours, DateTimePickerMinutes, DateTimePickerTime, Glyphicon, React; +var DateTimePickerHours, React; React = require('react'); -DateTimePickerMinutes = require('./DateTimePickerMinutes'); - -DateTimePickerHours = require('./DateTimePickerHours'); - -var Glyphicon = require('react-bootstrap').Glyphicon; - var Constants = require('./Constants'); DateTimePickerTime = React.createClass({ - propTypes: { - setSelectedHour: React.PropTypes.func.isRequired, - setSelectedMinute: React.PropTypes.func.isRequired, - subtractHour: React.PropTypes.func.isRequired, - addHour: React.PropTypes.func.isRequired, - subtractMinute: React.PropTypes.func.isRequired, - addMinute: React.PropTypes.func.isRequired, - viewDate: React.PropTypes.object.isRequired, - selectedDate: React.PropTypes.object.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({ - minutesDisplayed: true - }); - }, - showHours: function() { - return this.setState({ - hoursDisplayed: true - }); - }, - renderMinutes: function() { - if (this.state.minutesDisplayed) { - return ; - } else { - return null; - } - }, - renderHours: function() { - if (this.state.hoursDisplayed) { - return ; - } else { - return null; - } - }, - renderPicker: function() { - if (!this.state.minutesDisplayed && !this.state.hoursDisplayed) { - return ( -
    - - - - + getInitialState: function(){ + var date = this.props.selectedDate, + format = this.props.timeFormat, + counters = [] + ; + + if( format.indexOf('H') != -1 || format.indexOf('h') != -1 ){ + counters.push('hours'); + if( format.indexOf('m') != -1 ){ + counters.push('minutes'); + if( format.indexOf('s') != -1 ){ + counters.push('seconds'); + } + } + } + + return { + hours: date.format('H'), + minutes: date.format('mm'), + seconds: date.format('ss'), + milliseconds: date.format('SSS'), + counters: counters + }; + }, + renderCounter: function( type ){ + return ( +
    +
    +
    { this.state[ type ] }
    +
    +
    + ) + }, + render: function() { + var me = this, + counters = [] + ; + + this.state.counters.forEach( function(c){ + if( counters.length ) + counters.push(
    :
    ); + counters.push( me.renderCounter( c ) ); + }); + if( this.state.counters.length == 3 && this.props.timeFormat.indexOf('S') != -1 ){ + counters.push(
    :
    ); + counters.push(
    ); + } + return ( +
    +
    +
    + { this.renderHeader() } + + + +
    { counters }
    +
    +
    + ); - + return ( +
    +
    + + { this.renderHeader() } + + + - + - - + - - + + - + + - + - + - - + + - - + + - + - + - - - -
    {this.props.selectedDate.format('h')}
    :
    {this.props.selectedDate.format('H')}{this.props.selectedDate.format('mm')}:{this.props.selectedDate.format('mm')}
    + + + + +
    - ); - } else { - return ''; - } + ); }, - render: function() { - return ( -
    - {this.renderPicker()} + renderHeader: function(){ + if( !this.props.dateFormat ) + return ''; - {this.renderHours()} - - {this.renderMinutes()} -
    - ); - } + return ( + { this.props.selectedDate.format( this.props.dateFormat ) } + ); + }, + onStartClicking: function( action, type ){ + var me = this, + update = {} + ; + return function(){ + var update = {}; + update[ type ] = me[ action ]( type ); + me.setState( update ); + + me.timer = setTimeout( function(){ + me.increaseTimer = setInterval( function(){ + update[ type ] = me[ action ]( type ); + me.setState( update ); + },80) + }, 500); + + document.body.addEventListener('mouseup', function(){ + clearTimeout( me.timer ); + clearInterval( me.increaseTimer ); + me.props.setTime( type, me.state[ type ] ); + }); + console.log( 'Start clicking'); + }; + }, + + maxValues: { + hours: 23, + minutes: 59, + seconds: 59, + milliseconds: 999 + }, + padValues: { + hours: 1, + minutes: 2, + minutes: 2, + milliseconds: 3 + }, + increase: function( type ){ + value = parseInt(this.state[ type ]) + 1; + if( value > this.maxValues[ type ] ) + value = 0; + return this.pad( type, value ); + }, + decrease: function( type ){ + value = parseInt(this.state[ type ]) - 1; + if( value < 0 ) + value = this.maxValues[ type ]; + return this.pad( type, value ); + }, + pad: function( type, value ){ + var str = value + ''; + while( str.length < this.padValues[ type ] ) + str = '0' + str; + return str; + } }); module.exports = DateTimePickerTime; diff --git a/src/DateTimePickerYears.jsx b/src/DateTimePickerYears.jsx index 54ce7e6ba..82c9dac1e 100644 --- a/src/DateTimePickerYears.jsx +++ b/src/DateTimePickerYears.jsx @@ -1,6 +1,6 @@ var DateTimePickerYears, React; -React = require('react/addons'); +React = require('react'); DateTimePickerYears = React.createClass({ propTypes: { @@ -11,22 +11,29 @@ DateTimePickerYears = React.createClass({ setViewYear: React.PropTypes.func.isRequired }, renderYears: function() { - var classes, i, year, years; + var classes, i, year, years, rows; years = []; year = parseInt(this.props.viewDate.year() / 10, 10) * 10; year--; i = -1; + rows = []; while (i < 11) { - classes = { - year: true, - old: i === -1 | i === 10, - active: this.props.selectedDate.year() === year - }; - years.push({year}); + if( (i+1) && (i+1) % 4 == 0 ){ + rows.push( { years } ); + years = []; + } + classes = 'year'; + if( i === -1 | i === 10 ) + classes += ' old'; + if( this.props.selectedDate.year() === year ) + classes += ' active'; + + years.push({year}); year++; i++; } - return years; + rows.push( { years } ); + return rows; }, render: function() { var year; @@ -36,18 +43,15 @@ DateTimePickerYears = React.createClass({ - - + - - + - +
    {year} - {year+9}
    + - - - + {this.renderYears()}
    {this.renderYears()}
    diff --git a/webpack.config.js b/webpack.config.js index f9ef5cf05..3e48f67d0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,7 @@ var webpack = require('webpack'); var plugins = [ new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) + 'process.env': { NODE_ENV: '"production"'} }) ]; @@ -22,7 +22,7 @@ module.exports = { output: { path: __dirname + "/dist/", - library: 'ReactBootstrapDatetimepicker', + library: 'Datetime', libraryTarget: 'umd', }, @@ -32,8 +32,6 @@ module.exports = { externals: { 'react': 'React', - 'react/addons': 'React', - 'react-bootstrap': 'ReactBootstrap', 'moment': 'moment' },