react-tag-input-custom-search
Version:
React Tag Autocomplete is a simple tagging component ready to drop in your React projects.
93 lines (76 loc) • 2.51 kB
JavaScript
const React = require('react')
const _ = require('lodash')
function escapeForRegExp (query) {
return query.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&')
}
function markIt (item, query) {
let input = item.name;
let name = (_.get(item,'condition.length',0) == 1 ? (' ' + _.get(item,['condition',0])) : '');
const regex = RegExp(escapeForRegExp(query), 'gi')
return {
__html: input.replace(regex, '<mark>$&</mark>') + name
}
}
function filterSuggestions (query, suggestions, length, suggestionsFilter) {
if (!suggestionsFilter) {
const regex = new RegExp(`(?:^|\\s)${escapeForRegExp(query)}`, 'i')
suggestionsFilter = (item) => regex.test(item.name)
}
return suggestions.filter(suggestionsFilter).slice(0, length)
}
class Suggestions extends React.Component {
constructor (props) {
super(props)
this.state = {
options: filterSuggestions(this.props.query, this.props.suggestions, this.props.maxSuggestionsLength, this.props.suggestionsFilter)
}
}
componentWillReceiveProps (newProps) {
this.setState({
options: filterSuggestions(newProps.query, newProps.suggestions, newProps.maxSuggestionsLength, newProps.suggestionsFilter)
})
}
handleMouseDown (item, e) {
// if(item.disabled){
// console.log('item disabled called');
// e.preventDefault()
// return;
// }
// focus is shifted on mouse down but calling preventDefault prevents this
e.preventDefault()
this.props.addTag(item)
}
render () {
if (!this.props.expandable || !this.state.options.length) {
return null
}
const options = this.state.options.map((item, i) => {
const key = `${this.props.listboxId}-${i}`
const classNames = []
if (this.props.selectedIndex === i) {
classNames.push(this.props.classNames.suggestionActive)
}
if (item.disabled) {
classNames.push(this.props.classNames.suggestionDisabled)
}
return (
<li
id={key}
key={key}
role='option'
className={classNames.join(' ')}
aria-disabled={item.disabled === true}
onMouseDown={this.handleMouseDown.bind(this, item)}>
<span dangerouslySetInnerHTML={markIt(item, this.props.query)} />
</li>
)
})
return (
<div className={this.props.classNames.suggestions}>
<ul role='listbox' id={this.props.listboxId}>{options}</ul>
</div>
)
}
}
module.exports = Suggestions