Skip to content

Instantly share code, notes, and snippets.

@max107
Last active August 29, 2015 14:20
Show Gist options
  • Save max107/4b5b9da2912f4e467823 to your computer and use it in GitHub Desktop.
Save max107/4b5b9da2912f4e467823 to your computer and use it in GitHub Desktop.
React calendar
var Calendar = React.createClass({
getDefaultProps: function() {
return {
prev_text: "Prev",
next_text: "Next",
month_format: "MMMM, YYYY",
month: undefined,
count: 2,
reserved: [],
onSelect: function(date) {
}
};
},
getInitialState: function() {
return {
selected: undefined,
month: this.month ? this.month.clone() : moment()
};
},
handlePrevious: function() {
var month = this.state.month;
month.add(-1, "M");
this.setState({
month: month
});
},
handleNext: function() {
var month = this.state.month;
month.add(1, "M");
this.setState({
month: month
});
},
handleSelect: function(day) {
this.setState({
selected: day.date
});
this.forceUpdate();
this.props.onSelect(day.date);
},
renderMonth: function(month) {
month = month || this.state.month;
return (
<div key={'c' + month.toString()} className="calendar">
<div className="calendar-title">
{this.renderMonthLabel(month)}
</div>
<DayNames />
{this.renderWeeks(month)}
</div>
);
},
render: function() {
var count = Array.apply(null, Array(this.props.count)).map(function (_, i) {
return i;
});;
var calendarNodes = count.map(function(i) {
var month = this.state.month.clone();
month.add(i, "M");
return this.renderMonth(month);
}.bind(this));
return (
<div>
<div className="calendar-header">
<a href="javascript:;" className="calendar-header-next-month" onClick={this.handleNext}>{this.props.next_text}</a>
<a href="javascript:;" className="calendar-header-prev-month" onClick={this.handlePrevious}>{this.props.prev_text}</a>
</div>
{calendarNodes}
</div>
);
},
renderWeeks: function(month) {
month = month || this.state.month;
var weeks = [],
done = false,
date = month.clone().startOf("month").add("w" -1).day("Sunday"),
monthIndex = date.month(),
count = 0;
while (!done) {
weeks.push(
<Week
key={date.toString()}
date={date.clone()}
month={month.clone()}
select={this.handleSelect}
reserved={this.props.reserved}
selected={this.state.selected} />
);
date.add(1, "w");
done = count++ > 2 && monthIndex !== date.month();
monthIndex = date.month();
}
return weeks;
},
renderMonthLabel: function(month) {
month = month || this.state.month;
return <span>{month.format(this.props.month_format)}</span>;
}
});
var DayNames = React.createClass({
render: function() {
return (
<ul className="calendar-week-names">
<li className="calendar-day"><span>Вс</span></li>
<li className="calendar-day"><span>Пн</span></li>
<li className="calendar-day"><span>Вт</span></li>
<li className="calendar-day"><span>Ср</span></li>
<li className="calendar-day"><span>Чт</span></li>
<li className="calendar-day"><span>Пт</span></li>
<li className="calendar-day"><span>Сб</span></li>
</ul>
);
}
});
var Week = React.createClass({
getDefaultProps: function() {
return {
reserved: [],
date: undefined,
month: undefined,
selected: undefined
};
},
render: function() {
var days = [],
date = this.props.date,
month = this.props.month;
for (var i = 0; i < 7; i++) {
var day = {
name: date.format("dd").substring(0, 1),
number: date.date(),
isCurrentMonth: date.month() === month.month(),
isToday: date.isSame(new Date(), "day"),
date: date
};
var reserved = false;
for (var t = 0; t <= this.props.reserved.length; t++) {
if (day.date.isSame(this.props.reserved[t])) {
reserved = true;
break;
}
}
days.push(
<li key={day.date.toString()}
className={
"calendar-day" +
(day.isToday ? " today" : "") +
(day.isCurrentMonth ? "" : " different-month") +
(reserved ? " reserved" : "") +
(day.date.isSame(this.props.selected) ? " selected" : "")
}
onClick={this.props.select.bind(null, day)}>
<span>
{day.number}
</span>
</li>
);
date = date.clone();
date.add(1, "d");
}
return (
<ul className="calendar-week" key={days[0].toString()}>
{days}
</ul>
);
}
});
@max107
Copy link
Author

max107 commented May 4, 2015

screenshot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment