| |
@@ -0,0 +1,66 @@
|
| |
+ import React from 'react';
|
| |
+ import { apiCall } from '../../core/utils';
|
| |
+ import onClickOutside from "react-onclickoutside";
|
| |
+ import SearchResults from './SearchResults';
|
| |
+
|
| |
+
|
| |
+ class SearchBar extends React.Component {
|
| |
+
|
| |
+ constructor(props) {
|
| |
+ super(props);
|
| |
+ this.state = {
|
| |
+ isLoading: false,
|
| |
+ showResults: false,
|
| |
+ results: null
|
| |
+ };
|
| |
+ this.handleChange = this.handleChange.bind(this);
|
| |
+ }
|
| |
+
|
| |
+ handleClickOutside(event) {
|
| |
+ this.setState({
|
| |
+ showResults: false
|
| |
+ })
|
| |
+ }
|
| |
+
|
| |
+ handleChange(event) {
|
| |
+ event.preventDefault();
|
| |
+ let searchterm = this.refs.query.value;
|
| |
+ if (!searchterm || searchterm.length < 2) {
|
| |
+ this.setState({
|
| |
+ showResults: false
|
| |
+ });
|
| |
+ return;
|
| |
+ }
|
| |
+ this.setState({ showResults: true, isLoading: true });
|
| |
+ let url = `${this.props.searchUrl}${searchterm}`;
|
| |
+ apiCall(url).then(
|
| |
+ (data) => {
|
| |
+ this.setState({ isLoading: false, results: data });
|
| |
+ },
|
| |
+ (error) => {
|
| |
+ console.log(error);
|
| |
+ }
|
| |
+ )
|
| |
+ }
|
| |
+
|
| |
+ render() {
|
| |
+ return (
|
| |
+ <div className="form mx-auto">
|
| |
+ <div className="input-group">
|
| |
+ <input className="form-control" type="text" placeholder="Search hubs..."
|
| |
+ onChange={this.handleChange} onClick={this.handleChange} ref="query"/>
|
| |
+ <div style={{position: 'absolute', zIndex: 100, color: '#bbb', right: '10px', top: '7px'}}>
|
| |
+ <i className="fa fa-search"/>
|
| |
+ </div>
|
| |
+ {this.state.showResults &&
|
| |
+ <SearchResults isLoading={this.state.isLoading} results={this.state.results} query={this.refs.query.value}/>
|
| |
+ }
|
| |
+ </div>
|
| |
+ </div>
|
| |
+ )
|
| |
+ }
|
| |
+
|
| |
+
|
| |
+ }
|
| |
+
|
| |
+ export default onClickOutside(SearchBar);
|
| |
This PR tries to reproduce the behavior exhibited by the typeahead.js code using React components.
Arrow key based navigation of search results is currently missing.
Substring highlighting in search results does not work with accents. This is currently unsupported on the backend too, but is taken care of in PR #540.
Whoosh has support for automatically highlighting the matching terms which we can then pass as props to HubResult
Width of search bar has been increased from 4 columns => 8 columns to make room for more detailed widget search results (in progress).
Package 'react-onclickoutside' has also been added, it is confirmed to be working on touch devices.