Make a dropdown list to select in TextInput

578 views Asked by At

Im using react-native-paper which is a great library, but i ran into a problem when i needed a dropdown menu, that is overlay on the TextInput field around it. Don't want to use any Library unless it it maintained properly.

  return (
    <View style={{ top: StatusBar.currentHeight }}>
      <View
        style={{
          flexDirection: 'row',
          justifyContent: 'space-around',
          marginVertical: 10,
        }}>
        <TextInput
          label={'Title'}
          placeholder={'Mr'}
          value={userinput}
          style={{ width: '30%' }}
          onChangeText={(text) => setUserinput(text)}
          right={<TextInput.Icon icon="chevron-down" size={20} />}
        />
        <TextInput label={'First name'} style={{ width: '60%' }} />
      </View>
      <View style={{ alignSelf: 'center', width: '95%' }}>
        <TextInput
          label={'Phone number'}
          onChangeText={(text) => setUserinput(text)}
        />
      </View>
    </View>
  );

Currently screenshot of the current state. Required: Required

Bare minimum Expo Snack code.

Already tried

  1. Although react-native-paper provides List & List.Accordion but my problem is not solving by that. issue When list is open the other text bot field are also extending there height.

  2. Mapping function, Flatlist, issue not getting the results that i want.

  3. Position: Absolute issue Mapping is not working accordingly.

1

There are 1 answers

1
Shivo'ham On BEST ANSWER

I did it using flatlist with zIndex properties, check my example code

Example:

import React, { useState, useCallback } from 'react';
import { View, StatusBar, FlatList, TouchableOpacity, Text, Keyboard } from 'react-native';
import { TextInput } from 'react-native-paper';
    
    const App = () => {
      const [userinput, setUserinput] = useState(null);
      const [show, setShow] = useState(false);
      const openPicker = useCallback(
        () => {
          Keyboard.dismiss()
          setShow(true)
        },
        [show]
      );
    
      const hidePicker = useCallback(
        (item) => {
          setShow(false)
          setUserinput(item)
        },
        [show, userinput]
      );
    
      return (
        <View style={{ top: StatusBar.currentHeight }}>
          <View
            style={{
              flexDirection: 'row',
              justifyContent: 'space-around',
              marginVertical: 10,
            }}>
            <View style={{ width: '30%' }}>
              <TextInput
                label={'Title'}
                placeholder={show ?'' :'Mr'}
                value={userinput}
                style={{ width: '100%' }}
                onChangeText={(text) => setUserinput(text)}
    
                right={<TextInput.Icon onPress={openPicker} icon="chevron-down" size={20} />}
              />
              {show ?
                <FlatList
                  style={{ backgroundColor: 'rgb(211, 211, 211)',elevation:1, zIndex: 22, width: '100%', marginTop: 60, position: 'absolute' }}
                  data={['Mr', 'Mrs', 'Miss']}
                  renderItem={({ item, index }) => (
                    <TouchableOpacity
                      onPress={() => hidePicker(item)}>
                      <Text style={{padding:8}}>
                        {item}
                      </Text>
                    </TouchableOpacity>
                  )}
                  keyExtractor={item => item}
                />
                : null}
            </View>
            <TextInput label={'First name'} style={{ width: '60%' }} />
          </View>
          <View style={{ alignSelf: 'center', width: '95%', zIndex: -1 }}>
            <TextInput
              label={'Phone number'}
              onChangeText={(text) => setUserinput(text)}
            />
          </View>
        </View>
      );
    };
    
    export default App;

Note: marginTop will be the same as input height and you can also move the flatlist to components