I am trying to implement an autocomplete component in react native. Everything works fine except for when I click outside the list still remains . onBlur() doesnt get triggered. I have Wrapped as suggested here by many but still it doesnt work.
Can someone please help me fix this ? Here is my code . Sorry for the long code.
import React, { Component } from "react"; import { FlatList, StyleSheet, Text, TextInput, View, TouchableOpacity, Keyboard, ScrollView, } from "react-native"; import { Icon } from "react-native-elements"; // import SearchIcon from "../assets/Map/Search.svg"; export default class AutoCompleteBasics extends Component { constructor(props) { super(props); this.state = { text: "", textInputFocus: false, arrayList: [ "Parcelle 1", "Parcelle 2", "Parcelle 3", "Parcelle 4", "Parcelle 5", ], }; } updateDataWithKey = () => { const { arrayList } = this.state; const dataWithKey = arrayList.map((data) => { return { key: data }; }); this.setState({ dataWithKey, filterData: dataWithKey, }); }; changeText = (text) => { this.setState({ text }); const { dataWithKey } = this.state; if (text !== "") { let filterData = dataWithKey.filter((obj) => { return obj.key.toLowerCase().indexOf(text.trim().toLowerCase()) > -1; }); if (filterData.length === 0) { filterData = [{ key: "No Filter Data" }]; } this.setState({ filterData }); } else { this.setState({ filterData: dataWithKey }); } }; hideKeyboard = () => { Keyboard.dismiss(); }; onListItemClicked = (text, index) => { const { onAutoCompleteClick } = this.props; onAutoCompleteClick(index); this.setState({ text, textInputFocus: false, filterData: [{ key: text }], }); this.handleInputBlur(); }; renderRow = (item, index) => { const { filterData } = this.state; return ( <TouchableOpacity onPress={() => { this.hideKeyboard(); this.onListItemClicked(item.key, index); }} > <Text style={styles.item}>{item.key}</Text> </TouchableOpacity> ); }; FlatListItemSeparator = () => { return ( <View style={{ height: 0.5, width: "100%", backgroundColor: "#2C2C2C", }} /> ); }; handleInputFocus = () => { this.setState({ textInputFocus: true }); }; handleInputBlur = () => { this.setState({ textInputFocus: false }); }; render = () => { const { filterData, textInputFocus } = this.state; console.log("=====>", textInputFocus); return ( <ScrollView keyboardShouldPersistTaps="handled" style={styles.container}> {/* <View> */} <View style={styles.innerContainer}> <TextInput style={styles.textInput} onFocus={() => this.handleInputFocus()} onBlur={() => this.handleInputBlur()} placeholder="Rechercher" placeholderTextColor="#d8d8d8" onChangeText={(text) => this.changeText(text)} value={this.state.text} onEndEditing={() => this.handleInputBlur()} /> {/* {!textInputFocus && ( <View style={{ left: -20 }}> <SearchIcon /> </View> )} */} </View> {textInputFocus && ( <FlatList ItemSeparatorComponent={this.FlatListItemSeparator} keyboardShouldPersistTaps="always" data={filterData} renderItem={({ item, index }) => this.renderRow(item, index)} style={{ borderBottomLeftRadius: 25, borderBottomRightRadius: 25, backgroundColor: "#F2F2F2", }} /> )} {/* </View> */} </ScrollView> ); }; } const styles = StyleSheet.create({ container: { flex: 1, position: "absolute", top: 80, zIndex: 1, width: "60%", borderRadius: 25, // backgroundColor: "rgba(29, 29, 27, 0.5)", borderWidth: 2, borderColor: "#fff", borderStyle: "solid", }, textInput: { color: "#F2F2F2", fontSize: 18, height: 40, width: "100%", marginTop: 8, }, innerContainer: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingLeft: 15, paddingRight: 15, }, item: { padding: 10, paddingLeft: 20, fontSize: 18, height: 44, borderRadius: 25, }, });
Advertisement
Answer
The issue is some styles in container
. Remove these from it:
position: "absolute", width: "60%", top: 80,
The top-level ScrollView should cover the screen, therefore keyboardShouldPersistTaps
work as expected. Right now, it is not possible to tap on ScrollView outside of the input & Flatlist.