React-native-google-places-autocomplete: List items not clickable on the web

Created on 16 Oct 2020  路  19Comments  路  Source: FaridSafi/react-native-google-places-autocomplete

On expo 39 with web build.
List can't not be clickable, it's looks like blur is called and hide list before called.

Working fine with iOS and Android only issue with web

import * as React from 'react';
import { View, StyleSheet, TextInput } from 'react-native';
import Constants from 'expo-constants';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const GOOGLE_PLACES_API_KEY = ''; // never save your real api key in a snack!

const App = () => {
  return (
    <View style={styles.container}>
      <GooglePlacesAutocomplete
            placeholder="Search"
            onPress={(data, details = null) => {
                // 'details' is provided when fetchDetails = true
                console.log(data, details);
            }}
            requestUrl={{
                useOnPlatform: "web",
                url:
                    "https://cors-anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
            }}
            numberOfLines={3}
            query={{
                key: "",
                language: "en",
                components: "country:uk",
            }}
        />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 10,
    paddingTop: Constants.statusBarHeight + 10,
    backgroundColor: '#ecf0f1',
  },
});

export default App;

  ```

</details>


# Additional context


{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject"
},
"dependencies": {
"expo": "^39.0.0",
"react": "16.13.1",
"react-dom": "16.13.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-39.0.3.tar.gz",
"react-native-web": "~0.13.7",
"react-native-google-places-autocomplete": "^2.0.2"
},
"devDependencies": {
"babel-preset-expo": "^8.3.0",
"@babel/core": "^7.8.6"
},
"private": true
}
```

  • [ ] iOS
  • [ ] Android
  • [x] Web

If you are using expo please indicate here:

  • [x] I am using expo

Add any other context about the problem here, screenshots etc

bug help wanted

Most helpful comment

@ksi9302 thank you Peter, I was having the same issue. iOS and Android.

All 19 comments

I can reproduce this, and the issue is almost certainly here:

https://github.com/FaridSafi/react-native-google-places-autocomplete/blob/7f1c05a7a052db58ca3b7f96fbe326c04f69858c/GooglePlacesAutocomplete.js#L783.

We may have to revert #506, which is when this was added.

If someone wants to put in a PR, feel free. Otherwise, I will try and take a stab at it next week.

Hi, just wondering if there's a work around at the moment before the update?

Hi, just wondering if there's a work around at the moment before the update?

For anyone wanting a quick fix for web, just comment the line 895 ~ 902.

onBlur={ onBlur ? () => { this._onBlur(); onBlur(); } : this._onBlur }

@ksi9302 thank you Peter, I was having the same issue. iOS and Android.

For version 1.9.0 a fix that I found is to modify the _onBlur as below:

  _onBlur = () => {
    this.triggerBlur();

    this.setState(()=>{ listViewDisplayed: false }); // <-- using a callback here fixes the issue because the list will be 
      // hidden only after input state values are saved
  };

For latest version which is using hooks I haven't found a solution yet.

@bell-steven Please let me know if the solution is good enough for the moment and if 1.9.1 could be released....

For version 2.0.3 the only workaround that I found is to delay hiding the list at onBlur:

  const _onBlur = () => {
    setTimeout(()=>{
      setListViewDisplayed((_prev)=>false);
    }, 200);
    inputRef?.current?.blur();
  };

The problem with the workaround recommended by @ksi9302 is that the list is not hidden when tapping/clicking outside of it...

For version 1.9.0 a fix that I found is to modify the _onBlur as below:

  _onBlur = () => {
    this.triggerBlur();

    this.setState(()=>{ listViewDisplayed: false }); // <-- using a callback here fixes the issue because the list will be 
      // hidden only after input state values are saved
  };

For latest version which is using hooks I haven't found a solution yet.

@bell-steven Please let me know if the solution is good enough for the moment and if 1.9.1 could be released....

For version 2.0.3 the only workaround that I found is to delay hiding the list at onBlur:

  const _onBlur = () => {
    setTimeout(()=>{
      setListViewDisplayed((_prev)=>false);
    }, 200);
    inputRef?.current?.blur();
  };

The problem with the workaround recommended by @ksi9302 is that the list is not hidden when tapping/clicking outside of it...

thanks buddy

@dhru @ksi9302 @fdobre @manny1001 can you test #649 and report back if it solves the issue?

npm i [email protected]

@bell-steven tested 2.1.0-RC.0 on Web and iOS using RN 0.63.3:

Results:

  • for web onPress event on list item is not triggered (probably because blur event is still triggered too early)
  • for iOS tapping outside the list does not hide the list.

[email protected] doesn't solve this issue.

@bell-steven why is this closed? it is still a major issue on web and iOS.

@fdobre this was closed automatically by GitHub when the PR was merged.

it is still a major issue on web and iOS.

I don't think tapping outside the list on iOS/Android ever closed the input.

This library is built for React Native, and is primarily used for React Native, see #525 for a more in-depth discussion about this - and how it relates to this library.

