0

I have a working React Native Search bar which on keypress populates a FlatList view. When a Flatlist element is pressed I want to highlight just the element that is selected. Any ideas on how this can be done in React Native?

import React, { useState, Component, useEffect } from "react"; import { SearchBar } from 'react-native-elements'; import { StyleSheet, Text, View, ScrollView, Image, TextInput, Button, Alert, TouchableOpacity, Modal, Pressable, ActivityIndicator, FlatList } from "react-native"; import { useIsFocused } from "@react-navigation/native"; import { registerRootComponent } from 'expo'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import { useNavigation } from '@react-navigation/native'; import constants from './Constants.js'; import { styles } from './CommonStylesWeb.js'; import RNPickerSelect from 'react-native-picker-select'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; const CancerHomepageWeb = ({navigation}) => { const [cancerWiki, setCancerWiki] = useState(""); const [cancerType, setCancerType] = useState(""); const [selectedValue, setSelectedValue] = useState(null); const [selectedLabel, setSelectedLabel] = useState(null); const [options, setOptions] = useState([]); const [cancerWikiContent, setCancerWikiContent] = useState(""); const [loadingWiki, setLoadingWiki] = useState(null); const [loadingCancers, setLoadingCancers] = useState(null); console.log("navigation ", navigation); useEffect(() => { const getData = async () => { // show loading icon setLoadingWiki(true); var urlCancerWiki = await constants.getServerURL() + 'cancers_wiki'; console.warn("NEW COMMENT") console.warn(urlCancerWiki); let resultCancerWiki = await fetch(urlCancerWiki, { method: "GET", mode: 'cors' }).then(response => response.json()) .then(response => { if (response.status == 200) { setLoadingWiki(false) console.warn(response.content) setCancerWiki(response.content) } else { setLoadingWiki(false) console.warn(response.message) setGeneWiki(response.message) } }); }; getData(); }, []); async function handleChangeCancer(value, label) { console.warn("CANCER HAS CHANGED"); setSelectedValue(value); console.warn(value) if(label) { setCancerWiki(""); setCancerWikiContent(""); setLoadingWiki(true); const url = await constants.getServerURL() + 'cancer_wiki'; console.warn(url); let result = fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: value}), mode: 'cors' }).then(response => response.json()) .then(response => { if (response.status == 200) { setLoadingWiki(false); setCancerWikiContent(response.content) setCancerWiki("") } else { setLoadingWiki(false) console.warn(response.message) setGeneWiki(response.message) } }); } }; const searchCancers = async() => { const url = await constants.getServerURL() + 'cancer_name'; console.warn(url); console.warn(cancerType); if (cancerType.length >= 3) { setLoadingCancers(true); let result = fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ cancer_type: cancerType}), mode: 'cors' }).then(response => response.json()) .then(response => { setOptions([]); optionsTemp = []; console.warn("GETTING CANCER RESPONSE") console.warn(response) if (response.status == 200) { setLoadingCancers(false); //setCancer = response.cancers console.warn("VALID CANCER RESPONSE") response.content.map( (cancer) => { optionsTemp.push(new Object({label:cancer.name , value: cancer.id})); }); console.warn(optionsTemp) setOptions(optionsTemp); } else { setLoadingCancers(false); console.warn("Error retrieving Cancer"); //setErrorMessage("Error Getting Cancers!"); //setErrorVisible(true); } }); } } const renderItem = ({ item }) => ( <TouchableOpacity onPress={() => handleChangeCancer(item.value,item.label)}> <Text style={styles.item}>{item.label}</Text> </TouchableOpacity> ); return ( <View style={styles.container}> <StatusBar style="auto" /> <View> <SearchBar style={styles.searchBar} placeholder="Search by Cancer Type" onChangeText={(cancerType) => setCancerType(cancerType)} value={cancerType} onKeyPress={searchCancers} /> {loadingCancers && <ActivityIndicator size="large" /> } <FlatList data={options} renderItem={renderItem} keyExtractor={item => item.value} style={styles.dropdown} /> </View> <View> <Text style={{ fontSize: 20 }}>Cancers</Text> </View> <ScrollView> <View style={styles.wikiView}> <Text>{cancerWikiContent}</Text> <Text>{cancerWiki}</Text> {loadingWiki && <SafeAreaProvider> <SafeAreaView style={[styles.loadingContainer, styles.loadingHorizontal]}> <ActivityIndicator size="large" /> </SafeAreaView> </SafeAreaProvider> } </View> </ScrollView> </View> ); } export { CancerHomepageWeb }; 

I was thinking of adding a different style for the selected flatList element. (ie. itemSelected) So adding a condition to change the style of the selected item. But I will have to first apply the default style (ie. item) to all FlatList elements so I only have one element highlighted at a time.

import { StyleSheet, Text, View, Image, TextInput, Button, Alert, TouchableOpacity, } from "react-native"; import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen'; const styles = StyleSheet.create({ searchBar: { width: wp(60), height: 10, paddingLeft: 10, flex: 1, alignItems: "center", justifyContent: "center", } dropdown: { maxHeight: 150, backgroundColor: 'white', borderWidth: 1, borderColor: 'gray', borderRadius: 5, marginTop: 5, }, item: { padding: 15, fontSize: 16, }, itemSelected: { padding: 15, fontSize: 16, backgroundColor: '#2196F3', color: "white" } }); export { styles };``` 

1 Answer 1

0

I was able to highlight the selected item in a flatlist by using flag - highlightedIndex - whch then applys the higlighted styling - styles.itemSelected. Here is the code that worked for me.

import { StatusBar } from "expo-status-bar"; import React, { useState, Component, useEffect } from "react"; import { SearchBar } from 'react-native-elements'; import { StyleSheet, Text, View, ScrollView, Image, TextInput, Button, Alert, TouchableOpacity, Modal, Pressable, ActivityIndicator, FlatList } from "react-native"; import { useIsFocused } from "@react-navigation/native"; import { registerRootComponent } from 'expo'; import {NavigationContainer} from '@react-navigation/native'; import {createNativeStackNavigator} from '@react-navigation/native-stack'; import { useNavigation } from '@react-navigation/native'; import constants from './Constants.js'; import { styles } from './CommonStylesWeb.js'; import RNPickerSelect from 'react-native-picker-select'; import {SafeAreaView, SafeAreaProvider} from 'react-native-safe-area-context'; const CancerHomepageWeb = ({navigation}) => { const [cancerWiki, setCancerWiki] = useState(""); const [cancerType, setCancerType] = useState(""); const [selectedValue, setSelectedValue] = useState(null); const [selectedLabel, setSelectedLabel] = useState(null); const [options, setOptions] = useState([]); const [cancerWikiContent, setCancerWikiContent] = useState(""); const [loadingWiki, setLoadingWiki] = useState(null); const [loadingCancers, setLoadingCancers] = useState(null); const [highlightedIndex, setHighlightedIndex] = useState(-1); console.log("navigation ", navigation); useEffect(() => { const getData = async () => { // show loading icon setLoadingWiki(true); var urlCancerWiki = await constants.getServerURL() + 'cancers_wiki'; console.warn("NEW COMMENT") console.warn(urlCancerWiki); let resultCancerWiki = await fetch(urlCancerWiki, { method: "GET", mode: 'cors' }).then(response => response.json()) .then(response => { if (response.status == 200) { setLoadingWiki(false) console.warn(response.content) setCancerWiki(response.content) } else { setLoadingWiki(false) console.warn(response.message) setGeneWiki(response.message) } }); }; getData(); }, []); async function handleChangeCancer(value, label) { // find index number for options index = 0; for (option of options) { if (option.value == value) { setHighlightedIndex(index); } index++; } console.warn("CANCER HAS CHANGED"); setSelectedValue(value); console.warn(value) if(label) { setCancerWiki(""); setCancerWikiContent(""); setLoadingWiki(true); const url = await constants.getServerURL() + 'cancer_wiki'; console.warn(url); let result = fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: value}), mode: 'cors' }).then(response => response.json()) .then(response => { if (response.status == 200) { setLoadingWiki(false); setCancerWikiContent(response.content) setCancerWiki("") } else { setLoadingWiki(false) console.warn(response.message) setGeneWiki(response.message) } }); } }; const searchCancers = async() => { const url = await constants.getServerURL() + 'cancer_name'; console.warn(url); console.warn(cancerType); if (cancerType.length >= 3) { setLoadingCancers(true); let result = fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ cancer_type: cancerType}), mode: 'cors' }).then(response => response.json()) .then(response => { setOptions([]); optionsTemp = []; console.warn("GETTING CANCER RESPONSE") console.warn(response) if (response.status == 200) { setLoadingCancers(false); //setCancer = response.cancers console.warn("VALID CANCER RESPONSE") response.content.map( (cancer) => { optionsTemp.push(new Object({label:cancer.name , value: cancer.id})); }); console.warn(optionsTemp) setOptions(optionsTemp); } else { setLoadingCancers(false); console.warn("Error retrieving Cancer"); //setErrorMessage("Error Getting Cancers!"); //setErrorVisible(true); } }); } } const renderItem = ({ item, index }) => ( <TouchableOpacity onPress={() => handleChangeCancer(item.value,item.label)} style={[ styles.item, highlightedIndex === index && styles.itemSelected, ]} > <Text>{item.label}</Text> </TouchableOpacity> ); return ( <View style={styles.container}> <StatusBar style="auto" /> <View> <SearchBar style={styles.searchBar} placeholder="Search by Cancer Type" onChangeText={(cancerType) => setCancerType(cancerType)} value={cancerType} onKeyPress={searchCancers} /> {loadingCancers && <ActivityIndicator size="large" /> } <FlatList data={options} renderItem={renderItem} keyExtractor={item => item.value} style={styles.dropdown} /> </View> <View> <Text style={{ fontSize: 20 }}>Cancers</Text> </View> <ScrollView> <View style={styles.wikiView}> <Text>{cancerWikiContent}</Text> <Text>{cancerWiki}</Text> {loadingWiki && <SafeAreaProvider> <SafeAreaView style={[styles.loadingContainer, styles.loadingHorizontal]}> <ActivityIndicator size="large" /> </SafeAreaView> </SafeAreaProvider> } </View> </ScrollView> </View> ); } export { CancerHomepageWeb }; 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.