Hi,
I am very new to React native and working on Calendar App. I really like this calendar Agenda view.
I want to set the today's date on button click in Agenda view or move to a different month -
https://hub.mangoapps.com/sf/ODcxNzZfMTMyNzE0NQ .
Is it possible to set the date?
Try this code:
<Agenda ref={(agenda) => { this.agenda = agenda; }} />
Then in your 'today' handler method:
this.agenda.chooseDay(date)
Tell me if this works to you. I probably will add chooseDay to documentation soon
Hi Tautvilas,
Thank you for prompt response.
I've tried above solution but getting error "undefined is not an object (evaluating 'this.agenda.chooseDay')" - https://dongawli.tinytake.com/sf/MTYyNzk4NV81NTA4Mzgz
Do I need to import any component/class/file from React Native Calendars package ?
Currently I've just imported {Agenda} from 'react-native-calendars'.
Are you sure you got the reference code right?
https://facebook.github.io/react/docs/refs-and-the-dom.html
Also references are only accesible after component is mounted
Yes, I am using the reference code right.
Even I am not able to use the 'this.state.items', timeToString() method in newly added handler methods.
Same methods or state variables I am able to access from loadItems() method. There is something not right in my project may be. I am finding out.
Please let me know is it necessary to register the component
Navigation.registerComponent('Agenda', () => AgendaScreen); as I am not using registerScreens() in my project and directly accessing agenda.js
This is example how you should achieve what you want. There was also one bug that I fixed just now to make chooseDay properly work.
import React, {Component} from 'react';
import {
Text,
TouchableOpacity,
View,
Dimensions,
Animated
} from 'react-native';
import XDate from 'xdate';
import {parseDate, xdateToData} from '../interface';
import dateutils from '../dateutils';
import CalendarList from '../calendar-list';
import ReservationsList from './reservation-list';
import styleConstructor from './style';
const CALENDAR_OFFSET = 38;
export default class AgendaView extends Component {
constructor(props) {
super(props);
this.styles = styleConstructor(props.theme);
this.screenHeight = Dimensions.get('window').height;
this.scrollTimeout = undefined;
this.state = {
openAnimation: new Animated.Value(0),
calendarScrollable: false,
firstResevationLoad: false,
selectedDay: parseDate(this.props.selected) || XDate(true),
topDay: parseDate(this.props.selected) || XDate(true),
};
this.currentMonth = this.state.selectedDay.clone();
this.expandCalendar = this.expandCalendar.bind(this);
}
onLayout(event) {
this.screenHeight = event.nativeEvent.layout.height;
this.calendar.scrollToDay(this.state.selectedDay.clone(), CALENDAR_OFFSET, false);
}
onVisibleMonthsChange(months) {
if (this.props.items && !this.state.firstResevationLoad) {
clearTimeout(this.scrollTimeout);
this.scrollTimeout = setTimeout(() => {
if (this.props.loadItemsForMonth) {
this.props.loadItemsForMonth(months[0]);
}
}, 200);
}
}
loadReservations(props) {
if ((!props.items || !Object.keys(props.items).length) && !this.state.firstResevationLoad) {
this.setState({
firstResevationLoad: true
}, () => {
if (this.props.loadItemsForMonth) {
this.props.loadItemsForMonth(xdateToData(this.state.selectedDay));
}
});
}
}
componentWillMount() {
this.loadReservations(this.props);
}
componentWillReceiveProps(props) {
if (props.items) {
this.setState({
firstResevationLoad: false
});
} else {
this.loadReservations(props);
}
}
expandCalendar() {
this.setState({
calendarScrollable: true
});
Animated.timing(this.state.openAnimation, {
toValue: 1,
duration: 300
}).start();
this.calendar.scrollToDay(this.state.selectedDay, 100 - ((this.screenHeight / 2) - 16), true);
}
chooseDay(d) {
const day = parseDate(d);
this.setState({
calendarScrollable: false,
selectedDay: day.clone()
});
if (this.state.calendarScrollable) {
this.setState({
topDay: day.clone()
});
}
Animated.timing(this.state.openAnimation, {
toValue: 0,
duration: 200
}).start();
this.calendar.scrollToDay(day, CALENDAR_OFFSET, true);
if (this.props.loadItemsForMonth) {
this.props.loadItemsForMonth(xdateToData(day));
}
if (this.props.onDayPress) {
this.props.onDayPress(xdateToData(day));
}
}
renderReservations() {
return (
<ReservationsList
rowHasChanged={this.props.rowHasChanged}
renderItem={this.props.renderItem}
renderDay={this.props.renderDay}
renderEmptyDate={this.props.renderEmptyDate}
reservations={this.props.items}
selectedDay={this.state.selectedDay}
topDay={this.state.topDay}
onDayChange={this.onDayChange.bind(this)}
onScroll={() => {}}
ref={(c) => this.list = c}
/>
);
}
onDayChange(day) {
const newDate = parseDate(day);
const withAnimation = dateutils.sameMonth(newDate, this.state.selectedDay);
this.calendar.scrollToDay(day, CALENDAR_OFFSET, withAnimation);
this.setState({
selectedDay: parseDate(day)
});
}
render() {
const weekDaysNames = dateutils.weekDayNames(this.props.firstDay);
const maxCalHeight = this.screenHeight + 20;
const calendarStyle = [this.styles.calendar, {height: this.state.openAnimation.interpolate({
inputRange: [0, 1],
outputRange: [104, maxCalHeight]
})}];
const weekdaysStyle = [this.styles.weekdays, {opacity: this.state.openAnimation.interpolate({
inputRange: [0, 1],
outputRange: [1, 0]
})}];
let knob = (<View style={this.styles.knobContainer}/>);
if (!this.props.hideKnob) {
knob = (
<View style={this.styles.knobContainer}>
<TouchableOpacity onPress={this.expandCalendar}>
<View style={this.styles.knob}/>
</TouchableOpacity>
</View>
);
}
return (
<View onLayout={this.onLayout.bind(this)} style={[this.props.style, {flex: 1}]}>
<View style={this.styles.reservations}>
{this.renderReservations()}
</View>
<Animated.View style={calendarStyle}>
<CalendarList
theme={this.props.theme}
onVisibleMonthsChange={this.onVisibleMonthsChange.bind(this)}
ref={(c) => this.calendar = c}
selected={[this.state.selectedDay]}
current={this.currentMonth}
markedDates={this.props.items}
onDayPress={this.chooseDay.bind(this)}
scrollingEnabled={this.state.calendarScrollable}
hideExtraDays={this.state.calendarScrollable}
firstDay={this.props.firstDay}
/>
{knob}
</Animated.View>
<Animated.View style={weekdaysStyle}>
{weekDaysNames.map((day) => (
<Text key={day} style={this.styles.weekday}>{day}</Text>
))}
</Animated.View>
</View>
);
}
}
Thank you Tautvilas.
Able to solve the issue and set the calendar date to today.
I have the same problem, I just want selected variable in render part is today.
I used references in <Agenda />and put this.agenda.chooseDay(date) in selected variable. What is wrong?
Thank you!
Hi,
Here is how I've fixed the issue..
Agenda control is declared like this ->
/>
Today button placed like this in view and calling method _pressToday()
_pressToday(event) {
const today = new Date();
this.agenda.chooseDay(today);
}
Hope this will solve your issue.
Thank you about your answer, I will try the same way with your - have button "TODAY". So It's impossible to set selected variable become today, right?
@dongawli
If I scroll the agenda to the next month it doesn't go back anymore.
For example, today is Jan 7th. When I scroll down to someday in February and press the button with the following action:
this.agenda.chooseDay('2019-01-07')
It doesn't scroll back to Jan 7th.
Anyone had this issue? Thx
Most helpful comment
Hi,
Here is how I've fixed the issue..
Agenda control is declared like this ->
..
/>
Today button placed like this in view and calling method _pressToday()
_pressToday(event) {
const today = new Date();
this.agenda.chooseDay(today);
}
Hope this will solve your issue.