This is an issue for those who are using this with latest version of react-native-web (I believe it works on older versions). PR's are always welcome, and are normally reviewed within a day or 2.

@fdobre this was closed automatically by GitHub when the PR was merged.

it is still a major issue on web and iOS.

I don't think tapping outside the list on iOS/Android ever closed the input.

This library is built for React Native, and is primarily used for React Native, see #525 for a more in-depth discussion about this - and how it relates to this library.

This is an issue for those who are using this with latest version of react-native-web (I believe it works on older versions). PR's are always welcome, and are normally reviewed within a day or 2.

@bell-steven thank you for the fast response!

As I mentioned above, the only workaround that I found until now that fixes both issues (web onPress problem and the iOS dismiss list when tapping outside of it) is to delay hiding the list:

  const _onBlur = () => {
    setTimeout(()=>{
      setListViewDisplayed(false);
    }, 200);
    inputRef?.current?.blur();
  };
  };

If you consider this is good enough I will create a PR.

I will take a closer look early next week and see if I can find something better.

In terms of this particular solution, see https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/478#issuecomment-725462734. I appreciate your taking the time to look into this.

I have the same problem on IOS, GooglePlacesAutocompleteis inside the ScrollView, and when I'm clicking on any item, it closes the list immediately, without invokingonPress() method. Is there any workaround for v. 2.1.1 ?

`react-native: "~0.63.3",`
 "react-native-google-places-autocomplete": "^2.1.1",

Hi, just wondering if there's a work around at the moment before the update?

For anyone wanting a quick fix for web, just comment the line 895 ~ 902.

onBlur={ onBlur ? () => { this._onBlur(); onBlur(); } : this._onBlur }

This worked for me (line 787). I used patch-package to remove it.

For anyone interested, this is my patch:

patches/react-native-google-places-autocomplete+2.1.1.patch

diff --git a/node_modules/react-native-google-places-autocomplete/GooglePlacesAutocomplete.js b/node_modules/react-native-google-places-autocomplete/GooglePlacesAutocomplete.js
index abac368..04e1dbf 100644
--- a/node_modules/react-native-google-places-autocomplete/GooglePlacesAutocomplete.js
+++ b/node_modules/react-native-google-places-autocomplete/GooglePlacesAutocomplete.js
@@ -784,14 +784,14 @@ export const GooglePlacesAutocomplete = forwardRef((props, ref) => {
                   }
                 : _onFocus
             }
-            onBlur={
-              onBlur
-                ? () => {
-                    _onBlur();
-                    onBlur();
-                  }
-                : _onBlur
-            }
+            // onBlur={
+            //   onBlur
+            //     ? () => {
+            //         _onBlur();
+            //         onBlur();
+            //       }
+            //     : _onBlur
+            // }
             clearButtonMode={clearButtonMode || 'while-editing'}
             onChangeText={_handleChangeText}
             {...userProps}

Sorry to send 2 messages, but it actually doesn't solve the problem, since blurring the input no longer hides the dropdown. Does anyone have a solution that 1) enables pressing list items on web, and 2) still hides the dropdown when the input blurs?

For now, I'll stick to @fdobre's workaround. Thanks!

@bell-steven
Since pressing the list items are calling _onBlur in the _onPress function then we could trigger a blur only if the related target does not belong to the list with address items.

So another cleaner solution could be:

1) Attach an ID to the FlatList with results:

<FlatList
          nativeID="react-native-google-places-autocomplete-result-list-id" //<-- add an ID like this
          scrollEnabled={!props.disableScroll}
          style={[
            props.suppressDefaultStyles ? {} : defaultStyles.listView,
            props.styles.listView,
          ]}

2) Call the onBlur only if the tap or click is not inside the list with results:

  const isNewFocusInAutocompleteResultList = ({ relatedTarget, currentTarget }) => {
    if (!relatedTarget) return false;

    var node = relatedTarget.parentNode;

    while (node) {
      if (node.id === 'react-native-google-places-autocomplete-result-list-id') return true;
      node = node.parentNode;
    }

    return false;
  }

  const _onBlur = (e) => {
    if (e && isNewFocusInAutocompleteResultList(e)) return;

    setListViewDisplayed(false);
    inputRef?.current?.blur();
  };


   onBlur={
       onBlur
         ? (e) => {.   // <-- attach the event when calling the _onBlur  
         _onBlur(e); //<--

Tested in web, android and iOS => onPress works and also tapping/clicking outside the list will hide the list.

Please provide feedback if this is good enough.

Hi there, I'm coming back to this project, however, I'm still having this issue with version ^2.2.0 :(

Was this page helpful?
0 / 5 - 0 ratings

Related issues

quandevelopment picture quandevelopment  路  4Comments

biks152207 picture biks152207  路  4Comments

miguel-pm picture miguel-pm  路  3Comments

mbelgrader picture mbelgrader  路  4Comments

akhlopyk picture akhlopyk  路  3Comments