Created
March 29, 2018 18:03
-
-
Save dereknelson/110dde0b537217d06043e58ba877cac5 to your computer and use it in GitHub Desktop.
Alphabetized List implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component, } from 'react'; | |
import { View, Text, TouchableOpacity, FlatList, ListItem, Image, TextInput, Dimensions, | |
Animated, StyleSheet, SectionList, PanResponder, PixelRatio, ScrollView } from 'react-native'; | |
import sectionListGetItemLayout from 'react-native-section-list-get-item-layout' | |
var { height, width } = Dimensions.get('window') | |
/* this component is re-used between displaying the friends/groups and being able to pick them in metoo posts, so there are a few different if statements that | |
help the component decide whether to render something that is clickable that will be highlighted/checked or if it should navigate upon clicking */ | |
export default class AlphabetizedList extends Component { | |
constructor(props){ | |
super(props) | |
alphabet = [ { title: 'A', data: []}, { title: 'B', data: [] }, {title: 'C', data: []}, {title: 'D', data: []}, {title: 'E', data: []}, {title: 'F', data: []}, {title: 'G', data: []}, {title: 'H', data: []}, | |
{title: 'I', data: []}, {title: 'J', data: []}, {title: 'K', data: []}, {title: 'L', data: []}, {title: 'M', data: []}, {title: 'N', data: []}, {title: 'O', data: []}, {title: 'P', data: []}, {title: 'Q', data: []}, | |
{title: 'R', data: []}, {title: 'S', data: []}, {title: 'T', data: []}, {title: 'U', data: []}, {title: 'V', data: []}, {title: 'W', data: []}, {title: 'X', data: []}, {title: 'Y', data: []}, {title: 'Z', data: []} ] | |
this.state = { results: ["Kaleb", "Alex", "Alden", "Alex", "Alyssa", "Amanda", "Amarinda", "Andy", "alyssa", "Antonio", "Justin", "Apple", "Baylor", "ashlynn", "Augusto", "Alex", "ben", "carter", "Billy", | |
"Garrett", "Brendan", "Brady", "Brady", "Brandon", "Brevin", "Brendan", "Bros", "Camille", "Carina", "caro", "Eron", "Carter", "Charlie", "Chris", "Christine", "Cleo", "Colleen", "Collin", "Cora", "Corey", "Cory", | |
"Connor", "Dakota", "Dan", "Dan", "dennis", "Derek", "Stephen", "Alex", "drew", "Isaac", "Will", "eliza", "ellie", "Emily", "faith", "Peter", "Ike", "Ryan", "James", "Francesca", "Gabe", "Garrett", "George", "Giuseppe", | |
"Matt", "Greg", "Vincent", "Grant", "Haidar", "Jakob", "Hanna", "Harry", "helena", "Hunter", "Sean", "Ian", "Ian", "Jordan", "jack", "Jacob", "Jake", "Jake", "Jake", "Jacob", "Chris", "James", "Jed", "Jess", "jill", "Jim", | |
"Jimi", "Joe", "Jon", "Jonny", "Josh", "Jo", "Jullian", "Jonathan", "Kailee"], | |
searchText: '', alphabet: alphabet, alphabetPlaceHolder: alphabet, } | |
this.getItemLayout = sectionListGetItemLayout({ | |
// The height of the row with rowData at the given sectionIndex and rowIndex | |
// getItemHeight: (this.state.alphabet, 0, 0) => sectionIndex === 0 ? 100 : 50, | |
getItemHeight: (rowData, sectionIndex, rowIndex) => sectionIndex === 0 ? 150 : 20, | |
// These three properties are optional | |
getSeparatorHeight: () => 1 / PixelRatio.get(), // The height of your separators | |
getSectionHeaderHeight: () => 10, // The height of your section headers | |
getSectionFooterHeight: () => 0, // The height of your section footers | |
}) | |
} | |
componentWillMount(){ | |
var alphabet = this.sort() | |
this.panResponder = PanResponder.create({ | |
onStartShouldSetPanResponder: (event, gestureState) => true, | |
onStartShouldSetPanResponderCapture: (event, gestureState) => true, | |
onMoveShouldSetPanResponder: (event, gestureState) => true, | |
onMoveShouldSetPanResponderCapture: (event, gestureState) => true, | |
onPanResponderGrant: (event, gestureState) => { | |
for (i = 0; i < alphabet.length; i++){ | |
var { letterPosition, letterHeight } = alphabet[i] | |
letterPosition += this.offset | |
if (event.nativeEvent.pageY < letterPosition + letterHeight && event.nativeEvent.pageY > letterPosition){ | |
this.scroll(i) | |
break | |
} | |
} | |
}, | |
onPanResponderMove: (event, gestureState) => { | |
for (i = 0; i < alphabet.length; i++){ | |
var { letterPosition, letterHeight } = alphabet[i] | |
letterPosition += this.offset | |
if (event.nativeEvent.pageY < letterPosition + letterHeight && event.nativeEvent.pageY > letterPosition){ | |
this.scroll(i) | |
break | |
} | |
} | |
}, | |
onPanResponderTerminationRequest: (evt, gestureState) => true, | |
onPanResponderRelease: (evt, gestureState) => { | |
}, | |
onPanResponderTerminate: (evt, gestureState) => { | |
}, | |
onShouldBlockNativeResponder: (evt, gestureState) => { | |
return true; | |
}, | |
}) | |
} | |
render() { | |
var { alphabet } = this.state | |
return ( | |
<View onLayout={(event) => this.getOffset(event)} style={{ flexDirection: 'row', backgroundColor: 'white'}}> | |
<SectionList | |
sections={alphabet} | |
ref={ref => this.list = ref} | |
keyExtractor={(item, index) => index} | |
renderItem={this.renderItem} | |
ListHeaderComponent={this.SearchBar} | |
SectionSeparatorComponent={this.separator} | |
getItemLayout={this.getItemLayout} | |
/> | |
<View style={{ position: 'absolute', right: 5, height: height, justifyContent: 'center', }} > | |
<this.renderSidebar/> | |
</View> | |
</View> | |
) | |
} | |
renderItem = ({item, index}) => ( | |
<View style={{ flexDirection: 'row', alignItems: 'center', borderWidth: StyleSheet.hairlineWidth, borderColor: 'gray', paddingVertical: 5}} > | |
<Text style={{ fontSize: 20, paddingLeft: 15 }}> | |
{item} | |
</Text> | |
</View> | |
) | |
onLayout = (event) => { | |
var { x, y, width, height } = event.nativeEvent.layout; | |
this.totalHeight = height | |
} | |
// for the sake of simplicity, this doesn't actually do anything, but is more for adding complexity to the height of the overall component | |
SearchBar = () => ( | |
<View style={{ flexDirection: 'row', alignItems: 'center', borderColor: 'gray', borderWidth: StyleSheet.hairlineWidth, }}> | |
<TextInput | |
style={{ width: width * .95, backgroundColor: 'white', paddingLeft: 15, fontSize: 18, paddingVertical: 15 }} | |
value={this.state.searchText} | |
ref={ref => this.textInput = ref} | |
onChangeText={(text) => this.setState({ searchText })} | |
placeholder='Search friends' | |
autoCapitalize={'none'} | |
autoCorrect={false} | |
clearButtonMode="while-editing" | |
/> | |
</View> | |
) | |
separator = (separator) => { | |
if (separator.trailingItem != null){ | |
return ( | |
<Text style={{ paddingLeft: 20, fontSize: 20, color: 'blue' }} > | |
{separator.section.title} | |
</Text> | |
) | |
} | |
return null | |
} | |
keyExtractor = (item, index) => item.uuid; | |
scroll = (index) => { | |
this.list.scrollToLocation({ itemIndex: 0, sectionIndex: index, viewPosition: 0, animated: false }) | |
} | |
setLetterPosition = (event, i) => { | |
var { alphabet } = this.state | |
// the + 60 is for the safeareaview which doesn't get counted in onlayout | |
alphabet[i].letterPosition = event.nativeEvent.layout.y + 60, alphabet[i].letterHeight = event.nativeEvent.layout.height | |
} | |
getOffset = (event) => { | |
this.offset = event.nativeEvent.layout.y | |
} | |
renderSidebar = () => { | |
var { alphabet } = this.state | |
return ( | |
<View {...this.panResponder.panHandlers} hitSlop={{ left: 5 }} onLayout={(event) => this.getOffset(event)} | |
style={{ flexDirection: 'column', flexBasis: 'auto', alignContent: 'center', justifyContent: 'center', alignItems: 'center' }} > | |
{ alphabet.map((data, i) => { | |
return ( | |
<Text key={i} onLayout={(event) => this.setLetterPosition(event, i)} style={{ fontSize: 13, color: 'gray'}} > | |
{data.title} | |
</Text> | |
) | |
}) } | |
</View> | |
) | |
} | |
sort = () => { | |
const { results } = this.state | |
var alphabet = [ { title: 'A', data: []}, { title: 'B', data: [] }, {title: 'C', data: []}, {title: 'D', data: []}, {title: 'E', data: []}, {title: 'F', data: []}, {title: 'G', data: []}, {title: 'H', data: []}, | |
{title: 'I', data: []}, {title: 'J', data: []}, {title: 'K', data: []}, {title: 'L', data: []}, {title: 'M', data: []}, {title: 'N', data: []}, {title: 'O', data: []}, {title: 'P', data: []}, {title: 'Q', data: []}, | |
{title: 'R', data: []}, {title: 'S', data: []}, {title: 'T', data: []}, {title: 'U', data: []}, {title: 'V', data: []}, {title: 'W', data: []}, {title: 'X', data: []}, {title: 'Y', data: []}, {title: 'Z', data: []} ] | |
for (i = 0; i < results.length; i++){ | |
const letter = results[i][0].toLowerCase() | |
if (letter == 'a') alphabet[0].data.push(results[i]) | |
if (letter == 'b') alphabet[1].data.push(results[i]) | |
if (letter == 'c') alphabet[2].data.push(results[i]) | |
if (letter == 'd') alphabet[3].data.push(results[i]) | |
if (letter == 'e') alphabet[4].data.push(results[i]) | |
if (letter == 'f') alphabet[5].data.push(results[i]) | |
if (letter == 'g') alphabet[6].data.push(results[i]) | |
if (letter == 'h') alphabet[7].data.push(results[i]) | |
if (letter == 'i') alphabet[8].data.push(results[i]) | |
if (letter == 'j') alphabet[9].data.push(results[i]) | |
if (letter == 'k') alphabet[10].data.push(results[i]) | |
if (letter == 'l') alphabet[11].data.push(results[i]) | |
if (letter == 'm') alphabet[12].data.push(results[i]) | |
if (letter == 'n') alphabet[13].data.push(results[i]) | |
if (letter == 'o') alphabet[14].data.push(results[i]) | |
if (letter == 'p') alphabet[15].data.push(results[i]) | |
if (letter == 'q') alphabet[16].data.push(results[i]) | |
if (letter == 'r') alphabet[17].data.push(results[i]) | |
if (letter == 's') alphabet[18].data.push(results[i]) | |
if (letter == 't') alphabet[19].data.push(results[i]) | |
if (letter == 'u') alphabet[20].data.push(results[i]) | |
if (letter == 'v') alphabet[21].data.push(results[i]) | |
if (letter == 'w') alphabet[22].data.push(results[i]) | |
if (letter == 'x') alphabet[23].data.push(results[i]) | |
if (letter == 'y') alphabet[24].data.push(results[i]) | |
if (letter == 'z') alphabet[25].data.push(results[i]) | |
} | |
// this.totalHeight = 0 | |
// for (i = 0; i < alphabet.length; i++){ | |
// this.totalHeight += alphabet[i].data.length * 69 | |
// alphabet[i].height = this.totalHeight // entirely coincidentally, the height of each friend is 69 | |
// } | |
this.setState({ alphabet }) | |
return alphabet | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment