/*! * ObjectOriented UserInterface SearchWidget class. * * @copyright 2011-2013 OOJS Team and others; see AUTHORS.txt * @license The MIT License (MIT); see LICENSE.txt */ /** * Creates an OO.ui.SearchWidget object. * * @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 intialization config = config || {}; // Parent constructor OO.ui.Widget.call( this, config ); // Properties this.query = new OO.ui.TextInputWidget( { '$': this.$, 'icon': 'search', 'placeholder': config.placeholder, 'value': config.value } ); this.results = new OO.ui.SelectWidget( { '$': this.$ } ); this.$query = this.$( '
' ); this.$results = this.$( '
' ); // Events this.query.connect( this, { 'change': 'onQueryChange', 'enter': 'onQueryEnter' } ); this.results.connect( this, { 'highlight': 'onResultsHighlight', 'select': 'onResultsSelect' } ); this.query.$input.on( 'keydown', OO.ui.bind( this.onQueryKeydown, 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 ); }; /* Inheritance */ OO.inheritClass( OO.ui.SearchWidget, OO.ui.Widget ); /* Events */ /** * @event highlight * @param {Object|null} item Item data or null if no item is highlighted */ /** * @event select * @param {Object|null} item Item data or null if no item is selected */ /* Methods */ /** * Handle query key down events. * * @method * @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. * * @method * @param {string} value New value */ OO.ui.SearchWidget.prototype.onQueryChange = function () { // Reset this.results.clearItems(); }; /** * Handle select widget enter key events. * * Selects highlighted item. * * @method * @param {string} value New value */ OO.ui.SearchWidget.prototype.onQueryEnter = function () { // Reset this.results.selectItem( this.results.getHighlightedItem() ); }; /** * Handle select widget highlight events. * * @method * @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. * * @method * @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. * * @method * @returns {OO.ui.TextInputWidget} Query input */ OO.ui.SearchWidget.prototype.getQuery = function () { return this.query; }; /** * Get the results list. * * @method * @returns {OO.ui.SelectWidget} Select list */ OO.ui.SearchWidget.prototype.getResults = function () { return this.results; };