UNPKG

@ustack/uskin

Version:

A graceful framework which provides developers another chance to build an amazing site.

171 lines (143 loc) 4.09 kB
import React from 'react'; import helper from './helper'; import Constants from './constants'; const {WEEKS_LOCAL, WEEKS_COUNT, TABLE_LINE} = Constants; class DatePicker extends React.Component { constructor(props) { super(props); ['onClick'].forEach((func) => { this[func] = this[func].bind(this); }); } onClick(e) { let target = e.target; let monthOffset = parseInt(target.getAttribute('data-month'), 10); if (target.tagName === 'TD' && monthOffset === 0 && target.className === 'default') { let date = parseInt(target.getAttribute('data-date'), 10); let page = this.props.page; let newDate = new Date(page.year, page.month + monthOffset, date); this.onSelected(helper.formatDate(newDate)); } } onSelected(date) { let func = this.props.onSelected; func && func(date); } getWeeks(props) { let startDay = props.startWeek; let LOCAL = props.local && props.local.weeks ? props.local.weeks : WEEKS_LOCAL; let weeks = []; for (let i = 0; i < WEEKS_COUNT; i++) { let day = (startDay + i + WEEKS_COUNT) % WEEKS_COUNT; weeks.push(LOCAL[day]); } return weeks; } getDates(props) { let startDay = props.startWeek; let y = props.page.year; let m = props.page.month; let prevLastDate = new Date(y, m, 0).getDate(); let lastDate = new Date(y, m + 1, 0).getDate(); let firstDay = new Date(y, m, 1).getDay(); let dates = []; let line = 0; let offset = (firstDay - startDay + WEEKS_COUNT) % WEEKS_COUNT; if (startDay !== firstDay) { dates[line] = []; let i = 0; for (i = 0; i < offset; i++) { dates[line][i] = { monthOffset: -1, date: prevLastDate + i - offset + 1 }; } for (; i < WEEKS_COUNT; i++) { dates[line][i] = { monthOffset: 0, date: i - offset + 1 }; } line++; } let count = (WEEKS_COUNT - offset) % WEEKS_COUNT + 1; let countOverflow = 1; for (let i = line; i < TABLE_LINE; i++) { dates[i] = []; for (let j = 0; j < WEEKS_COUNT; j++, count++) { if (count <= lastDate) { dates[i][j] = { monthOffset: 0, date: count }; } else { dates[i][j] = { monthOffset: 1, date: countOverflow }; countOverflow++; } } } return dates; } isSelectable(disabled, date) { return this.props.isSelectable(disabled, date); } getClassName(props, ele) { if (ele.monthOffset === 0) { let date = { year: props.page.year, month: props.page.month, date: ele.date, monthOffset: ele.monthOffset }; if (props.disabled && !this.isSelectable(props.disabled, date)) { return 'not-selected'; } if (ele.monthOffset === 0 && props.selected.date && helper.compareDate(props.selected, date) === 0) { return 'selected'; } return 'default'; } else { return 'disabled'; } } render() { const props = this.props; let weeks = this.getWeeks(props); let dates = this.getDates(props); return ( <div className="calendar-datepicker"> <table> <thead> <tr> {weeks.map((ele) => <th key={ele}>{ele}</th>)} </tr> </thead> <tbody onClick={this.onClick}> { dates.map((line, index) => <tr key={index}> { line.map((ele, i) => <td key={ele.date} data-month={ele.monthOffset} data-date={ele.date} className={this.getClassName(props, ele)}> {ele.date} </td> ) } </tr> ) } </tbody> </table> </div> ); } } export default DatePicker;