|
|
'use strict';
|
|
|
|
|
|
import React from 'react-native';
|
|
|
const {
|
|
|
Component,
|
|
|
View,
|
|
|
Text,
|
|
|
TouchableOpacity,
|
|
|
StyleSheet,
|
|
|
Dimensions,
|
|
|
} = React;
|
|
|
|
|
|
import Month from './Month';
|
|
|
import Year from './Year';
|
|
|
|
|
|
console.disableYellowBox = true;
|
|
|
|
|
|
let width = Dimensions.get('window').width - 20;
|
|
|
|
|
|
export default class Calendar extends Component {
|
|
|
static defaultProps = {
|
|
|
onCancel: () => {
|
|
|
|
|
|
},
|
|
|
|
|
|
onOK: () => {
|
|
|
|
|
|
},
|
|
|
|
|
|
monthsLocale: ['1月', '2月', '3月', '4月', '5月', '6月',
|
|
|
'7月', '8月', '9月', '10月', '11月', '12月'],
|
|
|
weekDaysLocale: [ '日', '一', '二', '三', '四', '五', '六'],
|
|
|
|
|
|
width: width,
|
|
|
|
|
|
selectMode: 'week',
|
|
|
|
|
|
bodyBackColor: 'white',
|
|
|
bodyTextColor: 'black',
|
|
|
headerSepColor: 'grey',
|
|
|
|
|
|
dayCommonBackColor: 'white',
|
|
|
dayCommonTextColor: '#444444',
|
|
|
|
|
|
dayDisabledBackColor: 'white',
|
|
|
dayDisabledTextColor: '#B0B0B0',
|
|
|
|
|
|
daySelectedBackColor: '#FD9D2B',
|
|
|
daySelectedTextColor: '#444444',
|
|
|
|
|
|
dayInRangeBackColor: '#FD9D2B',
|
|
|
dayInRangeTextColor: '#444444'
|
|
|
};
|
|
|
|
|
|
static propTypes = {
|
|
|
selectFrom: React.PropTypes.instanceOf(Date),
|
|
|
selectTo: React.PropTypes.instanceOf(Date),
|
|
|
|
|
|
monthsCount: React.PropTypes.number,
|
|
|
|
|
|
monthsLocale: React.PropTypes.arrayOf(React.PropTypes.string),
|
|
|
weekDaysLocale: React.PropTypes.arrayOf(React.PropTypes.string),
|
|
|
startFromMonday: React.PropTypes.bool,
|
|
|
|
|
|
onCancel: React.PropTypes.func,
|
|
|
onOK: React.PropTypes.func,
|
|
|
|
|
|
width: React.PropTypes.number,
|
|
|
|
|
|
selectMode: React.PropTypes.oneOf(['day', 'week', 'month']),
|
|
|
|
|
|
bodyBackColor: React.PropTypes.string,
|
|
|
bodyTextColor: React.PropTypes.string,
|
|
|
headerSepColor: React.PropTypes.string,
|
|
|
|
|
|
dayCommonBackColor: React.PropTypes.string,
|
|
|
dayCommonTextColor: React.PropTypes.string,
|
|
|
|
|
|
dayDisabledBackColor: React.PropTypes.string,
|
|
|
dayDisabledTextColor: React.PropTypes.string,
|
|
|
|
|
|
daySelectedBackColor: React.PropTypes.string,
|
|
|
daySelectedTextColor: React.PropTypes.string,
|
|
|
|
|
|
dayInRangeBackColor: React.PropTypes.string,
|
|
|
dayInRangeTextColor: React.PropTypes.string
|
|
|
};
|
|
|
|
|
|
constructor(props) {
|
|
|
super(props);
|
|
|
|
|
|
this.changeSelection = this.changeSelection.bind(this);
|
|
|
this.generateMonth = this.generateMonth.bind(this);
|
|
|
this.prevMonth = this.prevMonth.bind(this);
|
|
|
this.nextMonth = this.nextMonth.bind(this);
|
|
|
|
|
|
let {selectMode, selectFrom, selectTo, monthsCount} = this.props;
|
|
|
|
|
|
this.selected = {
|
|
|
selectMode: selectMode,
|
|
|
from: null,
|
|
|
to: null,
|
|
|
day: null,
|
|
|
week: 0,
|
|
|
month: 0,
|
|
|
year: 0,
|
|
|
};
|
|
|
|
|
|
this.selectMode = selectMode;
|
|
|
this.month = this.generateMonth(new Date());
|
|
|
this.weeksInMonth = this.generateWeeks(new Date());
|
|
|
this.monthsInYear = this.generateMonthsInYear(new Date());
|
|
|
this.currentYear = new Date().getFullYear();
|
|
|
|
|
|
this.state = {
|
|
|
selectMode: this.selectMode,
|
|
|
month: this.month,
|
|
|
weeksInMonth: this.weeksInMonth,
|
|
|
monthsInYear: this.monthsInYear,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
|
this.selectMode = nextProps.selectMode;
|
|
|
this.month = this.generateMonth(this.state.month[15].date);
|
|
|
this.weeksInMonth = this.generateWeeks(this.state.month[15].date);
|
|
|
this.monthsInYear = this.generateMonthsInYear(this.state.month[15].date);
|
|
|
this.setState({
|
|
|
selectMode: this.selectMode,
|
|
|
month: this.month,
|
|
|
weeksInMonth: this.weeksInMonth,
|
|
|
monthsInYear: this.monthsInYear,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
generateMonth(currentDate) {
|
|
|
let month = this.getDates(currentDate, this.props.startFromMonday);
|
|
|
|
|
|
month = month.map((day, i) => {
|
|
|
return {
|
|
|
date: day,
|
|
|
status: 'common',
|
|
|
disabled: day.getMonth() !== currentDate.getMonth() || day > Date.now(),
|
|
|
belongWeek: Math.floor(i / 7) + 1,
|
|
|
first: false,
|
|
|
last: false,
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return month;
|
|
|
}
|
|
|
|
|
|
getDates(month, startFromMonday) {
|
|
|
month = new Date(month);
|
|
|
month.setDate(1);
|
|
|
|
|
|
var delta = month.getDay();
|
|
|
if (startFromMonday) {
|
|
|
delta--;
|
|
|
if (delta === -1) delta = 6;
|
|
|
}
|
|
|
|
|
|
var startDate = new Date(month);
|
|
|
startDate.setDate(startDate.getDate() - delta);
|
|
|
|
|
|
month.setMonth(month.getMonth() + 1);
|
|
|
month.setDate(0);
|
|
|
|
|
|
delta = 6 - month.getDay();
|
|
|
if (startFromMonday) {
|
|
|
delta++;
|
|
|
if (delta === 7) delta = 0;
|
|
|
}
|
|
|
|
|
|
var lastDate = new Date(month);
|
|
|
lastDate.setDate(lastDate.getDate() + delta);
|
|
|
|
|
|
var allDates = [];
|
|
|
while (startDate <= lastDate) {
|
|
|
allDates.push(new Date(startDate));
|
|
|
startDate.setDate(startDate.getDate() + 1);
|
|
|
}
|
|
|
return allDates;
|
|
|
}
|
|
|
|
|
|
generateWeeks(date) {
|
|
|
|
|
|
let weeksNum = Math.ceil(this.month.length / 7); //月份的周数
|
|
|
|
|
|
let monthWeeks = [];
|
|
|
for (let i = 0; i < weeksNum; i++) {
|
|
|
monthWeeks[i] = i + 1;
|
|
|
}
|
|
|
|
|
|
monthWeeks = monthWeeks.map((week) => {
|
|
|
let disabled = this.selectMode === 'week' ? false : true;
|
|
|
return {
|
|
|
week: week,
|
|
|
status: 'common',
|
|
|
disabled: disabled,
|
|
|
first: false,
|
|
|
last: false,
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return monthWeeks;
|
|
|
}
|
|
|
|
|
|
generateMonthsInYear(date) {
|
|
|
let monthsInYear = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
|
|
|
monthsInYear = monthsInYear.map((month) => {
|
|
|
let disabled = false;
|
|
|
// let earlierYear = date.getFullYear() > new Date().getFullYear();
|
|
|
//
|
|
|
// if (earlierYear) {
|
|
|
// let earlierMonth = date.getMonth() > new Date().getMonth();
|
|
|
// disabled = earlierMonth ? true : false;
|
|
|
// } else {
|
|
|
// disabled = false;
|
|
|
// }
|
|
|
return {
|
|
|
month: month,
|
|
|
status: 'common',
|
|
|
disabled: disabled,
|
|
|
}
|
|
|
});
|
|
|
|
|
|
return monthsInYear;
|
|
|
}
|
|
|
|
|
|
changeSelection(value) {
|
|
|
this.selected.selectMode = this.state.selectMode;
|
|
|
|
|
|
if (this.state.selectMode === 'week') {
|
|
|
this.selectWeek(value);
|
|
|
}
|
|
|
|
|
|
if (this.state.selectMode === 'day') {
|
|
|
this.selectDay(value);
|
|
|
}
|
|
|
|
|
|
if (this.state.selectMode === 'month') {
|
|
|
this.selectMonth(value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
selectDay(value) {
|
|
|
let {date} = value;
|
|
|
let {month} = this;
|
|
|
month = month.map((item) => {
|
|
|
let status = item.date.toDateString() === date.toDateString() ? 'selected' : 'common';
|
|
|
let first = item.date.toDateString() === date.toDateString() ? true : false;
|
|
|
let last = item.date.toDateString() === date.toDateString() ? true : false;
|
|
|
return {
|
|
|
date: item.date,
|
|
|
status: status,
|
|
|
disabled: item.disabled,
|
|
|
belongWeek: item.belongWeek,
|
|
|
first,
|
|
|
last,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
this.selected.day = date;
|
|
|
|
|
|
this.month = month;
|
|
|
|
|
|
this.setState({
|
|
|
month: this.month,
|
|
|
weeksInMonth: this.weeksInMonth,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
selectWeek(value) {
|
|
|
let {belongWeek} = value;
|
|
|
let {month, weeksInMonth} = this;
|
|
|
|
|
|
weeksInMonth = weeksInMonth.map((item) => {
|
|
|
let status = item.week === belongWeek ? 'selected' : 'common';
|
|
|
let first = item.week === belongWeek ? true : false;
|
|
|
return {
|
|
|
week: item.week,
|
|
|
status: status,
|
|
|
disabled: item.disabled,
|
|
|
first: first,
|
|
|
last: false,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
let currentWeekDays = month.filter((day) => {
|
|
|
return day.belongWeek === belongWeek;
|
|
|
});
|
|
|
|
|
|
let firstDay = currentWeekDays[0];
|
|
|
let lastDay = currentWeekDays[currentWeekDays.length - 1];
|
|
|
|
|
|
month = month.map((day) => {
|
|
|
let status = day.belongWeek === belongWeek ? 'selected' : 'common';
|
|
|
// let first = day.date.toDateString() === firstDay.date.toDateString() ? true : false;
|
|
|
let last = day.date.toDateString() === lastDay.date.toDateString() ? true : false;
|
|
|
return {
|
|
|
date: day.date,
|
|
|
status: status,
|
|
|
disabled: day.disabled,
|
|
|
belongWeek: day.belongWeek,
|
|
|
first: false,
|
|
|
last,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
this.selected.week = belongWeek;
|
|
|
this.selected.from = firstDay.date;
|
|
|
this.selected.to = lastDay.date
|
|
|
|
|
|
this.month = month;
|
|
|
this.weeksInMonth = weeksInMonth;
|
|
|
|
|
|
this.setState({
|
|
|
month: this.month,
|
|
|
weeksInMonth: this.weeksInMonth,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
selectMonth(value) {
|
|
|
let {month} = value;
|
|
|
let {monthsInYear} = this;
|
|
|
monthsInYear = monthsInYear.map((item) => {
|
|
|
let status = item.month == month ? 'selected' : 'common';
|
|
|
return {
|
|
|
month: item.month,
|
|
|
status: status,
|
|
|
disabled: item.disabled,
|
|
|
};
|
|
|
});
|
|
|
|
|
|
this.selected.month = month;
|
|
|
this.selected.year = this.currentYear;
|
|
|
|
|
|
this.monthsInYear = monthsInYear;
|
|
|
this.setState({
|
|
|
monthsInYear: this.monthsInYear,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
prevMonth() {
|
|
|
if (this.state.selectMode === 'month') {
|
|
|
this.currentYear -= 1;
|
|
|
this.updateMonthInYear(new Date(this.currentYear, 5, 1));
|
|
|
|
|
|
} else {
|
|
|
let middleDay = this.state.month[15].date;
|
|
|
let currentMonth = middleDay.getMonth();
|
|
|
let prevMonthDate = new Date(middleDay.setMonth(currentMonth - 1));
|
|
|
|
|
|
this.updateWeekAndMonth(prevMonthDate);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
nextMonth() {
|
|
|
if (this.state.selectMode === 'month') {
|
|
|
this.currentYear += 1;
|
|
|
this.updateMonthInYear(new Date(this.currentYear, 5, 1));
|
|
|
|
|
|
} else {
|
|
|
let middleDay = this.state.month[15].date;
|
|
|
let currentMonth = middleDay.getMonth();
|
|
|
let nextMonthDate = new Date(middleDay.setMonth(currentMonth + 1));
|
|
|
|
|
|
this.updateWeekAndMonth(nextMonthDate);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
updateMonthInYear(date) {
|
|
|
this.monthsInYear = this.generateMonthsInYear(date);
|
|
|
this.setState({
|
|
|
monthsInYear: this.monthsInYear,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
updateWeekAndMonth(date) {
|
|
|
this.month = this.generateMonth(date);
|
|
|
this.weeksInMonth = this.generateWeeks(date);
|
|
|
this.setState({
|
|
|
month: this.month,
|
|
|
weeksInMonth: this.weeksInMonth,
|
|
|
});
|
|
|
}
|
|
|
|
|
|
renderContent() {
|
|
|
return (
|
|
|
<Month
|
|
|
{...this.props}
|
|
|
days={this.state.month}
|
|
|
style={styles.month}
|
|
|
changeSelection={this.changeSelection}
|
|
|
weeks={this.state.weeksInMonth}
|
|
|
months={this.state.monthsInYear}
|
|
|
year={this.currentYear}
|
|
|
prevMonth={this.prevMonth}
|
|
|
nextMonth={this.nextMonth}
|
|
|
/>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
renderButton() {
|
|
|
return (
|
|
|
<View style={styles.buttonContainer}>
|
|
|
<TouchableOpacity onPress={() => {this.props.onCancel()}} style={styles.button}>
|
|
|
<Text style={[styles.text, styles.cancelText]}>
|
|
|
取消
|
|
|
</Text>
|
|
|
</TouchableOpacity>
|
|
|
<View style={styles.seprator} />
|
|
|
<TouchableOpacity onPress={() => {this.props.onOK(this.selected)}} style={styles.button}>
|
|
|
<Text style={styles.text}>
|
|
|
确定
|
|
|
</Text>
|
|
|
</TouchableOpacity>
|
|
|
</View>
|
|
|
);
|
|
|
}
|
|
|
|
|
|
render() {
|
|
|
return (
|
|
|
<View>
|
|
|
{this.renderContent()}
|
|
|
{this.renderButton()}
|
|
|
</View>
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const styles = StyleSheet.create({
|
|
|
listViewContainer: {
|
|
|
backgroundColor: 'white',
|
|
|
alignSelf: 'center',
|
|
|
transform: [{scaleY: -1}]
|
|
|
},
|
|
|
month: {
|
|
|
// transform: [{scaleY: -1}]
|
|
|
},
|
|
|
buttonContainer: {
|
|
|
flexDirection: 'row',
|
|
|
justifyContent: 'center',
|
|
|
alignItems: 'center',
|
|
|
borderTopWidth: 1,
|
|
|
borderTopColor: '#B0B0B0',
|
|
|
},
|
|
|
button: {
|
|
|
width: width / 2,
|
|
|
height: 35,
|
|
|
},
|
|
|
text: {
|
|
|
paddingTop: 10,
|
|
|
height: 35,
|
|
|
fontSize: 14,
|
|
|
color: '#444444',
|
|
|
textAlign: 'center',
|
|
|
},
|
|
|
seprator: {
|
|
|
width: 1,
|
|
|
height: 35,
|
|
|
backgroundColor: '#B0B0B0',
|
|
|
},
|
|
|
}); |
...
|
...
|
|