I am using react-native-google-places-autocomplete to get places suggestions based on user's current location. And it is working fine but the only issue I am facing is that whenever the 'Current Location' button is clicked, it sets the input field with value 'Current Location' and then shows the location results in the form of the list below it.
I don't want it to set currentLocationLabel value in the input field.
Here's my Code:
import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
navigator.geolocation = require('#react-native-community/geolocation');
const LocationAutocompleteScreen = props => {
return (
<GooglePlacesAutocomplete
placeholder='Search Location...'
minLength={3}
autoFocus={true}
returnKeyType={'search'}
listViewDisplayed='auto'
fetchDetails={true}
onPress={(data, details = null) => {
const locParam = {
description: data.description,
placeId: data.place_id,
location: details.geometry.location
}
props.navigation.navigate('LocationSearch', {locParam} )
}}
getDefaultValue={() => {
return '' // text input default value
}}
query={{
key: 'API_KEY',
language: 'en',
components: 'country:in',
}}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
marginTop: 16,
marginHorizontal: 16
},
textInput: {
marginLeft: 0,
marginRight: 0,
padding: 8,
minHeight: 30,
color: '#000000',
fontSize: 16,
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
paddingHorizontal: 8
},
description: {
fontWeight: '700',
letterSpacing: 0.5,
color: '#5d5d5d'
}
}}
currentLocation={true}
currentLocationLabel='Current Location'
nearbyPlacesAPI='GoogleReverseGeocoding' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
//renderDescription={row => row.description || row.formatted_address || row.name}
// 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',
// types: 'food'
// }}
//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
/>
);
}
export default LocationAutocompleteScreen;
Related
I want year to be displayed on selection from dropdown list.
In this, selected item is being shown as alert I want to set text to the search box.
Here is the code:
import React, { useState, useEffect } from "react";
import {
StyleSheet,
SafeAreaView,
Text,
View,
TextInput,
Image,
Button,
FlatList,
TouchableOpacity,
} from "react-native";
import SearchableDropdown from "react-native-searchable-dropdown";
const years = [
{ id: 1, name: "2021" },
{ id: 2, name: "2020" },
{ id: 3, name: "2019" },
{ id: 4, name: "2018" },
{ id: 5, name: "2017" },
{ id: 6, name: "2016" },
{ id: 7, name: "2015" },
];
export default function Year() {
console.log("App Executed");
return (
<SafeAreaView>
<Text style={styles.headingText}>Select Year</Text>
<SearchableDropdown
onTextChange={(text) => console.log(text)}
// On text change listner on the searchable input
onItemSelect={(year) => alert(JSON.stringify(year))}
// onItemSelect called after the selection from the dropdown
containerStyle={{ padding: 5 }}
// suggestion container style
textInputStyle={{
// inserted text style
padding: 12,
borderWidth: 1,
borderColor: "#ccc",
backgroundColor: "#FAF7F6",
}}
itemStyle={{
// single dropdown item style
padding: 10,
marginTop: 2,
backgroundColor: "#FAF9F8",
borderColor: "#bbb",
borderWidth: 1,
}}
itemTextStyle={{
// text style of a single dropdown item
color: "#222",
}}
itemsContainerStyle={{
// items container style you can pass maxHeight
// to restrict the items dropdown hieght
maxHeight: "50%",
}}
items={years}
// mapping of item array
defaultIndex={"eg:2021"}
// default selected item index
placeholder="eg:2021"
// place holder for the search input
resetValue={false}
// reset textInput Value with true and false state
/>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "white",
padding: 10,
},
titleText: {
padding: 8,
fontSize: 16,
textAlign: "center",
fontWeight: "bold",
},
headingText: {
padding: 10,
},
});
I was unable to use state
here is the solution
const years = [
{ id: 1, name: "2021" },
{ id: 2, name: "2020" },
{ id: 3, name: "2019" },
{ id: 4, name: "2018" },
{ id: 5, name: "2017" },
{ id: 6, name: "2016" },
{ id: 7, name: "2015" },
];
export default function Year() {
const [selectedItems, setSelectedItems] = useState();
console.log("App Executed");
return (
<SafeAreaView>
<SearchableDropdown
onTextChange={(text) => console.log(text)}
// On text change listner on the searchable input
selectedItems={selectedItems}
onItemSelect={(year) => setSelectedItems(year)}
// onItemSelect called after the selection from the dropdown
containerStyle={{ padding: 5 }}
// suggestion container style
textInputStyle={{
// inserted text style
padding: 12,
borderWidth: 1,
borderColor: "#ccc",
backgroundColor: "#FAF7F6",
}}
itemStyle={{
// single dropdown item style
padding: 10,
marginTop: 2,
backgroundColor: "#FAF9F8",
borderColor: "#bbb",
borderWidth: 1,
}}
itemTextStyle={{
// text style of a single dropdown item
color: "#222",
}}
itemsContainerStyle={{
// items container style you can pass maxHeight
// to restrict the items dropdown hieght
maxHeight: "50%",
}}
items={years}
// mapping of item array
defaultIndex={"eg:2021"}
// default selected item index
placeholder="eg:2021"
// place holder for the search input
resetValue={false}
// reset textInput Value with true and false state
/>
</SafeAreaView>
);
}
I SLOVED THAT BY THIS TRICK WAY:
const getTypeNameById_func = async id => {
const dataa = await accountsType.find(item => {
if (item.ID == id)
return item.NAME;
});
setTextSearchable(dataa.NAME);
};
AND IN SEARCHABLE DROPDOWN :
<SearchableDropdown
items={filterData}
placeholder={String(**textSearchable**)}
resetValue={false}
underlineColorAndroid="transparent"
onTextChange={text => console.log(text)}
onItemSelect={item => {
getTypeNameById_func(item.id);
setAccountType(item.id);
}}
defaultIndex={1}
/>
u can use useState variable and pass that variable in placeholder like:-
placeholder={variableName}
I have dataset, which looks like this:
var items = [
{
id: 1,
name: 'foo',
email: 'foo'
},
{
id: 2,
name: 'foo',
email: 'foo'
},
{
id: 3,
name: 'foo',
email: 'foo'
},
];
module.exports = items;
I'm feeding this data to searchable dropdown, so the data will be visible within the dropdown
The dropdown component, looks like this:
<SearchableDropdown
onItemSelect={(item) => {
const items = this.state.selectedItems;
items.push(item)
this.setState({ selectedItems: items });
}}
containerStyle={{ padding: 5 }}
onRemoveItem={(item, index) => {
const items = this.state.selectedItems.filter((sitem) => sitem.id !== item.id);
this.setState({ selectedItems: items });
}}
itemStyle={{
padding: 10,
marginTop: 2,
backgroundColor: '#ddd',
borderColor: '#bbb',
borderWidth: 1,
borderRadius: 5,
}}
itemTextStyle={{ color: '#222' }}
itemsContainerStyle={{ maxHeight: 140 }}
items={items}
defaultIndex={null}
resetValue={false}
textInputProps={
{
placeholder: "Choose priority level",
underlineColorAndroid: "transparent",
style: {
padding: 12,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 5,
},
onTextChange: text => console.log(text)
}
}
listProps={
{
nestedScrollEnabled: false,
}
}
/>
</Fragment>
And I imported the dataset with the following import:
import items from '../components/items';
However I'm getting that element type is invalid excepted a string but got object, I've tried previous threads from stackoverflow however nothing seems to solve my problem. Perhaps I'm missing something small that my eyes can't pick up? Any help appreciated.
First, you have to export the array as variable like
items.js
export const items = [
...
...
]
import it into your component.js like as
import {items} from '../path/to/items';
Just for confirmation log it inside your render method
console.log('Array Items', item);
Hope this will help you.
I am using react-native-radio-button to implement a flatlist with radio button as shown in the image.
[![enter image description here][1]][1]
But i am unable to select a single radio button at a time in flatlist.
Here is my code
import React from 'react';
import { StyleSheet, View, Text, FlatList, TouchableOpacity, Image, LayoutAnimation, UIManager, Platform } from 'react-native';
import RadioButton from 'react-native-radio-button';
import PHARMACY from './api/mockPharmacyList';
import { Colors, Fonts } from '../../styles';
interface IState {
selected: number;
selectedIndex: number;
data: any;
expanded: boolean;
checked: boolean;
}
export class TransferToPharmacy extends React.Component<{}, IState> {
constructor(props) {
super(props);
this.state = {
data: PHARMACY,
selected: 0,
selectedIndex: 0,
expanded: true,
checked: false,
};
this.onPress = this.onPress.bind(this);
this.renderItem = this.renderItem.bind(this);
this.renderSeparator = this.renderSeparator.bind(this);
this._keyExtractor = this._keyExtractor.bind(this);
this.changeLayout = this.changeLayout.bind(this);
this.onCheck = this.onCheck.bind(this);
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
changeLayout = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({ expanded: false });
}
getInitialState() {
return {
value: 0,
};
}
onPress(value) {
this.setState({ selected: value });
}
_keyExtractor = (item, index) => item.id;
onCheck = () => {
const { checked } = this.state;
if (checked === true) {
this.setState({ checked: false });
} else {
this.setState({ checked: true });
}
}
renderItem(data) {
const { item } = data;
return (
<View style={styles.itemBlock}>
<TouchableOpacity >
<View style={styles.arrowIconStyle}>
<Text style={styles.pharmacyText}>{item.name}</Text>
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selectedIndex === 0}
onPress={this.onPress}
/>
</View>
</TouchableOpacity>
<Text>{item.key1}</Text>
<View style={{ height: this.state.expanded === true ? 90 : 0, overflow: 'hidden' }}>
<View style={{ flexDirection: 'row', marginTop: 5, padding: 10 }}>
<Image style={[styles.itemImage, { width: 15, height: 15, margin: 1 }]} source={require('./images/map_pic_icon.png')} />
<Text style={styles.itemText}>{item.location}</Text>
</View>
<View style={{ flexDirection: 'row', marginTop: 5, padding: 10 }}>
<Image style={[styles.itemImage, { width: 15, height: 15, margin: 1 }]} source={require('./images/phone_icon.png')} />
<Text style={styles.itemText}>{item.phone}</Text>
</View>
</View>
</View>
);
}
renderSeparator() {
return <View style={styles.separator} />;
}
render() {
return (
<View style={styles.container} >
<Text style={styles.textStyle}>Transfer to Pharmacy</Text>
<View style={styles.childViewStyle}>
<FlatList
keyExtractor={this._keyExtractor}
data={this.state.data}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
textStyle: {
fontSize: 18,
color: Colors.black,
marginTop: 30,
marginLeft: 20
},
childViewStyle: {
margin: 20,
},
itemBlock: {
paddingVertical: 15,
},
itemImage: {
width: 50,
height: 50,
borderRadius: 25,
margin: 10
},
itemText: {
fontSize: 16,
justifyContent: 'center',
color: Colors.darkySkyBlue
},
itemName: {
fontSize: 20,
color: Colors.black,
},
separator: {
borderRadius: 4,
borderWidth: 1,
borderColor: Colors.lightGray,
},
pharmacyText: {
fontSize: 16,
fontFamily: Fonts.bold,
color: Colors.black
},
radioStyle: {
marginTop: 10,
marginRight: 50,
justifyContent: 'space-between'
},
arrowIconStyle: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10
// flex: 1
}
});
with this code i am not able to select the radio button
Please let me know where it is going wrong as i am unable to select radio button in the flatlist separately.
i have changed onPress() like this
onPress( index) {
this.setState({ selected: index, });
}
and in renderItem method i have changed it like this
const { item, index } = data;
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selected === index}
onPress={() => this.onPress(index)}
/>
Now the output is like this
Now the first radio button is selected but when i tried to select other radio buttons they are not getting selected.
Here is my mock data file which is used for Flatlist.
export const PHARMACY = [
{
key: 0,
name: 'Plaza Pharmacy',
type: 'Urgent Care Center - 4.01 mi',
location: '3417 Gaston Avenue, Suite 195\n Dallas, TX 75202',
phone: '469.764.7100',
},
{
key: 1,
name: 'Courtyard Pharmacy',
type: 'Urgent Care Center - 4.09 mi',
location: '5236 West University Drive, Suite 1900\n MCKINNEY, TX 75071',
phone: '969.264.7190',
},
{
key: 2,
name: 'Outptaient Pharmacy at the Cancer Center',
type: 'Urgent Care Center - 4.66 mi',
location: '3800 Gaylord Parkway, Ste 110\n FRISCO, TX 75034',
phone: '890.664.8130',
},
{
key: 3,
name: 'Carrolton Pharmacy',
type: 'Urgent Care Center - 4.08 mi',
location: '5236 West University Drive, Suite 1900\n MCKINNEY, TX 75071',
phone: '969.264.7190',
},
{
key: 4,
name: 'Garland Pharmacy',
type: 'Urgent Care Center - 22.11 mi',
location: '3417 Gaston Avenue, Suite 195\n Dallas, TX 75202',
phone: '469.764.7100',
},
];
I am exporting this const PHARMACY and importing it in my class and set this to a state variable "data".
you can do something like this in renderItem
renderItem = ({item, index}) => {
.....
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selectedIndex === index}
onPress={() => {this.onPress(index)}}
/>
}
and replace onPress with
onPress = (index) => {
this.setState({ selectedIndex: index });
}
and update FlatList with extraData props as FlatList needs to be re-rendered as
<FlatList
keyExtractor={this._keyExtractor}
data={this.state.data}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
extraData={this.state}
/>
You can refer in snack here
First, you need to get the index of the current item like so:
const { item, index } = data;
After you get the index of the current item you can then check if the current radio button is selected or not and for changing the radio button you need to pass the value of the current index to the onPress function.
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selected === index}
onPress={() => this.onPress(index)}
/>
When the current location is selected, the api gets the locations but the list seems to be not populating/displaying the places.
But when selected it does reverse geocode and print the details in the console.
However it does not get set to the textInput.
Not sure what I am missing
This is how the screen looks like
The code look like this
<GooglePlacesAutocomplete
placeholder='Deliver To'
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
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description || row.vicinity} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: '',
language: 'en', // language of the results
types: 'geocode', // default: 'geocode'
components: 'country:au',
}}
styles={{
textInputContainer: {
width: '100%',
backgroundColor: 'rgba(0,0,0,0)',
borderLeftWidth: 0.5,
borderRightWidth: 0.5,
},
textInput: {
fontFamily: "AvenirMedium",
fontSize: 17,
color: "#000",
backgroundColor: 'rgba(0,0,0,0)',
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI={'GoogleReverseGeocoding'} // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
key: '',
language: 'en',
}}
/>
1. Just add textInputProps={{ onBlur: () => {} }} in <GooglePlacesAutocomplete />
Ex.
2. comment // renderDescription={(row) => row.description}
`<View>
<ScrollView keyboardShouldPersistTaps="handled">
<View keyboardShouldPersistTaps="handled" >
<GooglePlacesAutocomplete
currentLocation={true}
placeholder='Enter your location'
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='true' // true/false/undefined
fetchDetails={true}
//renderDescription={row => row.description || row.formatted_address || row.name}
// renderDescription={(row) => row.description} // custom description render
//components='country:ind'
onPress={(data, details = null) => {
//let address = details.formatted_address.split(', ');
console.log("DATAA", data);
console.log("details", details.name + ", " + details.formatted_address);
if (data && details) {
this.setState({
disLocation: data.description ? data.description : details.name + ", " + details.formatted_address,
lat: details.geometry.location.lat ? details.geometry.location.lat : data.geometry.location.lat,
lng: details.geometry.location.lng ? details.geometry.location.lng : data.geometry.location.lng
})
}
}}
nearbyPlacesAPI='GooglePlacesSearch'
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
// type: 'cafe'
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaSyCK9195rpO4FJm0UvXImv28Dek6iEBHI4k',
//language: 'fr', // language of the results
//types: 'address', // default: 'geocode'
// components: 'country:ca' // added manually
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
textInputProps={{ onBlur: () => {} }}
//GooglePlacesDetailsQuery={{ fields: 'formatted_address' }}
GooglePlacesDetailsQuery={{ fields: ['geometry', 'formatted_address'] }}
debounce={300} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
/>
</View>
</ScrollView>
</View>`
`https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/496#issuecomment-606272340`
I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it as a props to be passed to another function. The value should be of type String. I do not how to extract the selected description value.
Here is what I have so far:
<GooglePlacesAutocomplete
placeholder='Event Location'
minLength={2} // minimum length of text to search
autoFocus={false}
// Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
//console.warn(data, details);
props.location = data.description;
}}
textInputProps={{
onChangeText: (text) => { console.warn(text) }
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaSyCKwbZNUyUIx2X0XBBlWbhPu_unz5_1o3E',
language: 'en', // language of the results
types: 'geocode' // default: 'geocode'
}}
styles={{
textInputContainer: {
backgroundColor: 'rgba(0,0,0,0)',
borderTopWidth: 0,
borderBottomWidth:0,
},
description: {
fontWeight: 'bold',
},
textInput: {
marginLeft: 22,
marginRight: 0,
height: 38,
color: '#5d5d5d',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
value={props.location}
onChangeText={props.onLocationChange}
renderLeftButton={() => <Text style={{ marginTop: 12, marginLeft:16, fontSize: 18 }}> Location </Text>}
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',
types: 'food'
}}
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
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
/>
You will get the selected location in onPress callback of the component.
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
this.setState(
{
address: data.description, // selected address
coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
}
);
}}
This gives you the latitude and longitude:
onPress = {(data, details = null) => {
const { lat, lng } = details.geometry.location;
)}}