Skip to content

Commit

Permalink
#767: Optimise autosuggest rendering
Browse files Browse the repository at this point in the history
Remove some unused state, and optimise the rendering of suggestions a bit.
Attempts to address dropped keystrokes under IE11 as reported in #767
  • Loading branch information
gjvoosten committed Aug 1, 2018
1 parent ae6e3ff commit add0d20
Showing 1 changed file with 20 additions and 20 deletions.
40 changes: 20 additions & 20 deletions client/src/components/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Autosuggest from 'react-autosuggest'
import autobind from 'autobind-decorator'
import _debounce from 'lodash/debounce'
import _isEqual from 'lodash/isEqual'
import _isEmpty from 'lodash/isEmpty'

import API from 'api'
import utils from 'utils'
Expand Down Expand Up @@ -51,16 +52,15 @@ export default class Autocomplete extends Component {
super(props)

this.fetchSuggestionsDebounced = _debounce(this.fetchSuggestions, 200)
this.noSuggestions = <span><i>No suggestions found</i></span>

const selectedIds = this._getSelectedIds(props)
const value = this._getValue(props)
const stringValue = this.getStringValue(value, props.valueKey)

this.state = {
suggestions: [],
noSuggestions: false,
selectedIds: selectedIds,
value: value,
stringValue: stringValue,
originalStringValue: stringValue,
}
Expand Down Expand Up @@ -106,36 +106,37 @@ export default class Autocomplete extends Component {
inputProps.onChange = this.onInputChange
inputProps.onBlur = this.onInputBlur
const { valueKey } = this.props
const renderSuggestion = this.props.template ? this.renderSuggestionTemplate : this.renderSuggestion

return <div style={{position: 'relative'}} ref={(el) => this.container = el}>
<img src={SEARCH_ICON} className="form-control-icon" alt="" onClick={this.focus} />

<Autosuggest
suggestions={this.state.noSuggestions ? [{}] : this.state.suggestions}
suggestions={this.state.suggestions}
onSuggestionsFetchRequested={this.fetchSuggestionsDebounced}
onSuggestionsClearRequested={this.clearSuggestions}
onSuggestionSelected={this.onSuggestionSelected}
getSuggestionValue={this.getStringValue.bind(this, valueKey)}
inputProps={inputProps}
renderInputComponent={this.renderInputComponent}
renderSuggestion={this.renderSuggestion}
renderSuggestion={renderSuggestion}
focusInputOnSuggestionClick={false}
/>
</div>
}

@autobind
renderSuggestion(suggestion) {
if (this.state.noSuggestions) {
return <span><i>No suggestions found</i></span>
}
return _isEmpty(suggestion)
? this.noSuggestions
: <span>{this.getStringValue(suggestion, this.props.valueKey)}</span>
}

let template = this.props.template
if (template) {
return template(suggestion)
} else {
return <span>{this.getStringValue(suggestion, this.props.valueKey)}</span>
}
@autobind
renderSuggestionTemplate(suggestion) {
return _isEmpty(suggestion)
? this.noSuggestions
: this.props.template(suggestion)
}

@autobind
Expand All @@ -156,8 +157,10 @@ export default class Autocomplete extends Component {
if (this.state.selectedIds) {
list = list.filter(suggestion => suggestion && suggestion.id && this.state.selectedIds.indexOf(suggestion.id) === -1)
}
let noSuggestions = list.length === 0
this.setState({suggestions: list, noSuggestions})
if (!list.length) {
list = [{}] // use an empty object so we render the 'noSuggestions' text
}
this.setState({suggestions: list})
}

@autobind
Expand Down Expand Up @@ -206,11 +209,8 @@ export default class Autocomplete extends Component {
event.preventDefault()

let stringValue = this.props.clearOnSelect ? '' : suggestionValue
// if (this.state.noSuggestions && stringValue !== ''){
// return
// }
this.currentSelected = suggestion
this.setState({value: suggestion, stringValue})
this.setState({stringValue: stringValue})

if (this.props.onChange) {
this.props.onChange(suggestion)
Expand Down Expand Up @@ -256,7 +256,7 @@ export default class Autocomplete extends Component {
if (val) {
if (val === this.state.originalStringValue) { return }

this.setState({value: val, stringValue: val})
this.setState({stringValue: val})
if (this.props.onErrorChange) {
this.props.onErrorChange(true, val)
} else if (this.props.onChange) {
Expand Down

0 comments on commit add0d20

Please sign in to comment.