How to get suggestions while typing in text-input in react-native

Viewed 9558

I want a text input box and it should show suggestions while typing, if there are no suggestions it should take the typed input, otherwise it should take input from the suggestion array. How can I achieve this? I have gone through few documents and modules react-native-autocomplete-input but could not understand the code. Can anyone help me out.

2 Answers

You can also build your own like below. This way you will have more control over the component and modify the behavior.

In this example I am using https://callstack.github.io/react-native-paper/text-input.html

// Autocomplete/index.js

import { View } from "react-native";
import { Menu, TextInput } from "react-native-paper";
import { bs } from "../../styles";
import React, { useState } from "react";

const Autocomplete = ({
  value: origValue,
  label,
  data,
  containerStyle,
  onChange: origOnChange,
  icon = 'bike',
  style = {},
  menuStyle = {},
  right = () => {},
  left = () => {},
}) => {
  const [value, setValue] = useState(origValue);
  const [menuVisible, setMenuVisible] = useState(false);
  const [filteredData, setFilteredData] = useState([]);

  const filterData = (text) => {
    return data.filter(
      (val) => val?.toLowerCase()?.indexOf(text?.toLowerCase()) > -1
    );
  };
  return (
    <View style={[containerStyle]}>
      <TextInput
        onFocus={() => {
          if (value.length === 0) {
            setMenuVisible(true);
          }
        }}
        // onBlur={() => setMenuVisible(false)}
        label={label}
        right={right}
        left={left}
        style={style}
        onChangeText={(text) => {
          origOnChange(text);
          if (text && text.length > 0) {
            setFilteredData(filterData(text));
          } else if (text && text.length === 0) {
            setFilteredData(data);
          }
          setMenuVisible(true);
          setValue(text);
        }}
        value={value}
      />
      {menuVisible && filteredData && (
        <View
          style={{
            flex: 1,
            backgroundColor: 'white',
            borderWidth: 2,
            flexDirection: 'column',
            borderColor: 'grey',
          }}
        >
          {filteredData.map((datum, i) => (
            <Menu.Item
              key={i}
              style={[{ width: '100%' }, bs.borderBottom, menuStyle]}
              icon={icon}
              onPress={() => {
                setValue(datum);
                setMenuVisible(false);
              }}
              title={datum}
            />
          ))}
        </View>
      )}
    </View>
  );
};

export default Autocomplete;

Usage


          <Autocomplete
            value={'Honda'}
            style={[style.input]}
            containerStyle={[bs.my2]}
            label="Model"
            data={['Honda', 'Yamaha', 'Suzuki', 'TVS']}
            menuStyle={{backgroundColor: 'white'}}
            onChange={() => {}}
          />
<Autocomplete
  autoCapitalize="none"
  autoCorrect={false}
  containerStyle={styles.autocompleteContainer}
  //data to show in suggestion
  data={films.length === 1 && comp(query, films[0].title) ? [] : films}
  //default value if you want to set something in input
  defaultValue={query}
  /*onchange of the text changing the state of the query which will trigger
  the findFilm method to show the suggestions*/
  onChangeText={text => this.setState({ query: text })}
  placeholder="Enter the film title"
  renderItem={({ item }) => (
    //you can change the view you want to show in suggestion from here
    <TouchableOpacity onPress={() => this.setState({ query: item.title })}>
      <Text style={styles.itemText}>
        {item.title} ({item.release_date})
      </Text>
    </TouchableOpacity>
  )}
/>

Got this from aboutreact.com, comments here explains what you want to pass to specific areas. I suggest trying to pass an array for the data prop.

Related