UNPKG

@attivio/suit

Version:

Attivio SUIT, the Search UI Toolkit, is a library for creating search clients for searching the Attivio platform.

276 lines (249 loc) 9.17 kB
var _class, _temp; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /* eslint-disable react/no-multi-comp */ import React from 'react'; import Dropdown from 'react-bootstrap/lib/Dropdown'; import MenuItem from 'react-bootstrap/lib/MenuItem'; import { RootCloseWrapper } from 'react-overlays'; import SignalData from '../api/SignalData'; import FetchUtils from '../util/FetchUtils'; import StringUtils from '../util/StringUtils'; var AutoCompleteInput = (_temp = _class = function (_React$Component) { _inherits(AutoCompleteInput, _React$Component); function AutoCompleteInput(props) { _classCallCheck(this, AutoCompleteInput); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props)); _this.state = { isLoading: false, suggestions: [], error: '', open: false, cursor: -1, queryValue: _this.props.value, userInput: _this.props.value, queryTimestamp: 0, queryIsAutocomplete: false }; _this.closeMenu = _this.closeMenu.bind(_this); _this.handleChange = _this.handleChange.bind(_this); _this.doKeyPress = _this.doKeyPress.bind(_this); _this.valueSelected = _this.valueSelected.bind(_this); _this.onToggle = _this.onToggle.bind(_this); return _this; } // Start looking for autocomplete values when there are at least 3 characters in the input field // eslint-disable-line max-len AutoCompleteInput.prototype.onToggle = function onToggle(isOpen) { this.setState({ open: isOpen }); }; AutoCompleteInput.prototype.valueSelected = function valueSelected(newValue) { this.updateValueAndAddSignal(newValue, true); this.setState({ queryValue: newValue }); this.closeMenu(); }; AutoCompleteInput.prototype.closeMenu = function closeMenu() { this.setState({ isLoading: false, suggestions: [], error: '', cursor: -1 }); }; AutoCompleteInput.prototype.handleChange = function handleChange(event) { var _this2 = this; var query = event.currentTarget.value; this.props.updateValue(query, false); if (query && query.length > AutoCompleteInput.AUTOCOMPLETE_THRESHOLD) { var _uri = this.props.uri; if (_uri) { var encodedValue = encodeURIComponent(query); this.setState({ isLoading: true, open: true, error: '', queryValue: query, userInput: query, queryTimestamp: Date.now(), queryIsAutocomplete: false }); var callback = function callback(response, errorString) { if (response) { var _suggestions = Array.isArray(response) ? response.map(function (item) { return item.label; }) : []; var _open = _suggestions.length > 0; _this2.setState({ isLoading: false, suggestions: _suggestions, error: '', open: _open }); } else if (errorString) { _this2.setState({ isLoading: false, suggestions: [], error: errorString, open: errorString.length > 0 }); } }; FetchUtils.fetch(_uri + '?term=' + encodedValue, null, callback, 'GET', 'An error occured while looking for suggestions.'); } } else { this.setState({ isLoading: false, suggestions: [], error: '', open: false, queryValue: query }); } }; AutoCompleteInput.prototype.updateValueAndAddSignal = function updateValueAndAddSignal(newQuery) { var doSearch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var _state = this.state, suggestions = _state.suggestions, queryTimestamp = _state.queryTimestamp, userInput = _state.userInput; var _props = this.props, updateValue = _props.updateValue, allowPunctuation = _props.allowPunctuation; var docOrdinal = suggestions.findIndex(function (suggestion) { return suggestion === newQuery; }); var signalData = new SignalData(); // index starts at 1 signalData.docOrdinal = docOrdinal + 1; signalData.query = userInput; signalData.queryTimestamp = queryTimestamp; var queryToSet = newQuery; if (!allowPunctuation) { queryToSet = StringUtils.normalizeAutocompleteSuggestion(newQuery); } this.setState({ queryValue: queryToSet, userInput: queryToSet }, function () { updateValue(queryToSet, doSearch, signalData); }); }; AutoCompleteInput.prototype.doKeyPress = function doKeyPress(event) { var suggestions = this.state.suggestions; // This condition is satisfied when a user presses the enter key. if (event.keyCode === 13) { var query = event.currentTarget.value; // This condition is satisfied when the user presses the enter key // after selecting entry from the autocomplete list if (this.state.queryIsAutocomplete) { this.updateValueAndAddSignal(query, true); } else { this.props.updateValue(query, true); } this.setState({ suggestions: [], open: false }); } else if (event.keyCode === 40 && this.state.cursor < suggestions.length - 1) { // This condition is satisfied when a user presses the down arrow key. var newCursor = this.state.cursor + 1; var _value = suggestions[newCursor]; this.setState({ cursor: newCursor, queryValue: _value, queryIsAutocomplete: true }); } else if (event.keyCode === 38 && this.state.cursor > 0) { // This condition is satisfied when a user presses the up arrow key. var _newCursor = this.state.cursor - 1; var _value2 = suggestions[_newCursor]; this.setState({ cursor: _newCursor, queryValue: _value2, queryIsAutocomplete: true }); } else if (event.keyCode === 27 && this.props.onEscape) { // This condition is satisfied when a user presses the escape key this.props.onEscape(); } }; AutoCompleteInput.prototype.render = function render() { var _this3 = this; var menuItems = []; if (this.state.error && this.state.error.length > 0) { menuItems.push(React.createElement( MenuItem, { eventKey: 'error', disabled: true }, this.state.error )); } else if (this.state.loading) { menuItems.push(React.createElement( MenuItem, { eventKey: 'loading', disabled: true }, 'Loading\u2026' )); } else { this.state.suggestions.forEach(function (suggestion, i) { var activeState = _this3.state.cursor === i; menuItems.push(React.createElement( MenuItem, { eventKey: suggestion, key: suggestion, active: activeState }, suggestion )); }); } return React.createElement( RootCloseWrapper, { onRootClose: this.closeMenu }, React.createElement( Dropdown, { id: this.props.id, onSelect: this.valueSelected, className: 'attivio-dropdown', open: this.state.open, onToggle: this.onToggle }, React.createElement('input', { placeholder: this.props.placeholder, value: this.state.queryValue, className: this.props.className, style: this.props.style, disabled: this.props.disabled, onInput: this.handleChange, onChange: this.handleChange, onKeyDown: this.doKeyPress }), React.createElement(Dropdown.Toggle, { style: { display: 'none' } }), React.createElement( Dropdown.Menu, { style: this.props.style }, menuItems ) ) ); }; return AutoCompleteInput; }(React.Component), _class.defaultProps = { id: 'autocomplete', placeholder: '', value: '', disabled: false, className: '', style: {}, allowPunctuation: false }, _class.displayName = 'AutoCompleteInput', _class.AUTOCOMPLETE_THRESHOLD = 2, _temp); export { AutoCompleteInput as default };