From a6b31205acb51c2627dcb5495ae2c24aa8f13e2d Mon Sep 17 00:00:00 2001 From: Prateek Saxena Date: Wed, 22 Mar 2017 15:46:24 +0530 Subject: [PATCH] mw.widgets: Add SelectWithInputWidget and its PHP implementation Bug: T106999 Change-Id: Ic158bec3c463fba5099b05f41c9686f833e1c313 --- autoload.php | 1 + includes/widget/SelectWithInputWidget.php | 65 +++++++++ resources/Resources.php | 12 ++ .../mw.widgets.SelectWithInputWidget.base.css | 20 +++ .../mw.widgets.SelectWithInputWidget.js | 135 ++++++++++++++++++ 5 files changed, 233 insertions(+) create mode 100644 includes/widget/SelectWithInputWidget.php create mode 100644 resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css create mode 100644 resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js diff --git a/autoload.php b/autoload.php index 27c27c5692..09e42f6442 100644 --- a/autoload.php +++ b/autoload.php @@ -950,6 +950,7 @@ $wgAutoloadLocalClasses = [ 'MediaWiki\\Widget\\Search\\SearchResultWidget' => __DIR__ . '/includes/widget/search/SearchResultWidget.php', 'MediaWiki\\Widget\\Search\\SimpleSearchResultSetWidget' => __DIR__ . '/includes/widget/search/SimpleSearchResultSetWidget.php', 'MediaWiki\\Widget\\Search\\SimpleSearchResultWidget' => __DIR__ . '/includes/widget/search/SimpleSearchResultWidget.php', + 'MediaWiki\\Widget\\SelectWithInputWidget' => __DIR__ . '/includes/widget/SelectWithInputWidget.php', 'MediaWiki\\Widget\\TitleInputWidget' => __DIR__ . '/includes/widget/TitleInputWidget.php', 'MediaWiki\\Widget\\UserInputWidget' => __DIR__ . '/includes/widget/UserInputWidget.php', 'MediaWiki\\Widget\\UsersMultiselectWidget' => __DIR__ . '/includes/widget/UsersMultiselectWidget.php', diff --git a/includes/widget/SelectWithInputWidget.php b/includes/widget/SelectWithInputWidget.php new file mode 100644 index 0000000000..8faae82251 --- /dev/null +++ b/includes/widget/SelectWithInputWidget.php @@ -0,0 +1,65 @@ + [], + 'dropdowninput' => [], + 'or' => false + ], + $config + ); + + // Parent constructor + parent::__construct( $config ); + + // Properties + $this->config = $config; + $this->textinput = new TextInputWidget( $config['textinput'] ); + $this->dropdowninput = new DropdownInputWidget( $config['dropdowninput'] ); + + // Initialization + $this + ->addClasses( [ 'mw-widget-selectWithInputWidget' ] ) + ->appendContent( $this->dropdowninput, $this->textinput ); + } + + protected function getJavaScriptClassName() { + return 'mw.widgets.SelectWithInputWidget'; + } + + public function getConfig( &$config ) { + $config['textinput'] = $this->config['textinput']; + $config['dropdowninput'] = $this->config['dropdowninput']; + $config['or'] = $this->config['or']; + return parent::getConfig( $config ); + } +} diff --git a/resources/Resources.php b/resources/Resources.php index 71a5f61e75..715cdb8c9e 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -2383,6 +2383,18 @@ return [ ], 'targets' => [ 'desktop', 'mobile' ], ], + 'mediawiki.widgets.SelectWithInputWidget' => [ + 'scripts' => 'resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js', + 'dependencies' => [ + 'mediawiki.widgets.SelectWithInputWidget.styles', + 'oojs-ui-widgets', + ], + 'targets' => [ 'desktop', 'mobile' ], + ], + 'mediawiki.widgets.SelectWithInputWidget.styles' => [ + 'styles' => 'resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css', + 'targets' => [ 'desktop', 'mobile' ], + ], 'mediawiki.widgets.MediaSearch' => [ 'scripts' => [ 'resources/src/mediawiki.widgets/MediaSearch/mw.widgets.APIResultsProvider.js', diff --git a/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css b/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css new file mode 100644 index 0000000000..8c495a5fcb --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css @@ -0,0 +1,20 @@ +/*! + * MediaWiki Widgets - base SelectWithInput styles. + * + * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ + +.mw-widget-selectWithInputWidget .oo-ui-dropdownInputWidget, +.mw-widget-selectWithInputWidget .oo-ui-textInputWidget { + display: inline-block; +} + +.mw-widget-selectWithInputWidget .oo-ui-dropdownInputWidget { + max-width: 20em; + margin-right: 0.5em; +} + +.mw-widget-selectWithInputWidget .oo-ui-textInputWidget { + max-width: 29.5em; +} diff --git a/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js b/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js new file mode 100644 index 0000000000..8c60ecf939 --- /dev/null +++ b/resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js @@ -0,0 +1,135 @@ +/*! + * MediaWiki Widgets - SelectWithInputWidget class. + * + * @copyright 2011-2017 MediaWiki Widgets Team and others; see AUTHORS.txt + * @license The MIT License (MIT); see LICENSE.txt + */ +( function ( $, mw ) { + + /** + * Select with input widget. Displays an OO.ui.TextInputWidget along with + * an OO.ui.DropdownInputWidget. + * TODO Explain the OTHER option + * + * mw.loader.using( 'mediawiki.widgets.SelectWithInputWidget', function () { + * var swi = new mw.widgets.SelectWithInputWidget( { + * or: true, + * dropdowninput: { + * options: [ + * { data: 'other', label: 'Other' }, + * { data: 'a', label: 'First' }, + * { data: 'b', label: 'Second' }, + * { data: 'c', label: 'Third' } + * ] + * }, + * textinput: { + * } + * } ); + * + * $( 'body' ).append( swi.$element ); + * } ); + * + * @class mw.widgets.SelectWithInputWidget + * @extends OO.ui.Widget + * + * @constructor + * @param {Object} [config] Configuration options + * @cfg {Object} [dropdowninput] Config for the dropdown + * @cfg {Object} [textinput] Config for the text input + * @cfg {boolean} [or=false] Config for whether the widget is dropdown AND input + * or dropdown OR input + */ + mw.widgets.SelectWithInputWidget = function MwWidgetsSelectWithInputWidget( config ) { + // Config initialization + config = $.extend( { or: false }, config ); + + // Properties + this.textinput = new OO.ui.TextInputWidget( config.textinput ); + this.dropdowninput = new OO.ui.DropdownInputWidget( config.dropdowninput ); + + if ( config.or === true ) { + this.dropdowninput.on( 'change', this.onChange.bind( this ) ); + this.onChange(); + } + + // Parent constructor + mw.widgets.SelectWithInputWidget.parent.call( this, config ); + + // Initialization + this.$element + .addClass( 'mw-widget-selectWithInputWidget' ) + .append( + this.dropdowninput.$element, + this.textinput.$element + ); + }; + + /* Setup */ + OO.inheritClass( mw.widgets.SelectWithInputWidget, OO.ui.Widget ); + + /* Static Methods */ + + /** + * @inheritdoc + */ + mw.widgets.SelectWithInputWidget.static.reusePreInfuseDOM = function ( node, config ) { + config = mw.widgets.SelectWithInputWidget.parent.static.reusePreInfuseDOM( node, config ); + config.dropdowninput = OO.ui.DropdownInputWidget.static.reusePreInfuseDOM( + $( node ).find( '.oo-ui-dropdownInputWidget' ), + config.dropdowninput + ); + config.textinput = OO.ui.TextInputWidget.static.reusePreInfuseDOM( + $( node ).find( '.oo-ui-textInputWidget' ), + config.textinput + ); + return config; + }; + + /** + * @inheritdoc + */ + mw.widgets.SelectWithInputWidget.static.gatherPreInfuseState = function ( node, config ) { + var state = mw.widgets.SelectWithInputWidget.parent.static.gatherPreInfuseState( node, config ); + state.dropdowninput = OO.ui.DropdownInputWidget.static.gatherPreInfuseState( + $( node ).find( '.oo-ui-dropdownInputWidget' ), + config.dropdowninput + ); + state.textinput = OO.ui.TextInputWidget.static.gatherPreInfuseState( + $( node ).find( '.oo-ui-textInputWidget' ), + config.textinput + ); + return state; + }; + + /* Methods */ + + /** + * @inheritdoc + */ + mw.widgets.SelectWithInputWidget.prototype.restorePreInfuseState = function ( state ) { + mw.widgets.SelectWithInputWidget.parent.prototype.restorePreInfuseState.call( this, state ); + this.dropdowninput.restorePreInfuseState( state.dropdowninput ); + this.textinput.restorePreInfuseState( state.textinput ); + }; + + /** + * @inheritdoc + */ + mw.widgets.SelectWithInputWidget.prototype.setDisabled = function ( disabled ) { + mw.widgets.SelectWithInputWidget.parent.prototype.setDisabled.call( this, disabled ); + this.textinput.setDisabled( disabled ); + this.dropdowninput.setDisabled( disabled ); + }; + + /** + * Handle change events on the DropdownInput + * + * @param {string|undefined} value + * @private + */ + mw.widgets.SelectWithInputWidget.prototype.onChange = function ( value ) { + value = value || this.dropdowninput.getValue(); + this.textinput.$element.toggle( value === 'other' ); + }; + +}( jQuery, mediaWiki ) ); -- 2.20.1