Last active
October 18, 2020 11:35
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | |
/> | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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