Last active
February 4, 2016 16:53
-
-
Save MrLeebo/db40779fecffda785d85 to your computer and use it in GitHub Desktop.
Example using Autosuggest with jquery-ui to fix the suggestions menu position inside a scrollable container
This file contains 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
/*global __IS_TEST__*/ | |
import _ from 'lodash'; | |
import React from 'react'; | |
const { array, string, func, number } = React.PropTypes; | |
import { findDOMNode } from 'react-dom'; | |
import Autosuggest from 'react-autosuggest'; | |
if (!__IS_TEST__) require('jquery-ui'); | |
export default React.createClass({ | |
propTypes: { | |
options: array.isRequired, | |
value: string, | |
onChange: func.isRequired, | |
maxSuggestions: number | |
}, | |
getDefaultProps() { | |
return { maxSuggestions: 5, value: '' } | |
}, | |
getInitialState() { | |
return { suggestions: this.getSuggestions(this.props.value) } | |
}, | |
componentDidMount() { | |
this.fixSuggestionsPosition(); | |
}, | |
componentDidUpdate() { | |
this.fixSuggestionsPosition(); | |
}, | |
fixSuggestionsPosition() { | |
if (__IS_TEST__) return; | |
// I feel like there should be a better way to do this. | |
window.requestAnimationFrame(() => { | |
const component = findDOMNode(this.refs.autosuggest); | |
const menu = $('.autosuggest-suggestions', component); | |
const input = $('input', component); | |
menu.position({ | |
my: "left top", | |
at: "left bottom", | |
of: input, | |
collision: "fit" | |
}); | |
}); | |
}, | |
onSuggestionsUpdateRequested({value}) { | |
this.setState({ suggestions: this.getSuggestions(value)}) | |
}, | |
getSuggestionValue(suggestion) { | |
return suggestion; | |
}, | |
renderSuggestion(suggestion) { | |
return <a href='#'>{suggestion}</a> | |
}, | |
getSuggestions(value='') { | |
value = value && value.trim().toLowerCase(); | |
return value && _.take(this.props.options.filter(o => o.toLowerCase().includes(value)), this.props.maxSuggestions) || []; | |
}, | |
shouldRenderSuggestions(value='') { | |
this.fixSuggestionsPosition(); | |
return value && value.trim().length > 0; | |
}, | |
onChange(e, {newValue}) { | |
e.preventDefault(); | |
this.props.onChange(newValue); | |
}, | |
onSuggestionSelected(e, {suggestionValue}) { | |
e.preventDefault(); | |
this.props.onChange(suggestionValue); | |
}, | |
render() { | |
const { options, value, ...passableProps } = this.props; | |
const theme = { | |
container: 'autosuggest dropdown', | |
containerOpen: 'open', | |
input: 'autosuggest-input form-control', | |
suggestionsContainer: 'autosuggest-suggestions dropdown-menu', | |
suggestion: '', | |
suggestionFocused: 'active' | |
}; | |
const inputProps = { | |
value: value, | |
className: 'form-control', | |
...passableProps, | |
onChange: this.onChange | |
}; | |
return ( | |
<Autosuggest | |
ref='autosuggest' | |
suggestions={this.getSuggestions(value)} | |
onSuggestionsUpdateRequested={this.onSuggestionsUpdateRequested} | |
onSuggestionSelected={this.onSuggestionSelected} | |
getSuggestionValue={this.getSuggestionValue} | |
renderSuggestion={this.renderSuggestion} | |
shouldRenderSuggestions={this.shouldRenderSuggestions} | |
inputProps={inputProps} | |
theme={theme}/> | |
); | |
} | |
}) |
This file contains 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
.scrollable-menu { | |
height: auto; | |
max-height: 50vh; | |
overflow-y: auto; | |
} | |
.autosuggest { | |
position: static; | |
margin-right: 20px; | |
} | |
.autosuggest-suggestions { | |
position: absolute; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment