How can I load items in order to get a working demo for the agenda as seen in the agenda gif in the readme. Here is my code, most of which is from the Agenda.js file:
import React, { Component } from 'react';
import {
Alert,
Button,
Platform,
Text,
StyleSheet,
ScrollView,
View
} from 'react-native';
import {Calendar, CalendarList, Agenda} from 'react-native-calendars';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
items: {}
};
}
render() {
return (
<Agenda
items={
{'2017-05-22': [{text: 'item 1 - any js object'}],
'2017-05-23': [{text: 'item 2 - any js object'}],
'2017-05-24': [],
'2017-05-25': [{text: 'item 3 - any js object'},{text: 'any js object'}],
}}
items={this.state.items}
loadItemsForMonth={this.loadItems.bind(this)}
selected={'2017-05-16'}
renderItem={this.renderItem.bind(this)}
renderEmptyDate={this.renderEmptyDate.bind(this)}
rowHasChanged={this.rowHasChanged.bind(this)}
/>
);
}
loadItems(day) {
setTimeout(() => {
for (let i = -15; i < 85; i++) {
const time = day.timestamp + i * 24 * 60 * 60 * 1000;
const strTime = this.timeToString(time);
if (!this.state.items[strTime]) {
this.state.items[strTime] = [];
const numItems = Math.floor(Math.random() * 5);
for (let j = 0; j < numItems; j++) {
this.state.items[strTime].push({
name: 'Item for ' + strTime,
height: Math.max(50, Math.floor(Math.random() * 150))
});
}
}
}
//console.log(this.state.items);
const newItems = {};
Object.keys(this.state.items).forEach(key => {newItems[key] = this.state.items[key];});
this.setState({
items: newItems
});
}, 1000);
// console.log(`Load Items for ${day.year}-${day.month}`);
}
renderItem(item) {
return (
<View style={[styles.item, {height: item.height}]}><Text>{item.name}</Text></View>
);
}
renderEmptyDate() {
return (
<View style={styles.emptyDate}><Text>This is empty date!</Text></View>
);
}
rowHasChanged(r1, r2) {
return r1.name !== r2.name;
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
}
const styles = StyleSheet.create({
item: {
backgroundColor: 'white',
flex: 1,
borderRadius: 5,
padding: 10,
marginRight: 10,
marginTop: 17
},
emptyDate: {
height: 15,
flex:1,
paddingTop: 30
}
});
@LudwigVonPoopen
i use your code. but i saw warning at debugtool.
Warning: Failed child context type: Invalid child context virtualizedCell.cellKey of type number supplied to CellRenderer, expected string.
in CellRenderer (at VirtualizedList.js:681)
Hi, please check the example project
https://github.com/wix/react-native-calendars/tree/master/example
Does anyone have an example of this which uses actual data for 'items' rather than the randomly generated items in the example listed by @tautvilas, this seems overly confusing.
Thanks
Does anyone have an example of this which uses actual data for 'items' rather than the randomly generated items in the example listed by @tautvilas, this seems overly confusing.
Thanks
this, please we beg someone to post a proper example of data on renderItem
Does anyone have an example of this which uses actual data for 'items' rather than the randomly generated items in the example listed by @tautvilas, this seems overly confusing.
Thanksthis, please we beg someone to post a proper example of data on renderItem
been fighting with this for a day now. finally got it.
The format is:
{
"YYYY-MM-01:[{whatever:"youwant"},{whatever:"youwant"}]
,"YYYY-MM-02:[{whatever:"youwant"},{whatever:"youwant",whatever2:"youwant"}]
}
One day per element, then each item in the array. the outer most object is an object (not an array).
So.. i created an external (to my screen) function to simulate a call to my GetData.js / useEffect Fetch().
here are some code pieces to help (I'm all hooks). this isn't everything in the project, but should be good enough
Edit 2: Im posting this on an old issue because this is what Google shows as the second link in the react-native-calendars agenda example... good luck / have fun.
const getMonthData = ()=>{
let loadingData = true
let dataToReturn = {
"2020-06-07":[
{name:"Whats up Food Stuff",start:"2020-06-09T13:45:00",end:"2020-06-09 19:45"}
,{name:"Whats up second Stuff",start:"2020-06-09T18:45:00",end:"2020-06-09 21:45"}
],
"2020-06-08":[
{name:"Whats up Food Stuff",start:"2020-06-09T13:45:00",end:"2020-06-09 19:45"}
,{name:"Whats up second Stuff",start:"2020-06-09T18:45:00",end:"2020-06-09 21:45"}
]
}
return [dataToReturn,false]
}
export default function ThatOneScreen({props, navigation,route}) {
const [monthData, loadingData] = getMonthData()
const renderItem = (item, firstItemInDay) => {
console.log('rendering', item)
return (
<TouchableOpacity>
<>
<Text style={{color: xtextlink}}>{Moment(item.start).format("hh:mm a")}</Text>
<Text style={{color: '#555'}}>{item.name}</Text>
</>
</TouchableOpacity>
);
}
if (loadingData || !monthData){
return (
<View>
<Text>Loading</Text>
</View>
)
}
return (
<View style={[styles.bg, theme_bgcolor]}>
<Agenda
items={monthData}
renderItem={(item, firstItemInDay) => { return (renderItem(item, firstItemInDay))}}
pastScrollRange={0}
futureScrollRange={0}
//renderEmptyData={renderEmptyItem}
//renderEmptyDate={renderEmptyDate}
theme={calendarTheme}
/>
</View>
);
}
@El-Rick - Hero!
@El-Rick @DavidAPears
Can you suggest how we can improve our Docs? Examples?
@El-Rick @DavidAPears
Can you suggest how we can improve our Docs? Examples?
Examples would help. I would have followed an example from the GIFs for what I wanted... which was a customized expandableCalendar (week only component with scroll) and not the agenda.. BUT... i was able to figure this out and it took me a while to find out how, so i decided to post my solution here. Now I'm digging in the eC code for more info (looking for extraData, expo / redux or this component isn't updating themes on a redux dispatch/ change.. but its my battle to solve)
Having examples for Hooks and Classes would probably benefit everyone. The item generator (loadItems) example isn't bad, it should be external to the class Example or const Example()=>{}.
edit**: Most people work with APIs, so data is coming into the component rather than being generated in it. that's what I mean by external to the class/function
For the most part, i think people want to push their data into a magic box with simple hideKnob type configurations... but still have the power that onDateChanged / renderItems gives.
I've only been using js for a few months, react-native for a few weeks. But I've been a data architect for almost a decade. So my opinion.. really isn't worth much in this realm. But... i can say 100%, that the GIFs you had made me want to install this component, and having code that only do what the gifs do... would help a lot.
Maybe even having a wiki like material-ui, bootstrap, react-native-elements with your components and available props would be a cherry on top. Not as crazy as redux (i think a computer wrote their docs), but everything/anything helps.
keep up the good work. this is a great component. It has its 'personality' but all in all the cleanest calendar I've seen and you all commit a ton. So, thank you.
Any updates on this using JSON data?
I'm still having issues with loading items (currently does not render the Agenda, just returns a blank screen). However it works when I use their example that generates the items. I will be getting the dates from an API.
UPDATE:
This issue is that the agenda doesn't render if there are any other components on the screen. Below I'm wrapping it in a View and also am displaying Text. If I remove these, if works, however I need to include other elements on the screen.
Here's my code based on the example above:
import React from 'react';
import { Text, View, StyleSheet, Alert, TouchableOpacity } from 'react-native';
import { Agenda } from 'react-native-calendars';
const getMonthData = () => {
//let loadingData = true;
let dataToReturn = {
'2020-09-01': [{name: 'item 1 - any js object'}],
'2020-09-03': [{name: 'item 2 - any js object'}],
'2020-09-06': [{name: 'item 3 - any js object'}, {name: 'any js object'}]
};
return dataToReturn;
};
const LocateScreen = props => {
const monthData = getMonthData();
const renderItem = (item) => {
return (
<TouchableOpacity
onPress={() => Alert.alert(item.name)}
>
<Text>{item.name}</Text>
</TouchableOpacity>
);
};
return (
<View style={styles.locate}>
<Text>Locate Screen</Text>
<Agenda
items={monthData}
renderItem={(item) => { return (renderItem(item)) }}
selected={'2020-09-01'}
pastScrollRange={0}
futureScrollRange={0}
//renderEmptyData={renderEmptyItem}
//renderEmptyDate={renderEmptyDate}
//theme={calendarTheme}
/>
</View>
);
};
const styles = StyleSheet.create({
locate: {
backgroundColor: '#eee'
}
});
export default LocateScreen;
I'm still having issues with loading items (currently does not render the Agenda, just returns a blank screen). However it works when I use their example that generates the items. I will be getting the dates from an API.
UPDATE:
This issue is that the agenda doesn't render if there are any other components on the screen. Below I'm wrapping it in a View and also am displaying Text. If I remove these, if works, however I need to include other elements on the screen.Here's my code based on the example above:
import React from 'react'; import { Text, View, StyleSheet, Alert, TouchableOpacity } from 'react-native'; import { Agenda } from 'react-native-calendars'; const getMonthData = () => { //let loadingData = true; let dataToReturn = { '2020-09-01': [{name: 'item 1 - any js object'}], '2020-09-03': [{name: 'item 2 - any js object'}], '2020-09-06': [{name: 'item 3 - any js object'}, {name: 'any js object'}] }; return dataToReturn; }; const LocateScreen = props => { const monthData = getMonthData(); const renderItem = (item) => { return ( <TouchableOpacity onPress={() => Alert.alert(item.name)} > <Text>{item.name}</Text> </TouchableOpacity> ); }; return ( <View style={styles.locate}> <Text>Locate Screen</Text> <Agenda items={monthData} renderItem={(item) => { return (renderItem(item)) }} selected={'2020-09-01'} pastScrollRange={0} futureScrollRange={0} //renderEmptyData={renderEmptyItem} //renderEmptyDate={renderEmptyDate} //theme={calendarTheme} /> </View> ); }; const styles = StyleSheet.create({ locate: { backgroundColor: '#eee' } }); export default LocateScreen;I faced the same problem and solved it by giving each item a height on the item object itself. Give this function a try.
const getMonthData = () => {
//let loadingData = true;
let dataToReturn = {
'2020-09-01': [{name: 'item 1 - any js object', height: 100}],
'2020-09-03': [{name: 'item 2 - any js object', height: 100}],
'2020-09-06': [{name: 'item 3 - any js object', height: 100}, {name: 'any js object', height: 100}]
};
return dataToReturn;
};
Most helpful comment
Does anyone have an example of this which uses actual data for 'items' rather than the randomly generated items in the example listed by @tautvilas, this seems overly confusing.
Thanks