@nateradebaugh/react-datetime
Version:
A lightweight but complete datetime picker React.js component
140 lines (115 loc) • 3.76 kB
JavaScript
import React, { Component } from "react";
import format from "date-fns/format";
import getMonth from "date-fns/get_month";
import setMonth from "date-fns/set_month";
import getYear from "date-fns/get_year";
import getDaysInMonth from "date-fns/get_days_in_month";
import setDate from "date-fns/set_date";
import onClickOutside from "react-onclickoutside";
class MonthsView extends Component {
constructor(props) {
super(props);
// Bind functions
this.renderMonths = this.renderMonths.bind(this);
this.updateSelectedMonth = this.updateSelectedMonth.bind(this);
this.renderMonth = this.renderMonth.bind(this);
this.alwaysValidDate = this.alwaysValidDate.bind(this);
this.getFormatOptions = this.getFormatOptions.bind(this);
}
getFormatOptions() {
return { locale: this.props.locale };
}
render() {
const date = this.props.viewDate || new Date();
return (
<div className="rdtMonths">
<table>
<thead>
<tr>
<th
className="rdtPrev"
onClick={this.props.subtractTime(1, "years")}
>
<span>‹</span>
</th>
<th
className="rdtSwitch"
onClick={this.props.showView("years")}
colSpan={2}
data-value={getYear(this.props.viewDate)}
>
{format(date, "YYYY", this.getFormatOptions())}
</th>
<th className="rdtNext" onClick={this.props.addTime(1, "years")}>
<span>›</span>
</th>
</tr>
</thead>
</table>
<table>
<tbody>{this.renderMonths()}</tbody>
</table>
</div>
);
}
renderMonths() {
const date = this.props.selectedDate;
const year = getYear(this.props.viewDate);
const renderer = this.props.renderMonth || this.renderMonth;
const isValid = this.props.isValidDate || this.alwaysValidDate;
const rows = [];
let months = [];
for (let i = 0; i < 12; i++) {
let classes = "rdtMonth";
const currentMonth = setMonth(this.props.viewDate, i);
const noOfDaysInMonth = getDaysInMonth(currentMonth);
const daysInMonth = Array.from({ length: noOfDaysInMonth }, (e, i) => {
return i + 1;
});
const validDay = daysInMonth.find(d => {
const day = setDate(currentMonth, d);
return isValid(day);
});
const isDisabled = validDay === undefined;
if (isDisabled) {
classes += " rdtDisabled";
}
if (date && i === getMonth(date) && year === getYear(date)) {
classes += " rdtActive";
}
const props = {
key: i,
"data-value": i,
className: classes
};
if (!isDisabled) {
props.onClick =
this.props.updateOn === "months"
? this.updateSelectedMonth
: this.props.setDate("month");
}
months.push(renderer(props, i, year, date));
if (months.length === 4) {
rows.push(<tr key={i}>{months}</tr>);
months = [];
}
}
return rows;
}
updateSelectedMonth(event) {
this.props.updateSelectedDate(event);
}
renderMonth(props, month, year, selected) {
const monthDate = setMonth(new Date(), month);
return (
<td {...props}>{format(monthDate, "MMM", this.getFormatOptions())}</td>
);
}
alwaysValidDate() {
return 1;
}
handleClickOutside() {
this.props.handleClickOutside();
}
}
export default onClickOutside(MonthsView);