hoaphantn7604 / react-native-element-dropdown

A react-native dropdown component easy to customize for both iOS and Android.
MIT License
959 stars 166 forks source link

Does it support autocomplete #262

Open vricosti opened 5 months ago

vricosti commented 5 months ago

Hi, Wanted to know if it supports autocomplete feature ? I mean every time I enter some text it should call an api and fill the dropdown accordingly (same behavior as react-native-autocomplete-dropdown.

And very bad idea to put example inside the README, first time I see this, generally we put an example or 2 but not that much because we have to scroll so much. I mean if you want an example you look at example folder ...

vricosti commented 5 months ago

Ok I have tested this and it seems to work:

import React, { useRef, useState, useCallback } from 'react';
import { Button, StyleSheet, View } from 'react-native';
import { Dropdown, IDropdownRef } from 'react-native-element-dropdown';

type AutocompleteDropdownItem = {
  label: string;
  value: string;
};

const DropdownComponent = () => {
  const [value, setValue] = useState<string>();
  const [remoteDataSet, setRemoteDataSet] = useState<AutocompleteDropdownItem[]>([]);
  const ref = useRef<IDropdownRef>(null);

  /**
   * Simulates fetching brands from a backend that match a given prefix.
   * 
   * @param prefix The prefix to filter brands by.
   * @returns A promise that resolves with the filtered brands.
   */
  const ALL_BRANDS: string[] = [
    'SAMSUNG',
    'SONOS',
    'SONY',
    'SHARP',
  ];
  function simulateFetch(prefix: string): Promise<string[]> {
    return new Promise(resolve => {
      // Use setTimeout to simulate network delay
      setTimeout(() => {
        const filteredBrands = ALL_BRANDS.filter(brand =>
          brand.toUpperCase().startsWith(prefix.toUpperCase())
        );
        resolve(filteredBrands);
      }, 200); // Simulate a delay of 200 milliseconds
    });
  }

  const getSuggestions = useCallback(async (q: string) => {
    const filterToken = q.toLowerCase()
    console.log('getSuggestions', filterToken)
    if (typeof q !== 'string' || q.length < 2) {
      console.log(`q: '${q}'`);
      console.log(' setRemoteDataSet(null)');
      setRemoteDataSet([]);
      return
    }
    //setLoading(true)
    const brands = await simulateFetch(q) as string[];
    const suggestions = brands.map((brand, index) => ({
        value: index.toString(),
        label: brand,
      }));

    setRemoteDataSet(suggestions)
    //setLoading(false)
  }, [])

  return (
    <View style={styles.row}>
      <Dropdown
        ref={ref}
        style={styles.dropdown}
        placeholderStyle={styles.placeholderStyle}
        selectedTextStyle={styles.selectedTextStyle}
        inputSearchStyle={styles.inputSearchStyle}
        iconStyle={styles.iconStyle}
        data={remoteDataSet}
        search
        maxHeight={300}
        labelField="label"
        valueField="value"
        placeholder="Dropdown 2"
        searchPlaceholder="Search..."
        value={value}
        onChange={(item) => {
          console.log('onChange: ', item);
          setValue(item.value);
        }}
        onChangeText={(search) => {
          console.log('onChangeText: ', search);
          if (search.length) {
            getSuggestions(search);
          }
        }} // Keep search keyword
      />
      <View style={styles.button}>
        <Button
          title="Open"
          onPress={() => {
            ref.current?.open();
          }}
        />
      </View>
    </View>
  );
};

export default DropdownComponent;

const styles = StyleSheet.create({
  row: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  dropdown: {
    flex: 1,
    margin: 16,
    height: 50,
    borderBottomColor: 'gray',
    borderBottomWidth: 0.5,
  },
  placeholderStyle: {
    fontSize: 16,
  },
  selectedTextStyle: {
    fontSize: 16,
  },
  iconStyle: {
    width: 20,
    height: 20,
  },
  inputSearchStyle: {
    height: 40,
    fontSize: 16,
  },
  button: {
    marginHorizontal: 16,
  },
});

So I give you one more example to add ;-)