colouring-montreal/app/src/frontend/search-box.js

140 lines
4.0 KiB
JavaScript
Raw Normal View History

2019-02-11 04:04:19 -05:00
import React, { Component } from 'react';
import './search-box.css';
/**
* Search for location
*/
class SearchBox extends Component {
constructor(props) {
super(props);
this.state = {
2019-05-27 11:31:48 -04:00
q: '',
2019-02-11 04:04:19 -05:00
results: [],
fetching: false
}
this.handleChange = this.handleChange.bind(this);
this.search = this.search.bind(this);
this.handleKeyPress = this.handleKeyPress.bind(this);
this.clearResults = this.clearResults.bind(this);
this.clearQuery = this.clearQuery.bind(this);
2019-02-11 04:04:19 -05:00
}
// Update search term
handleChange(e) {
this.setState({
q: e.target.value
});
// If the clear icon has been clicked, clear results list as well
2019-05-27 11:31:48 -04:00
if(e.target.value === '') {
this.clearResults();
}
}
// Clear search results on ESC
handleKeyPress(e){
if(e.keyCode === 27) {
//ESC is pressed
this.clearQuery();
this.clearResults();
}
}
clearResults(){
this.setState({
results: []
});
}
clearQuery(){
this.setState({
2019-05-27 11:31:48 -04:00
q: ''
});
2019-02-11 04:04:19 -05:00
}
// Query search endpoint
search(e) {
e.preventDefault();
this.setState({
fetching: true
})
fetch(
'/search?q='+this.state.q
).then(
(res) => res.json()
).then((data) => {
if (data && data.results){
this.setState({
results: data.results,
fetching: false
})
} else {
console.error(data);
this.setState({
results: [],
fetching: false
})
}
}).catch((err) => {
console.error(err)
this.setState({
results: [],
fetching: false
})
})
}
render() {
const resultsList = this.state.results.length?
<ul className="search-box-results">
{
this.state.results.map((result) => {
const label = result.attributes.label;
const lng = result.geometry.coordinates[0];
const lat = result.geometry.coordinates[1];
const zoom = result.attributes.zoom;
const href = `?lng=${lng}&lat=${lat}&zoom=${zoom}`
return (
<li key={result.attributes.label}>
<a
className="search-box-result"
onClick={(e) => {
e.preventDefault();
this.props.onLocate(lat, lng, zoom);
}}
href={href}
>{`${label.substring(0,4)} ${label.substring(4, 7)}`}</a>
</li>
)
})
}
</ul>
: null;
return (
2019-05-27 11:31:48 -04:00
<div className={`search-box ${this.props.is_building? 'building' : ''}`} onKeyDown={this.handleKeyPress}>
2019-02-11 04:04:19 -05:00
<form action="/search" method="GET" onSubmit={this.search}
2019-02-24 08:34:57 -05:00
className="form-inline">
2019-02-11 04:04:19 -05:00
<input
className="form-control"
type="search"
id="search-box-q"
name="q"
value={this.state.q}
placeholder="Search for a postcode"
aria-label="Search for a postcode"
onChange={this.handleChange}
/>
2019-02-24 08:34:57 -05:00
<button className="btn btn-outline-dark" type="submit">Search</button>
2019-02-11 04:04:19 -05:00
</form>
{ resultsList }
</div>
)
}
}
export default SearchBox;