From 85ae636f8d707a7cf0de38f40bda16d0ddac686c Mon Sep 17 00:00:00 2001 From: Prateek Saxena Date: Thu, 3 Sep 2015 16:14:02 +0530 Subject: [PATCH] Add mw.widgets.CategorySelector Extends OO.ui.CapsuleMultiSelectWidget for category selection. Bug: T111791 Change-Id: I317c23d4fdbc16cd488fb211f8dd96681806324a --- resources/Resources.php | 1 + .../mw.widgets.CategorySelector.js | 102 ++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js diff --git a/resources/Resources.php b/resources/Resources.php index 1df28adcd0..2b99428fc3 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1887,6 +1887,7 @@ return array( 'resources/src/mediawiki.widgets/mw.widgets.TitleInputWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.TitleOptionWidget.js', 'resources/src/mediawiki.widgets/mw.widgets.UserInputWidget.js', + 'resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js', ), 'skinStyles' => array( 'default' => array( diff --git a/resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js b/resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js new file mode 100644 index 0000000000..09ac7b29bf --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.CategorySelector.js @@ -0,0 +1,102 @@ +/*! + * MediaWiki Widgets - CategorySelector class. + * + * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ +( function ( $, mw ) { + + /** + * Category selector widget. Displays an OO.ui.CapsuleMultiSelectWidget + * and autocompletes with available categories. + * + * @class + * @uses mw.Api + * @extends OO.ui.CapsuleMultiSelectWidget + * + * @constructor + * @param {Object} [config] Configuration options + */ + mw.widgets.CategorySelector = function ( config ) { + // Parent constructor + mw.widgets.CategorySelector.parent.call( this, config ); + + // Event handler to call the autocomplete methods + this.$input.on( 'change input cut paste', OO.ui.debounce( this.updateMenuItems.bind( this ), 100 ) ); + }; + + /* Setup */ + + OO.inheritClass( mw.widgets.CategorySelector, OO.ui.CapsuleMultiSelectWidget ); + + /* Methods */ + + /** + * Gets new items based on the input by calling + * {@link #getNewMenuItems getNewItems} and updates the menu + * after removing duplicates based on the data value. + * + * @private + * @method + */ + mw.widgets.CategorySelector.prototype.updateMenuItems = function () { + this.getNewMenuItems( this.$input.val() ).then( function ( items ) { + var existingItems, filteredItems, + menu = this.getMenu(); + + // Array of strings of the data of OO.ui.MenuOptionsWidgets + existingItems = menu.getItems().map( function ( item ) { + return item.data; + } ); + + // Remove if items' data already exists + filteredItems = items.filter( function ( item ) { + return existingItems.indexOf( item.data ) === -1; + } ); + + // Map to an array of OO.ui.MenuOptionWidgets + filteredItems = filteredItems.map( function ( item ) { + return new OO.ui.MenuOptionWidget( { + data: item.data, + label: item.label + } ); + } ); + + menu.addItems( filteredItems ).updateItemVisibility(); + }.bind( this ) ); + }; + + /** + * Searches for categories based on the input. + * + * @private + * @method + * @param {string} input The input used to prefix search categories + * @return {jQuery.Promise} Resolves with an array of categories + */ + mw.widgets.CategorySelector.prototype.getNewMenuItems = function ( input ) { + var deferred = new $.Deferred(), + catNsId = mw.config.get( 'wgNamespaceIds' ).category, + api = new mw.Api(); + + api.get( { + action: 'opensearch', + namespace: catNsId, + limit: 10, + search: input + } ).done( function ( res ) { + var categoryNames = res[ 1 ].map( function ( name ) { + return mw.Title.newFromText( name, catNsId ).getMainText(); + } ); + + deferred.resolve( categoryNames.map( function ( category ) { + return { + data: category, + label: category + }; + } ) ); + } ); + + return deferred.promise(); + }; +}( jQuery, mediaWiki ) ); -- 2.20.1