diff options
Diffstat (limited to 'vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js')
-rw-r--r-- | vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js b/vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js new file mode 100644 index 00000000..6b971e81 --- /dev/null +++ b/vendor/oojs/oojs-ui/src/widgets/TextInputMenuSelectWidget.js @@ -0,0 +1,103 @@ +/** + * TextInputMenuSelectWidget is a menu that is specially designed to be positioned beneath + * a {@link OO.ui.TextInputWidget text input} field. The menu's position is automatically + * calculated and maintained when the menu is toggled or the window is resized. + * See OO.ui.ComboBoxWidget for an example of a widget that uses this class. + * + * @class + * @extends OO.ui.MenuSelectWidget + * + * @constructor + * @param {OO.ui.TextInputWidget} inputWidget Text input widget to provide menu for + * @param {Object} [config] Configuration options + * @cfg {jQuery} [$container=input.$element] Element to render menu under + */ +OO.ui.TextInputMenuSelectWidget = function OoUiTextInputMenuSelectWidget( inputWidget, config ) { + // Allow passing positional parameters inside the config object + if ( OO.isPlainObject( inputWidget ) && config === undefined ) { + config = inputWidget; + inputWidget = config.inputWidget; + } + + // Configuration initialization + config = config || {}; + + // Parent constructor + OO.ui.TextInputMenuSelectWidget.super.call( this, config ); + + // Properties + this.inputWidget = inputWidget; + this.$container = config.$container || this.inputWidget.$element; + this.onWindowResizeHandler = this.onWindowResize.bind( this ); + + // Initialization + this.$element.addClass( 'oo-ui-textInputMenuSelectWidget' ); +}; + +/* Setup */ + +OO.inheritClass( OO.ui.TextInputMenuSelectWidget, OO.ui.MenuSelectWidget ); + +/* Methods */ + +/** + * Handle window resize event. + * + * @private + * @param {jQuery.Event} e Window resize event + */ +OO.ui.TextInputMenuSelectWidget.prototype.onWindowResize = function () { + this.position(); +}; + +/** + * @inheritdoc + */ +OO.ui.TextInputMenuSelectWidget.prototype.toggle = function ( visible ) { + visible = visible === undefined ? !this.isVisible() : !!visible; + + var change = visible !== this.isVisible(); + + if ( change && visible ) { + // Make sure the width is set before the parent method runs. + // After this we have to call this.position(); again to actually + // position ourselves correctly. + this.position(); + } + + // Parent method + OO.ui.TextInputMenuSelectWidget.super.prototype.toggle.call( this, visible ); + + if ( change ) { + if ( this.isVisible() ) { + this.position(); + $( this.getElementWindow() ).on( 'resize', this.onWindowResizeHandler ); + } else { + $( this.getElementWindow() ).off( 'resize', this.onWindowResizeHandler ); + } + } + + return this; +}; + +/** + * Position the menu. + * + * @private + * @chainable + */ +OO.ui.TextInputMenuSelectWidget.prototype.position = function () { + var $container = this.$container, + pos = OO.ui.Element.static.getRelativePosition( $container, this.$element.offsetParent() ); + + // Position under input + pos.top += $container.height(); + this.$element.css( pos ); + + // Set width + this.setIdealSize( $container.width() ); + // We updated the position, so re-evaluate the clipping state + this.clip(); + + return this; +}; |