Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OnPress for React Native Google Places Autocomplete doesn't work due to its parent components

I'm trying to use the react-native-google-places-autocomplete library within my React Native app, but I'm having an issue clicking on the suggested list. Whenever I click on the Google suggested address, the list disappears and onPress doesn't grab the address. If I use the library in a component by itself without the parent components, it works perfectly fine, but only when I place the component within keyboardavoidingview or KeyboardAwareScrollView, it does not work:

This GooglePlacesInput.js component is just the standard library from the original repository:

       <GooglePlacesAutocomplete
            placeholder='Search'
            minLength={2} // minimum length of text to search
            autoFocus={false}
            returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
            keyboardAppearance={'light'} // Can be left out for default keyboardAppearance https://facebook.github.io/react-native/docs/textinput.html#keyboardappearance
            listViewDisplayed={false}   // true/false/undefined
            fetchDetails={true}
            renderDescription={row => row.description} // custom description render
            onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
                console.log(data, details);
            }}
            textInputProps={{
                onBlur,
            }}
            getDefaultValue={() => ''}

            query={{
                // available options: https://developers.google.com/places/web-service/autocomplete
                key: googleAPIKeyForAutocomplete,
                language: 'en', // language of the results
                region: "CA",
                // types: '(cities)' // default: 'geocode'
                types: '',
            }}

            styles={{
                listView: {
                    position: 'absolute',
                    top: 60,
                    left: 10,
                    right: 10,
                    backgroundColor: 'white',
                    borderRadius: 5,
                    flex: 1,
                    elevation: 3,
                    zIndex: 100,
                },
                textInputContainer: {
                    backgroundColor: 'transparent',
                    margin: 0,
                    width: '100%',
                    padding: 0,
                    borderTopWidth: 0,
                    borderBottomWidth: 0
                },
                textInput: {
                    backgroundColor: '#F9F5F4',
                    borderRadius: 50,
                    width: "100%",
                    height: height / 15,
                    padding: 20,
                },
                description: {
                    // color: '#ac879a',
                    fontWeight: '300'
                },
                predefinedPlacesDescription: {
                    color: '#1faadb'
                }
            }}

            currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
            currentLocationLabel="Current location"
            nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
            GoogleReverseGeocodingQuery={{
                // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
            }}
            GooglePlacesSearchQuery={{
                // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
                rankby: 'distance',
                type: 'food'
            }}

            GooglePlacesDetailsQuery={{
                // available options for GooglePlacesDetails API : https://developers.google.com/places/web-service/details
                fields: 'formatted_address',
            }}

            filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
            predefinedPlaces={[]}
            enablePoweredByContainer={false}
            debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
            renderLeftButton={() => { }}
            renderRightButton={() => { }}
        />

I'm using Formik for its parent component Form.js:

        <View style={styles.container} >
            <Formik
                initialValues={initialValues}
                onSubmit={(value, action) => submitHandler(value, action)}
                validationSchema={yup.object().shape({
                    address: yup
                        .string()
                        .min(5)
                        .required(),
                })}
            >
                {({
                    values,
                    handleChange,
                    errors,
                    setFieldTouched,
                    touched,
                    isValid,
                    handleSubmit,
                    resetForm,
                    isSubmitting,
                    }) => (
                        <View style={styles.form}>

                            <Animated.View
                                style={[styles.fieldset, addressStyle]}
                                onLayout={e => {
                                    if (addressHeight !== e.nativeEvent.layout.y) {
                                        setAddressHeight(e.nativeEvent.layout.y)
                                    }
                                }}
                            >
                                <Text style={{ marginLeft: 40, marginVertical: 5 }}>
                                    <Text style={{ color: '#FF5D4E' }}>* </Text>
                                    Address
                                    </Text>
                                <View style={styles.autoComplete}>
                                    <GooglePlacesInput
                                        onBlur={() => onBlurProps('address', setFieldTouched)}
                                    />
                                </View>
                            </Animated.View>
                            {touched.address && errors.address &&
                                <Animated.Text style={{ fontSize: 10, color: 'red' }}>{errors.address}</Animated.Text>
                            }
                            <TouchableOpacity
                                disabled={!isValid || loading || isSubmitting}
                                onPress={handleSubmit}
                                style={styles.button}
                            >
                                <Text style={styles.buttonText}>Submit</Text>
                            </TouchableOpacity>
                        </View>
                    )}
            </Formik>
        </View>

handleChange still has to be passed, but I want to first figure out the onPress situation first.

And finally, the most parent component:

        <KeyboardAwareScrollView>
            <SafeAreaView style={styles.container} >
                <ScrollView
                    keyboardShouldPersistTaps={'always'}
                    contentContainerStyle={styles.container}
                    style={{ flexGrow: 1 }}
                    showsVerticalScrollIndicator={false}
                    onLayout={e => {
                        if (heightPosition !== e.nativeEvent.layout.y) {
                            setHeightPosition(e.nativeEvent.layout.y)
                        }
                    }}
                >

                    <View style={styles.form}>
                        <Form
                            submitHandler={submitHandler}
                            loading={loading}
                            heightPosition={heightPosition}
                        />
                    </View>
                </ ScrollView>
            </SafeAreaView>
        </KeyboardAwareScrollView>
like image 322
Kevvv Avatar asked Dec 18 '19 04:12

Kevvv


2 Answers

Include this property keepResultsAfterBlur={true}.

like image 81
Maisum Abbas Avatar answered Oct 09 '22 21:10

Maisum Abbas


Please include keyboardShouldPersistTaps='always' in your parent ScrollView JSX

and listViewDisplayed={false} as per the documentation

like image 25
Rahul Shakya Avatar answered Oct 09 '22 21:10

Rahul Shakya