mw.widgets: Add SelectWithInputWidget and its PHP implementation
authorPrateek Saxena <prtksxna@gmail.com>
Wed, 22 Mar 2017 10:16:24 +0000 (15:46 +0530)
committerBartosz Dziewoński <matma.rex@gmail.com>
Mon, 24 Apr 2017 08:19:55 +0000 (10:19 +0200)
Bug: T106999
Change-Id: Ic158bec3c463fba5099b05f41c9686f833e1c313

autoload.php
includes/widget/SelectWithInputWidget.php [new file with mode: 0644]
resources/Resources.php
resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.base.css [new file with mode: 0644]
resources/src/mediawiki.widgets/mw.widgets.SelectWithInputWidget.js [new file with mode: 0644]

index 27c27c5..09e42f6 100644 (file)
@@ -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 (file)
index 0000000..8faae82
--- /dev/null
@@ -0,0 +1,65 @@
+<?php
+/**
+ * MediaWiki Widgets – SelectWithInputWidget class.
+ *
+ * @copyright 2011-2017 MediaWiki Widgets Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+namespace MediaWiki\Widget;
+
+use \OOUI\TextInputWidget;
+use \OOUI\DropdownInputWidget;
+
+/**
+ * Select and input widget.
+ */
+class SelectWithInputWidget extends \OOUI\Widget {
+
+       protected $textinput = null;
+       protected $dropdowninput = null;
+
+       /**
+        * A version of the SelectWithInputWidget, with `or` set to true.
+        *
+        * @param array $config Configuration options
+        * @param array $config['textinput'] Configuration for the TextInputWidget
+        * @param array $config['dropdowninput'] Configuration for the DropdownInputWidget
+        * @param boolean $config['or'] Configuration for whether the widget is dropdown AND input
+        *                              or dropdown OR input
+        */
+       public function __construct( array $config = [] ) {
+               // Configuration initialization
+               $config = array_merge(
+                       [
+                               'textinput' => [],
+                               '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 );
+       }
+}
index 71a5f61..715cdb8 100644 (file)
@@ -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 (file)
index 0000000..8c495a5
--- /dev/null
@@ -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 (file)
index 0000000..8c60ecf
--- /dev/null
@@ -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 ) );