I want to create a searchable flatlist for skills using the JSON data provided below:
const employeeList = [
{
id: "1",
name: "John",
image: require("../images/John.png"),
skills: [
{ id: 1, name: "Cooking" },
{ id: 2, name: "Climbing" },
],
},
{
id: "2",
name: "Pat",
image: require("../images/Pat.png"),
skills: [
{ id: 1, name: "Cooking" },
{ id: 2, name: "Rowing" },
],
},
];
export default employeeList;
I have managed to display all employees and their skills but my search feature currently filters only by employee names. I would like to enhance it to search for skills as well and show the employee associated with that skill.
// Search Bar Filter Functionality in React Native FlatList
// Source: https://aboutreact.com/react-native-search-bar-filter-on-listview/
// Import necessary components
import React, { useState, useEffect } from "react";
import {
SafeAreaView,
Text,
StyleSheet,
View,
FlatList,
TextInput,
Image,
TouchableOpacity,
} from "react-native";
// Import the employee JSON data
import employeeList from "../json/employee";
const AllListScreen = ({ navigation, route }) => {
const [search, setSearch] = useState("");
const [filteredDataSource, setFilteredDataSource] = useState([]);
const [masterDataSource, setMasterDataSource] = useState([]);
// Populate the initial data sources with employee list
useEffect(() => {
setFilteredDataSource(employeeList);
setMasterDataSource(employeeList);
console.log(JSON.stringify(employeeList[0].skills)); // Display skills
}, []);
// Function to filter based on search text
const searchFilterFunction = (text) => {
if (text) {
const newData = masterDataSource.filter(function (item) {
const itemData = item.name ? item.name.toUpperCase() : "".toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setFilteredDataSource(newData);
setSearch(text);
} else {
setFilteredDataSource(masterDataSource);
setSearch(text);
}
};
// Component to render each item in the FlatList
const ItemView = ({ item, index }) => {
return (
<View>
{item.skills.map((v, i) => (
<>
<TouchableOpacity
onPress={() => console.log(v.name)}
style={styles.itemStyle}
key={item.id}
>
<Image
source={{ uri: "https://source.unsplash.com/random" }}
style={{ height: 50, width: 50 }}
/>
<View style={styles.textPortion}>
<Text>{item.name}</Text>
<Text>{v.name.toUpperCase()}</Text>
</View>
</TouchableOpacity>
<ItemSeparatorView />
</>
))}
</View>
);
};
// Component to render separator between items
const ItemSeparatorView = () => {
return (
<View
style={{
height: 0.5,
width: "100%",
backgroundColor: "#C8C8C8",
}}
/>
);
};
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<TextInput
style={styles.textInputStyle}
onChangeText={(text) => searchFilterFunction(text)}
value={search}
underlineColorAndroid="transparent"
placeholder="Search Here"
/>
<FlatList
data={filteredDataSource}
keyExtractor={(item, index) => index.toString()}
renderItem={ItemView}
/>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: "#FFFFFF",
},
itemStyle: {
flex: 1,
padding: 8,
flexDirection: "row",
},
textInputStyle: {
height: 50,
borderWidth: 1,
paddingLeft: 20,
margin: 6,
borderColor: "#009688",
backgroundColor: "#FFFFFF",
borderRadius: 5,
},
textPortion: {
flexWrap: "wrap",
flexShrink: 1,
marginLeft: 6,
},
});
export default AllListScreen;
You can view the current display of the app here. Any assistance on improving the search functionality for skills is greatly appreciated. Thank you.