Skip to content

Instantly share code, notes, and snippets.

@louisremi
Last active October 18, 2020 11:35
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louisremi/f7ac527d30ed15c74a568e9022d128d4 to your computer and use it in GitHub Desktop.
Save louisremi/f7ac527d30ed15c74a568e9022d128d4 to your computer and use it in GitHub Desktop.
react-select-places Address autocomplete component built on top of React-Select and Algolia Places
import React from 'react';
import Places from './places.components.jsx';
export default class Example extends React.Component {
constructor(props) {
super(props);
this.state = {address: {}};
this.handleChange = this.handleChange.bind(this);
// options passed to the REST API
this.placesOptions = {
type: 'address',
hitsPerPage: 5,
};
// properties of the <input/> generated by react-select
this.inputProps = {
autoComplete: 'off',
};
}
handleChange(value) {
this.setState({
address: {
query: value.query,
suggestion: value,
},
});
}
render() {
return (
<Places
value={this.state.address}
onChange={this.handleChange}
inputProps={this.inputProps}
options={this.placesOptions}
appId="xxxxxxxx"
apiKey="XXXXXXXXX"
/>
);
}
}
import React from 'react';
import Select from 'react-select';
import formatHit from './places/formatHit.js';
import formatInputValue from './places/formatInputValue.js';
import formatDropdownValue from './places/formatDropdownValue.jsx';
export default class Places extends React.Component {
constructor(props) {
super(props);
this.loadAddresses = this.loadAddresses.bind(this);
}
renderOption(option) {
return (
<span dangerouslySetInnerHTML={{__html: formatDropdownValue(option)}} />
);
}
renderValue(option) {
return (
<span dangerouslySetInnerHTML={{__html: option.suggestion.value}} />
);
}
loadAddresses(input) {
const {options, appId, apiKey} = this.props;
const args = Object.assign({
query: input,
language: 'DE',
}, options);
return fetch('https://places-dsn.algolia.net/1/places/query', {
method: 'POST',
headers: {
'X-Algolia-Application-Id': appId,
'X-Algolia-API-Key': apiKey,
},
mode: 'cors',
body: JSON.stringify(args),
}).then((response) => {
return response.json();
}).then((data) => {
const opts = {
options: data.hits.map((hit, hitIndex) => {
return formatHit({
formatInputValue,
hit,
hitIndex,
query: input,
});
}),
};
return opts;
});
}
// we don't want Select to filter-out any option based on the input
dontFilter(options) {
return options;
}
render() {
return (
<Select.Async {...this.props}
loadOptions={this.loadAddresses}
filterOptions={this.dontFilter}
optionRenderer={this.renderOption}
valueRenderer={this.renderValue}
/>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment