A React component to build a customized UI for Google Maps Places Autocomplete (Demo)
- Enable you to easily build a customized autocomplete dropdown powered by Google Maps Places Library
- Utility function to get latitude and longitude using Google Maps Geocoder API
To install the stable version
npm install --save react-places-autocomplete
The React component is exported as a default export
import PlacesAutocomplete from 'react-places-autocomplete'
geocodeByAddress
and geocodeByPlaceId
utility functions are named exports
import { geocodeByAddress, geocodeByPlaceId } from 'react-places-autocomplete'
See live demo: kenny-hibino.github.io/react-places-autocomplete/
To use this component, you are going to need to load Google Maps JavaScript API
Load the library in your project
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script>
Declare your PlacesAutocomplete component using React component
import React from 'react'
import PlacesAutocomplete, { geocodeByAddress } from 'react-places-autocomplete'
class SimpleForm extends React.Component {
constructor(props) {
super(props)
this.state = { address: 'San Francisco, CA' }
this.onChange = (address) => this.setState({ address })
this.handleFormSubmit = this.handleFormSubmit.bind(this)
}
handleFormSubmit(event) {
event.preventDefault()
const { address } = this.state
geocodeByAddress(address, (err, { lat, lng }) => {
if (err) {
console.log('Oh no!', err)
}
console.log(`Yay! got latitude and longitude for ${address}`, { lat, lng })
})
}
render() {
return (
<form onSubmit={this.handleFormSubmit}>
<PlacesAutocomplete
value={this.state.address}
onChange={this.onChange}
/>
<button type="submit">Submit</button>
</form>
)
}
}
export default SimpleForm
- value
- onChange
- autocompleteItem
- children
- classNames
- styles
- placeholder
- hideLabel
- onError
- clearItemsOnError
- onSelect
- options
- autoFocus
Type: String
,
Required: true
Value displayed in the input field
Type: Function
,
Required: true
Please see the example above
Type: Functional React Component
,
Required: false
The function takes props with suggestion
, formattedSuggestion
keys (see the example below).
We highly recommend that you create your own custom AutocompleteItem
and pass it as a prop.
/***********************************************
Example #1
autocompleteItem example with `suggestion`
************************************************/
render() {
const AutocompleteItem = ({ suggestion }) => (<div><i className="fa fa-map-marker"/>{suggestion}</div>)
return (
<PlacesAutocomplete
value={this.state.value}
onChange={this.onChange}
autocompleteItem={AutocompleteItem}
/>
)
}
/***************************************************
Example #2
autocompleteItem example with `formattedSuggestion`
****************************************************/
render() {
const AutocompleteItem = ({ formattedSuggestion }) => (
<div>
<strong>{ formattedSuggestion.mainText }</strong>{' '}
<small>{ formattedSuggestion.secondaryText }</small>
</div>
)
return (
<PlacesAutocomplete
value={this.state.value}
onChange={this.onChange}
autocompleteItem={AutocompleteItem}
/>
)
}
Type: Element
Required: false
You can add autocomplete functionality to an existing input element by wrapping it in <PlacesAutocomplete>
.
The wrapper will pass onChange
, onKeyDown
, and value
props down to the child component.
// custom input element example
import MyCustomInput from 'my-custom-input'
...
render() {
return (
<PlacesAutocomplete
value={this.state.value}
onChange={this.onChange}
>
<MyCustomInput/>
</PlacesAutocomplete>
)
}
Type: Object
,
Required: false
You can give a custom css classes to elements.
Accepted keys are root
, label
, input
, autocompleteContainer
// classNames example
render() {
const cssClasses = {
root: 'form-group',
label: 'form-label',
input: 'form-control',
autocompleteContainer: 'my-autocomplete-container'
}
return (
<PlacesAutocomplete
value={this.state.address}
onChange={this.onChange}
classNames={cssClasses}
/>
)
}
Now you can easily apply custom CSS styles using the classNames!
Type Object
,
Required: false
You can provide custom inline styles to elements.
Accepted keys are root
, label
, input
, autocompleteContainer
, autocompleteItem
, autocompleteItemActive
// custom style examples
render() {
const myStyles = {
root: { position: 'absolute' },
label: { color: 'red' },
input: { width: '100%' },
autocompleteContainer: { backgroundColor: 'green' },
autocompleteItem: { color: 'black' },
autocompleteItemActive: { color: 'blue' }
}
return (
<PlacesAutocomplete
value={this.state.address}
onChange={this.onChange}
styles={myStyles}
/>
)
}
Type: String
,
Required: false
,
Default: "Address"
You can pass placeholder
prop to customize input's placeholder text
Type: boolean
Required: false
,
Default: false
You can set hideLabel
to true
to not render the label element
Type: function
Required: false
Default: (status) => console.error('[react-places-autocomplete]: error happened when fetching data from Google Maps API.\nPlease check the docs here (https://github.com/kenny-hibino/react-places-autocomplete)\nStatus: ', status)
You can pass onError
prop to customize the behavior when google.maps.places.PlacesServiceStatus is not OK
(e.g., no predictions are found)
Receives status
as a parameter
Type: boolean
Required: false
Default: false
You can pass clearItemsOnError
prop to indicate whether the autocomplete predictions should be cleared when google.maps.places.PlacesServiceStatus
is not OK
Type: function
Required: false
,
Default: null
You can pass a function that gets called instead of onChange
function when user
hits the Enter key or clicks on an autocomplete item.
The function takes two positional arguments. First argument is address
, second is placeId
.
const handleSelect = (address, placeId) => {
this.setState({ address, placeId })
// You can do other things with address string or placeId. For example, geocode :)
}
// Pass this function via onSelect prop.
<PlacesAutocomplete
value={this.state.value}
onChange={this.handleChange}
onSelect={this.handleSelect}
/>
Type: object
Required: false
Default: {}
You can fine-tune the settings passed to the AutocompleteService class with options
prop.
This prop accepts an object following the same format as google.maps.places.AutocompletionRequest
(except for input
, which comes from the value of the input field).
// these options will bias the autocomplete predictions toward Sydney, Australia with a radius of 2000 meters,
// and limit the results to addresses only
const options = {
location: new google.maps.LatLng(-34, 151),
radius: 2000,
types: ['address']
}
<PlacesAutocomplete
value={this.state.address}
onChange={this.onChange}
options={options}
/>
Type: boolean
Required: false
Default: false
geocodeByAddress(address, callback)
Type: String
,
Required: true
String that gets passed to Google Maps Geocoder
Type: Function
,
Required: true
Three arguments will be passed to the callback.
First argument is an error object, set to null
when there's no error.
Second argument is an object with lat
and lng
keys
Third argument (optional) is entire payload from Google API
import { geocodeByAddress } from 'react-places-autocomplete'
geocodeByAddress('Los Angeles, CA', (error, { lat, lng }, results) => {
if (error) { return }
console.log('Geocoding success!', { lat, lng })
console.log('Entire payload from Google API', results)
})
geocodeByPlaceId(placeId, callback)
Type: String
,
Required: true
String that gets passed to Google Maps Geocoder
Type: Function
,
Required: true
Three arguments will be passed to the callback.
First argument is an error object, set to null
when there's no error.
Second argument is an object with lat
and lng
keys
Third argument (optional) is entire payload from Google API
import { geocodeByPlaceId } from 'react-places-autocomplete'
geocodeByPlaceId('ChIJE9on3F3HwoAR9AhGJW_fL-I', (error, { lat, lng }, results) => {
if (error) { return }
console.log('Geocoding success!', { lat, lng })
console.log('Entire payload from Google API', results)
})
Join us on Gitter if you are interested in contributing!
MIT