import React from 'react'; import APIClient from 'App/api_client'; import cn from 'classnames'; import { Input, Icon } from 'UI'; import { debounce } from 'App/utils'; import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv'; import EventSearchInput from 'Shared/EventSearchInput'; import stl from './autoComplete.module.css'; import FilterItem from '../CustomFilters/FilterItem'; const TYPE_TO_SEARCH_MSG = "Start typing to search..."; const NO_RESULTS_MSG = "No results found."; const SOME_ERROR_MSG = "Some error occured."; const defaultValueToText = value => value; const defaultOptionMapping = (values, valueToText) => values.map(value => ({ text: valueToText(value), value })); const hiddenStyle = { whiteSpace: 'pre-wrap', opacity: 0, position: 'fixed', left: '-3000px' }; let pasted = false; let changed = false; class AutoComplete extends React.PureComponent { static defaultProps = { method: 'GET', params: {}, } state = { values: [], noResultsMessage: TYPE_TO_SEARCH_MSG, ddOpen: false, query: this.props.value, loading: false, error: false } componentWillReceiveProps(newProps) { if (this.props.value !== newProps.value) { this.setState({ query: newProps.value}); } } onClickOutside = () => { this.setState({ ddOpen: false }); } requestValues = (q) => { const { params, endpoint, method } = this.props; this.setState({ loading: true, error: false, }); return new APIClient()[ method.toLowerCase() ](endpoint, { ...params, q }) .then(response => response.json()) .then(({ errors, data }) => { if (errors) { this.setError(); } else { this.setState({ ddOpen: true, values: data, loading: false, noResultsMessage: NO_RESULTS_MSG, }); } }) .catch(this.setError); } debouncedRequestValues = debounce(this.requestValues, 1000) setError = () => this.setState({ loading: false, error: true, noResultsMessage: SOME_ERROR_MSG, }) onInputChange = ({ target: { value } }) => { changed = true; this.setState({ query: value, updated: true }) const _value = value ? value.trim() : undefined; if (_value !== '' && _value !== ' ') { this.debouncedRequestValues(_value) } } onBlur = ({ target: { value } }) => { // to avoid sending unnecessary request on focus in/out without changing if (!changed && !pasted) return; value = pasted ? this.hiddenInput.value : value; const { onSelect, name } = this.props; if (value !== this.props.value) { const _value = value ? value.trim() : undefined; onSelect(null, {name, value: _value}); } changed = false; pasted = false; } onItemClick = (e, item) => { e.stopPropagation(); e.preventDefault(); const { onSelect, name } = this.props; this.setState({ query: item.value, ddOpen: false}) onSelect(e, {name, ...item.toJS()}); } render() { const { ddOpen, query, loading, values } = this.state; const { optionMapping = defaultOptionMapping, valueToText = defaultValueToText, placeholder = 'Type to search...', headerText = '', fullWidth = false, onRemoveValue = () => {}, onAddValue = () => {}, showCloseButton = false, } = this.props; const options = optionMapping(values, valueToText) return ( {/* */}
this.setState({ddOpen: true})} onChange={ this.onInputChange } onBlur={ this.onBlur } value={ query } autoFocus={ true } type="text" placeholder={ placeholder } onPaste={(e) => { const text = e.clipboardData.getData('Text'); this.hiddenInput.value = text; pasted = true; // to use only the hidden input } } autocomplete="do-not-autofill-bad-chrome" />
{ showCloseButton ? : or}
{showCloseButton &&
or
} {/* this.setState({ddOpen: true})} value={ query } // icon="search" label={{ basic: true, content:
test
}} labelPosition='right' loading={ loading } autoFocus={ true } type="search" placeholder={ placeholder } onPaste={(e) => { const text = e.clipboardData.getData('Text'); this.hiddenInput.value = text; pasted = true; // to use only the hidden input } } /> */} { ddOpen && options.length > 0 &&
{ headerText && headerText } { options.map(item => ( this.onItemClick(e, item) } /> )) }
}
); } } export default AutoComplete;