/** * SearchWidgets combine a {@link OO.ui.TextInputWidget text input field}, where users can type a search query, * and a {@link OO.ui.TextInputMenuSelectWidget menu} of search results, which is displayed beneath the query * field. Unlike {@link OO.ui.LookupElement lookup menus}, search result menus are always visible to the user. * Users can choose an item from the menu or type a query into the text field to search for a matching result item. * In general, search widgets are used inside a separate {@link OO.ui.Dialog dialog} window. * * Each time the query is changed, the search result menu is cleared and repopulated. Please see * the [OOjs UI demos][1] for an example. * * [1]: https://tools.wmflabs.org/oojs-ui/oojs-ui/demos/#dialogs-mediawiki-vector-ltr * * @class * @extends OO.ui.Widget * * @constructor * @param {Object} [config] Configuration options * @cfg {string|jQuery} [placeholder] Placeholder text for query input * @cfg {string} [value] Initial query value */ OO.ui.SearchWidget = function OoUiSearchWidget( config ) { // Configuration initialization config = config || {}; // Parent constructor OO.ui.SearchWidget.super.call( this, config ); // Properties this.query = new OO.ui.TextInputWidget( { icon: 'search', placeholder: config.placeholder, value: config.value } ); this.results = new OO.ui.SelectWidget(); this.$query = $( '
' ); this.$results = $( '
' ); // Events this.query.connect( this, { change: 'onQueryChange', enter: 'onQueryEnter' } ); this.results.connect( this, { highlight: 'onResultsHighlight', select: 'onResultsSelect' } ); this.query.$input.on( 'keydown', this.onQueryKeydown.bind( this ) ); // Initialization this.$query .addClass( 'oo-ui-searchWidget-query' ) .append( this.query.$element ); this.$results .addClass( 'oo-ui-searchWidget-results' ) .append( this.results.$element ); this.$element .addClass( 'oo-ui-searchWidget' ) .append( this.$results, this.$query ); }; /* Setup */ OO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget ); /* Events */ /** * A 'highlight' event is emitted when an item is highlighted. The highlight indicates which * item will be selected. When a user mouses over a menu item, it is highlighted. If a search * string is typed into the query field instead, the first menu item that matches the query * will be highlighted. * @event highlight * @deprecated Connect straight to getResults() events instead * @param {Object|null} item Item data or null if no item is highlighted */ /** * A 'select' event is emitted when an item is selected. A menu item is selected when it is clicked, * or when a user types a search query, a menu result is highlighted, and the user presses enter. * * @event select * @deprecated Connect straight to getResults() events instead * @param {Object|null} item Item data or null if no item is selected */ /* Methods */ /** * Handle query key down events. * * @private * @param {jQuery.Event} e Key down event */ OO.ui.SearchWidget.prototype.onQueryKeydown = function ( e ) { var highlightedItem, nextItem, dir = e.which === OO.ui.Keys.DOWN ? 1 : ( e.which === OO.ui.Keys.UP ? -1 : 0 ); if ( dir ) { highlightedItem = this.results.getHighlightedItem(); if ( !highlightedItem ) { highlightedItem = this.results.getSelectedItem(); } nextItem = this.results.getRelativeSelectableItem( highlightedItem, dir ); this.results.highlightItem( nextItem ); nextItem.scrollElementIntoView(); } }; /** * Handle select widget select events. * * Clears existing results. Subclasses should repopulate items according to new query. * * @private * @param {string} value New value */ OO.ui.SearchWidget.prototype.onQueryChange = function () { // Reset this.results.clearItems(); }; /** * Handle select widget enter key events. * * Selects highlighted item. * * @private * @param {string} value New value */ OO.ui.SearchWidget.prototype.onQueryEnter = function () { // Reset this.results.selectItem( this.results.getHighlightedItem() ); }; /** * Handle select widget highlight events. * * @private * @deprecated Connect straight to getResults() events instead * @param {OO.ui.OptionWidget} item Highlighted item * @fires highlight */ OO.ui.SearchWidget.prototype.onResultsHighlight = function ( item ) { this.emit( 'highlight', item ? item.getData() : null ); }; /** * Handle select widget select events. * * @private * @deprecated Connect straight to getResults() events instead * @param {OO.ui.OptionWidget} item Selected item * @fires select */ OO.ui.SearchWidget.prototype.onResultsSelect = function ( item ) { this.emit( 'select', item ? item.getData() : null ); }; /** * Get the query input. * * @return {OO.ui.TextInputWidget} Query input */ OO.ui.SearchWidget.prototype.getQuery = function () { return this.query; }; /** * Get the search results menu. * * @return {OO.ui.SelectWidget} Menu of search results */ OO.ui.SearchWidget.prototype.getResults = function () { return this.results; };