Reputation: 13
I have a JSON list of test transactions and I'm able to display them with the dates they were performed but I would like to be able to group these so that for instance all transactions that were performed today are listed under one banner that says 'Today' and other transactions that were performed on same dates fall under a banner displaying that date. I've tried to think of ways to implement this but am struggling, any help would be appreciated.
Below is the component I'm trying to create this function within.
import React from 'react';
import {
Text,
SafeAreaView,
StatusBar,
ActivityIndicator,
FlatList,
View,
List,
Image,
SectionList,
} from 'react-native';
import moment from 'moment';
import transactions from '../testdata/transactions.json';
import Icon from 'react-native-ionicons'
var datetest = [moment(transactions[0].addedtime).calendar()];
moment.locale('en-uk', {
calendar: {
lastDay: '[Yesterday ]',
sameDay: '[Today]',
nextDay: '[Tomorrow]',
lastWeek: 'L',
nextWeek: 'dddd',
sameElse: 'L',
},
});
class TransactionsComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: true,
dataSource: [],
epochDate: [],
};
}
componentDidMount() {
this.setState({
isLoading: false,
dataSource: transactions,
epochDate: datetest,
});
}
renderSeparator = () => {
return (
<View
style={{
height: 0,
width: '100%',
backgroundColor: '#F5F5F5 ',
marginLeft: '0%',
}}
/>
);
};
render() {
if (this.state.isLoading) {
return (
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator />
</View>
);
}
}
render() {
return (
<View style={{width: '100%'}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => (
<View
style={{
flex: 1,
flexDirection: 'column',
borderBottomColor: '#5AA8C8',
borderBottomWidth: 1,
paddingBottom: 10,
}}>
{ <View style={{marginLeft: '3%'}}>
<Text style={{fontWeight: 'bold', fontSize: 18}}>
{moment(item.addedtime).calendar()}
</Text>
</View> }
<View style={{marginLeft: '5%', flexDirection: 'row', flex: 2,}}>
<View
style={{flexDirection: 'row', alignItems: 'center', flex: 3}}>
<Image
style={{width: 40, height: 40}}
source={{uri: item.iconblob}}
/>
<Text
style={{fontSize: 16, color: 'grey', fontWeight: 'bold'}}>
{' '}
{item.merchantname}
</Text>
</View>
<View
style={{
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-end',
marginRight: '3%',
}}>
<Text style={{fontSize: 18, color: 'black'}}>
<Text style={{fontSize: 12, color: 'grey'}}>CHF</Text>
{parseFloat(item.billingamountauthorised / 100).toFixed(2)}
</Text>
<View style= {{flex :6, flexDirection:"row", justifyContent:"flex-end"}}>
<Icon name="arrow-dropright" color="#5AA8C8" />
</View>
</View>
</View>
</View>
)}
keyExtractor={item => item.uniqueref}
//containerStyle={{borderBottomWidth: 0}}
/>
</View>
);
}
}
export default TransactionsComponent;
This is an example of how the JSON looks with addedtime being the epoch date the transaction was created
[
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B"
},
{
"billingamountauthorised": "750",
"iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
"merchantname": "Starbucks",
"merchantstreet": "Rue du Mont-Blanc",
"addedtime": 1576590342000,
"uniqueref": "D0868EB65DC2DE585"
},
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B0"
},
{
"billingamountauthorised": "100",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1575554709000,
"uniqueref": "0D10B5F56A73D73DD"
},
{
"billingamountauthorised": "1320",
"iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
"merchantname": "Schweizerische Bundesbahnen",
"merchantstreet": "Bahnhofplatz",
"addedtime": 1575554709000,
"uniqueref": "2F3D907B0FF675216"
}
]
This is currently how it is the transactions are looking with each one displaying the date next to it regardless of if the date is the same as another transaction.
Upvotes: 1
Views: 4723
Reputation: 4631
If you are planning to use SectionList, you need to group item according to dates. in-order to do that you can used reduce method in JavaScript.
const JSON_DATA = [
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B"
},
{
"billingamountauthorised": "750",
"iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
"merchantname": "Starbucks",
"merchantstreet": "Rue du Mont-Blanc",
"addedtime": 1576590342000,
"uniqueref": "D0868EB65DC2DE585"
},
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B0"
},
{
"billingamountauthorised": "100",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1575554709000,
"uniqueref": "0D10B5F56A73D73DD"
},
{
"billingamountauthorised": "1320",
"iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
"merchantname": "Schweizerische Bundesbahnen",
"merchantstreet": "Bahnhofplatz",
"addedtime": 1575554709000,
"uniqueref": "2F3D907B0FF675216"
}
]
let data = Object.values(JSON_DATA.reduce((acc, item) => {
if (!acc[item.addedtime]) acc[item.addedtime] = {
title: item.addedtime,
data: []
};
acc[item.addedtime].data.push(item);
return acc;
}, {}))
Now you can used React-Native SectionList as below demo.
import React, { Component } from 'react';
import { StyleSheet, Text, View, SectionList, Image } from 'react-native';
const JSON_DATA = [
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B"
},
{
"billingamountauthorised": "750",
"iconblob": "https://upload.wikimedia.org/wikipedia/en/thumb/d/d3/Starbucks_Corporation_Logo_2011.svg/1024px-Starbucks_Corporation_Logo_2011.svg.png",
"merchantname": "Starbucks",
"merchantstreet": "Rue du Mont-Blanc",
"addedtime": 1576590342000,
"uniqueref": "D0868EB65DC2DE585"
},
{
"billingamountauthorised": "1",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1576590342000,
"uniqueref": "A446806878486B5B0"
},
{
"billingamountauthorised": "100",
"iconblob": "https://is1-ssl.mzstatic.com/image/thumb/Purple114/v4/cb/cf/bb/cbcfbb61-4d03-4f4e-ecf7-b7582688435f/source/512x512bb.jpg",
"merchantname": "K Kiosk Sihlquai",
"merchantstreet": "Sihlquai",
"addedtime": 1575554709000,
"uniqueref": "0D10B5F56A73D73DD"
},
{
"billingamountauthorised": "1320",
"iconblob": "https://pbs.twimg.com/profile_images/568401882444349441/KDWvUHCJ_400x400.jpeg",
"merchantname": "Schweizerische Bundesbahnen",
"merchantstreet": "Bahnhofplatz",
"addedtime": 1575554709000,
"uniqueref": "2F3D907B0FF675216"
}
]
const DATA = Object.values(JSON_DATA.reduce((acc, item) => {
if (!acc[item.addedtime]) acc[item.addedtime] = {
title: item.addedtime,
data: []
};
acc[item.addedtime].data.push(item);
return acc;
}, {}))
export default class App extends Component {
renderItems = ({ item }) => {
return (
<View style={styles.itemStyle}>
<Image
style={{ width: 60, height: 60 }}
source={{ uri: item.iconblob }}
/>
<Text>{item.merchantname}</Text>
<Text>{item.merchantstreet}</Text>
</View>
)
}
renderHeader = ({ section }) => {
return (
<View style={styles.headerStyle}>
<Text>{section.title}</Text>
</View>
)
}
render() {
return (
<SectionList
sections={DATA}
keyExtractor={(item, index) => item + index}
renderItem={this.renderItems}
renderSectionHeader={this.renderHeader}
/>
);
}
}
const styles = StyleSheet.create({
itemStyle: {
backgroundColor: '#dcdee0',
padding: 10,
margin: 5,
},
headerStyle: {
paddingLeft: 10,
paddingVertical: 10,
},
});
Hope this will help you. try to modify code according to your requirements.
Upvotes: 4