UNPKG

cruk-searchkit

Version:

Set of overriden and new searchkit components designed specifically for Cancer Research UK

332 lines (282 loc) 12 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _throttle = require('lodash/throttle'); var _throttle2 = _interopRequireDefault(_throttle); var _searchkit = require('searchkit'); var _CRUKCustomElasticGetter = require('../getter/CRUKCustomElasticGetter'); var _CRUKCustomElasticGetter2 = _interopRequireDefault(_CRUKCustomElasticGetter); var _CRUKSearchkitAutocompleteList = require('../autocomplete/CRUKSearchkitAutocompleteList'); var _CRUKSearchkitAutocompleteList2 = _interopRequireDefault(_CRUKSearchkitAutocompleteList); var _lodash = require('lodash'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; } 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) : _defaults(subClass, superClass); } /** * Override the render method on the SearchBox component to alter the markup. */ var CRUKSearchkitSearchBox = function (_SearchBox) { _inherits(CRUKSearchkitSearchBox, _SearchBox); function CRUKSearchkitSearchBox(props) { _classCallCheck(this, CRUKSearchkitSearchBox); var _this = _possibleConstructorReturn(this, (CRUKSearchkitSearchBox.__proto__ || Object.getPrototypeOf(CRUKSearchkitSearchBox)).call(this, props)); _this.state = { clearText: false, focused: false, autocompleteActive: false, input: undefined, autocompleteItems: [], selectedItem: 0 }; _this.lastSearchMs = 0; _this.throttledSearch = (0, _throttle2.default)(function () { _this.searchQuery(_this.accessor.getQueryString()); }, props.searchThrottleTime); _this.autocompleteToggle = _this.autocompleteToggle.bind(_this); _this.inputState = _this.inputState.bind(_this); _this.handleSearchButton = _this.handleSearchButton.bind(_this); return _this; } _createClass(CRUKSearchkitSearchBox, [{ key: 'handleKeyUp', value: function handleKeyUp(e) { if (!this.props.autocompleteEnable) return; var _state = this.state, autocompleteItems = _state.autocompleteItems, selectedItem = _state.selectedItem; if (this.refs.queryField.value === '') { this.setState({ autocompleteActive: false }); return; } var self = this; if (e.keyCode === 40 || e.keyCode === 38) { this.handleAutocompleteItems(e.keyCode); return; } if (this.props.test) return; var getter = new _CRUKCustomElasticGetter2.default(this.searchkit.host + '/_suggest'); getter.autocompleteRequest(this.refs.queryField.value).then(function (response) { self.setState({ autocompleteItems: CRUKSearchkitSearchBox.buildResults(response.data), autocompleteActive: true }); }).catch(function (error) { console.log(error); }); } }, { key: 'autocompleteToggle', value: function autocompleteToggle(flag) { this.setState({ autocompleteActive: flag }); } }, { key: 'inputState', value: function inputState(state) { this.setState({ input: state }); } }, { key: 'handleAutocompleteItems', value: function handleAutocompleteItems(arrow) { var _state2 = this.state, autocompleteItems = _state2.autocompleteItems, selectedItem = _state2.selectedItem; if (this.props.test) { autocompleteItems = this.props.autocompleteItems; } if (autocompleteItems.length < 1) return; var selectedItemIndex = function () { if (arrow === 40) { if (selectedItem < autocompleteItems.length) return selectedItem + 1; return autocompleteItems.length; } if (arrow === 38) { if (selectedItem > 1) return selectedItem - 1; return 1; } return 0; }(); this.setState({ selectedItem: selectedItemIndex }); } }, { key: 'setFocusState', value: function setFocusState(focused) { if (!focused) { var input = this.state.input; if (this.props.blurAction === 'search' && !(0, _lodash.isUndefined)(input) && input != this.getAccessorValue()) { this.searchQuery(input); } /** * Behave differently if this component has autocomplete enabled, needs * to be smarter innit. */ if (this.props.autocompleteEnable) { if (!this.state.autocompleteActive) { this.setState({ focused: focused }); } } else { this.setState({ focused: focused, input: undefined // Flush (should use accessor's state now) }); } } else { this.setState({ focused: focused }); } } }, { key: 'handleSearchButton', value: function handleSearchButton(e) { var _this2 = this; var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var clearText = this.state.clearText; if (w <= 768 && clearText) { e.preventDefault(); this.setState({ focused: true, clearText: false }, function () { _this2.refs.queryField.value = ''; }); this.refs.queryField.focus(); } } }, { key: 'onSubmit', value: function onSubmit(event) { var _this3 = this; var _state3 = this.state, autocompleteItems = _state3.autocompleteItems, selectedItem = _state3.selectedItem; event.preventDefault(); var query = this.getValue(); if (this.props.autocompleteEnable && selectedItem > 0) { query = autocompleteItems[selectedItem - 1]; this.setState({ input: query, selectedItem: 0, autocompleteActive: false }, function () { _this3.searchQuery(query); }); } /** * De-focus the input. */ if (document.activeElement != document.body) { document.activeElement.blur(); } } }, { key: 'componentDidMount', value: function componentDidMount() { var self = this; if (!this.props.test) { this.searchkit.addResultsListener(function (results) { var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var clearText = w <= 768 ? true : false; self.setState({ input: self.getAccessorValue(), clearText: clearText }); }); } } }, { key: 'render', value: function render() { var _state4 = this.state, focused = _state4.focused, selectedItem = _state4.selectedItem, clearText = _state4.clearText; var _state5 = this.state, autocompleteItems = _state5.autocompleteItems, autocompleteActive = _state5.autocompleteActive; var wrapper_class = 'cr-input-group cr-input-group--lg cr-search-input'; var placeholder = this.props.placeholder || this.translate('searchbox.placeholder'); if (focused) { wrapper_class += ' cr-input-group--focused'; } if (this.props.test && this.props.autocompleteItems) { autocompleteItems = this.props.autocompleteItems; autocompleteActive = true; } if (clearText) { wrapper_class += ' cr-search-input--closer'; } return _react2.default.createElement( 'form', { action: '.', onSubmit: this.onSubmit.bind(this) }, _react2.default.createElement( 'div', { className: wrapper_class }, _react2.default.createElement( 'label', { htmlFor: 'search-input', id: 'search-label' }, placeholder ), _react2.default.createElement('input', { type: 'search', 'data-qa': 'query', id: 'search-input', className: 'cr-input-group__input cr-search-input__input', placeholder: placeholder, value: this.getValue(), onFocus: this.setFocusState.bind(this, true), onBlur: this.setFocusState.bind(this, false), onKeyUp: this.handleKeyUp.bind(this), ref: 'queryField', autoFocus: this.props.autofocus, onChange: this.onChange.bind(this), 'aria-describedby': 'search-label', autoComplete: 'off', autoCorrect: 'off', tabIndex: '1' }), _react2.default.createElement( 'span', { className: 'cr-input-group__button cr-search-input__button' }, _react2.default.createElement( 'button', { type: 'submit', className: 'btn', 'aria-label': 'Submit your search', 'data-qa': 'submit', onClick: this.handleSearchButton }, _react2.default.createElement('span', { className: 'cr-input-group__icon glyphicon glyphicon-search', 'aria-hidden': 'true' }) ) ), this.props.autocompleteEnable && _react2.default.createElement(_CRUKSearchkitAutocompleteList2.default, { selectedItem: selectedItem, inputState: this.inputState, autocompleteActive: autocompleteActive, autocompleteItems: autocompleteItems, toggle: this.autocompleteToggle }) ) ); } }]); return CRUKSearchkitSearchBox; }(_searchkit.SearchBox); CRUKSearchkitSearchBox.buildResults = function (results) { return results.title_suggest[0].options.map(function (v) { return v.text; }); }; CRUKSearchkitSearchBox.propTypes = _extends({ autocompleteEnable: _react2.default.PropTypes.bool, test: _react2.default.PropTypes.bool, autocompleteItems: _react2.default.PropTypes.array }, _searchkit.SearchBox.propTypes); exports.default = CRUKSearchkitSearchBox;