react-components-calendar
Version:
Calendar component for ReactJS
220 lines (191 loc) • 5.76 kB
JavaScript
/**
* Created by simba on 09/11/2017.
*/
import React from 'react';
import s from './index.scss'
class Calendar extends React.Component {
constructor() {
super();
this.state = {
today: '',
chooseDate: '',
cur_year: '',
cur_month: '',
weeks_ch: [],
hasEmptyGrid: false,
empytGrids: [],
days: []
};
this.formatTime = this.formatTime.bind(this);
this.formatNumber = this.formatNumber.bind(this);
this.iniCalendar = this.iniCalendar.bind(this);
this.calculateEmptyGrids = this.calculateEmptyGrids.bind(this);
this.calculateDays = this.calculateDays.bind(this);
this.getThisMonthDays = this.getThisMonthDays.bind(this);
this.getFirstDayOfWeek = this.getFirstDayOfWeek.bind(this);
this.calculateEmptyGrids = this.calculateEmptyGrids.bind(this);
this.calculateDays = this.calculateDays.bind(this);
this.handleCalendar = this.handleCalendar.bind(this);
this.chooseDate = this.chooseDate.bind(this);
this.handleMonth = this.handleMonth.bind(this);
}
componentDidMount(){
this.iniCalendar();
}
componentWillReceiveProps(nextProps){
}
//格式化时间
formatTime(date) {
let year = date.getFullYear();
let month = date.getMonth() + 1;
let day = date.getDate();
return [year, month, day].map(this.formatNumber).join('-');
}
formatNumber(n) {
n = n.toString();
return n[1] ? n : '0' + n
}
// 初始化日历
iniCalendar(){
let that = this;
const date = new Date();
const cur_year = date.getFullYear();
const cur_month = date.getMonth() + 1;
const weeks_ch = ['日', '一', '二', '三', '四', '五', '六'];
const today = this.formatTime(date);
that.calculateEmptyGrids(cur_year, cur_month);
that.calculateDays(cur_year, cur_month);
that.handleMonth(`${cur_year}-${this.formatNumber(cur_month)}-01`);
that.setState({
today: today,
chooseDate: today,
cur_year: cur_year,
cur_month: cur_month,
weeks_ch: weeks_ch
})
}
// 获取当月共多少天
getThisMonthDays(year, month) {
return new Date(year, month, 0).getDate();
}
// 获取当月第一天星期几
getFirstDayOfWeek(year, month) {
return new Date(Date.UTC(year, month - 1, 1)).getDay();
}
// 计算当月1号前空了几个格子
calculateEmptyGrids(year, month) {
const firstDayOfWeek = this.getFirstDayOfWeek(year, month);
let empytGrids = [];
if (firstDayOfWeek > 0) {
for (let i = 0; i < firstDayOfWeek; i++) {
empytGrids.push(i);
}
this.setState({
hasEmptyGrid: true,
empytGrids: empytGrids
});
} else {
this.setState({
hasEmptyGrid: false,
empytGrids: []
});
}
}
// 绘制当月天数占的格子
calculateDays(year, month) {
let days = [];
let day ={};
const thisMonthDays = this.getThisMonthDays(year, month);
for (let i = 1; i <= thisMonthDays; i++) {
day = {
dayNumber:i,
dayDate:`${year}-${this.formatNumber(month)}-${this.formatNumber(i)}`
}
days.push(day);
}
this.setState({
days:days
});
}
// 切换控制年月
handleCalendar(e) {
const handle = e.currentTarget.dataset.handle;
const cur_year = this.state.cur_year;
const cur_month = this.state.cur_month;
let newMonth,newYear;
if (handle === 'prev') {
newMonth = cur_month - 1;
newYear = cur_year;
if (newMonth < 1) {
newYear = cur_year - 1;
newMonth = 12;
}
} else {
newMonth = cur_month + 1;
newYear = cur_year;
if (newMonth > 12) {
newYear = cur_year + 1;
newMonth = 1;
}
}
this.calculateDays(newYear, newMonth);
this.calculateEmptyGrids(newYear, newMonth);
this.handleMonth(`${newYear}-${this.formatNumber(newMonth)}-01`);
this.setState({
cur_year: newYear,
cur_month: newMonth
})
}
//选择日期
chooseDate(date){
this.props.chooseDate && this.props.chooseDate(date);
this.setState({
chooseDate: date
})
}
//切换月份
handleMonth(month){
this.props.handleMonth && this.props.handleMonth(month)
}
render() {
let weeks = this.state.weeks_ch.map((u,i) => {
return(
<div key={i} className={s.week} data-idx={i}>
{u}
</div>
)
});
let emptyDays = this.state.empytGrids.map((u,i) => {
return(
<div key={i} className={s.dayBox} data-idx={i}></div>
)
});
let days = this.state.days.map((u,i) => {
let hasRecords = this.props.MonthRecords && this.props.MonthRecords.includes(u.dayDate);
return(
<div key={i} className={s.dayBox} data-idx={i} onClick={()=>this.chooseDate(u.dayDate)}>
<div className={`${s.day} ${u.dayDate == this.state.chooseDate ? s.today : ''} ${hasRecords ? s.hasRecords : ''}`} data-day={u.dayDate}>{u.dayNumber}</div>
</div>
)
})
return (
<div className={s.calendarBox}>
<div className={s.handleBox}>
<div className={s.handleBtn} onClick={this.handleCalendar} data-handle="prev"><</div>
<div className={s.curDate}>{this.state.cur_year || "--"} 年 {this.state.cur_month || "--"} 月</div>
<div className={s.handleBtn} onClick={this.handleCalendar} data-handle="next">></div>
</div>
<div className={s.weeksBox}>
{weeks}
</div>
<div className={s.daysBox}>
{
this.state.hasEmptyGrid ? emptyDays : ''
}
{days}
</div>
</div>
);
}
}
export default Calendar;