@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
JavaScript
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 };