import React from "react"; import PropTypes from "prop-types"; export default class DateRangeSelect extends React.Component { constructor(props) { super(props); this.state = { startsAt: this.parseDate(props.startsAt) || this.defaultDate(), endsAt: this.parseDate(props.endsAt) || this.defaultDate(60), startTime: "", endTime: "" }; this.state.startTime = this.timeToString(this.state.startsAt); this.state.endTime = this.timeToString(this.state.endsAt); this.changeStartsAt = this.changeStartsAt.bind(this); this.changeEndsAt = this.changeEndsAt.bind(this); } changeStartsAt(options = {}) { let newDate = this.modifyDate(this.state.startsAt, options); this.setDates( newDate, new Date(this.state.endsAt.getTime() + (newDate - this.state.startsAt)) ); } changeEndsAt(options = {}) { let newDate = this.modifyDate(this.state.endsAt, options); this.setDates(this.state.startsAt, newDate); } defaultDate(offset = 0) { let coeff = 1000 * 60 * 60; return new Date( (Math.round((new Date()).getTime() / coeff) * coeff) + coeff + (1000 * 60 * offset) ); } modifyDate(original, options = {}) { var newDate = new Date(original); if (Object.prototype.hasOwnProperty.call(options, "year")) { newDate.setFullYear(options.year); } if (Object.prototype.hasOwnProperty.call(options, "month")) { newDate.setMonth(options.month); } if (Object.prototype.hasOwnProperty.call(options, "date")) { newDate.setDate(options.date); } if (Object.prototype.hasOwnProperty.call(options, "time") && options.time.match(/^[\d]{1,2}(:[\d]{1,2})?$/)) { newDate.setHours(options.time.split(":")[0]); newDate.setMinutes(options.time.split(":")[1] || 0); } return newDate; } parseDate(str) { if (!str) { return; } return new Date(str); } setDates(start, end) { if (end < start) { end = start; } this.setState({ startsAt: start, endsAt: end, startTime: this.timeToString(start), endTime: this.timeToString(end) }); } startsAtToString() { if (this.props.disabled) { return ""; } return this.state.startsAt.toJSON(); } endsAtToString() { if (this.props.disabled) { return ""; } return this.state.endsAt.toJSON(); } renderDateSelect(key, date, handleChange) { return (
); } render() { return (
{this.renderDateSelect("starts-at", this.state.startsAt, this.changeStartsAt)} {!this.props.disableTime && ( this.setState({ startTime: e.target.value })} onBlur={e => this.changeStartsAt({ time: e.target.value })} /> )}
to
{this.renderDateSelect("ends-at", this.state.endsAt, this.changeEndsAt)} {!this.props.disableTime && ( this.setState({ endTime: e.target.value })} onBlur={e => this.changeEndsAt({ time: e.target.value })} /> )}
); } timeToString(time) { return time.toTimeString().slice(0, 5); } // Returns an array with years from 2000 to 10 years from now. yearOptions() { let start = 2000; return Array.apply(null, Array((new Date()).getFullYear() - start + 11)) .map((_, i) => i + start); } monthOptions() { return(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]); } dayOptions() { return Array.apply(null, Array(31)).map((_, i) => i + 1); } } DateRangeSelect.propTypes = { startsAt: PropTypes.string, endsAt: PropTypes.string, disabled: PropTypes.bool, disableTime: PropTypes.bool, objectName: PropTypes.string };