2 * MediaWiki Widgets - SelectWithInputWidget class.
4 * @copyright 2011-2017 MediaWiki Widgets Team and others; see AUTHORS.txt
5 * @license The MIT License (MIT); see LICENSE.txt
10 * Select with input widget. Displays an OO.ui.TextInputWidget along with
11 * an OO.ui.DropdownInputWidget.
12 * TODO Explain the OTHER option
14 * mw.loader.using( 'mediawiki.widgets.SelectWithInputWidget', function () {
15 * var swi = new mw.widgets.SelectWithInputWidget( {
19 * { data: 'other', label: 'Other' },
20 * { data: 'a', label: 'First' },
21 * { data: 'b', label: 'Second' },
22 * { data: 'c', label: 'Third' }
29 * $( 'body' ).append( swi.$element );
32 * @class mw.widgets.SelectWithInputWidget
33 * @extends OO.ui.Widget
36 * @param {Object} [config] Configuration options
37 * @cfg {Object} [dropdowninput] Config for the dropdown
38 * @cfg {Object} [textinput] Config for the text input
39 * @cfg {boolean} [or=false] Config for whether the widget is dropdown AND input
40 * or dropdown OR input
42 mw
.widgets
.SelectWithInputWidget
= function MwWidgetsSelectWithInputWidget( config
) {
43 // Config initialization
44 config
= $.extend( { or
: false }, config
);
47 this.textinput
= new OO
.ui
.TextInputWidget( config
.textinput
);
48 this.dropdowninput
= new OO
.ui
.DropdownInputWidget( config
.dropdowninput
);
52 this.dropdowninput
.on( 'change', this.onChange
.bind( this ) );
53 this.textinput
.on( 'change', function () {
54 this.emit( 'change', this.getValue() );
58 mw
.widgets
.SelectWithInputWidget
.parent
.call( this, config
);
62 .addClass( 'mw-widget-selectWithInputWidget' )
64 this.dropdowninput
.$element
,
65 this.textinput
.$element
71 OO
.inheritClass( mw
.widgets
.SelectWithInputWidget
, OO
.ui
.Widget
);
78 mw
.widgets
.SelectWithInputWidget
.static.reusePreInfuseDOM = function ( node
, config
) {
79 config
= mw
.widgets
.SelectWithInputWidget
.parent
.static.reusePreInfuseDOM( node
, config
);
80 config
.dropdowninput
= OO
.ui
.DropdownInputWidget
.static.reusePreInfuseDOM(
81 $( node
).find( '.oo-ui-dropdownInputWidget' ),
84 config
.textinput
= OO
.ui
.TextInputWidget
.static.reusePreInfuseDOM(
85 $( node
).find( '.oo-ui-textInputWidget' ),
94 mw
.widgets
.SelectWithInputWidget
.static.gatherPreInfuseState = function ( node
, config
) {
95 var state
= mw
.widgets
.SelectWithInputWidget
.parent
.static.gatherPreInfuseState( node
, config
);
96 state
.dropdowninput
= OO
.ui
.DropdownInputWidget
.static.gatherPreInfuseState(
97 $( node
).find( '.oo-ui-dropdownInputWidget' ),
100 state
.textinput
= OO
.ui
.TextInputWidget
.static.gatherPreInfuseState(
101 $( node
).find( '.oo-ui-textInputWidget' ),
112 mw
.widgets
.SelectWithInputWidget
.prototype.restorePreInfuseState = function ( state
) {
113 mw
.widgets
.SelectWithInputWidget
.parent
.prototype.restorePreInfuseState
.call( this, state
);
114 this.dropdowninput
.restorePreInfuseState( state
.dropdowninput
);
115 this.textinput
.restorePreInfuseState( state
.textinput
);
121 mw
.widgets
.SelectWithInputWidget
.prototype.setDisabled = function ( disabled
) {
122 var textinputIsHidden
= this.or
&& this.dropdowninput
.getValue() !== 'other';
123 mw
.widgets
.SelectWithInputWidget
.parent
.prototype.setDisabled
.call( this, disabled
);
124 this.dropdowninput
.setDisabled( disabled
);
125 // It is impossible to submit a form with hidden fields failing validation, e.g. one that
126 // is required. However, validity is not checked for disabled fields, as these are not
127 // submitted with the form. So we should also disable fields when hiding them.
128 this.textinput
.setDisabled( textinputIsHidden
|| disabled
);
132 * Set the value from outside.
134 * @param {string|undefined} value
136 mw
.widgets
.SelectWithInputWidget
.prototype.setValue = function ( value
) {
137 var selectable
= false;
140 if ( value
!== 'other' ) {
141 selectable
= !!this.dropdowninput
.dropdownWidget
.getMenu().findItemFromData( value
);
145 this.dropdowninput
.setValue( value
);
146 this.textinput
.setValue( undefined );
148 this.dropdowninput
.setValue( 'other' );
149 this.textinput
.setValue( value
);
152 this.emit( 'change', value
);
157 * Get the value from outside.
161 mw
.widgets
.SelectWithInputWidget
.prototype.getValue = function () {
163 if ( this.dropdowninput
.getValue() !== 'other' ) {
164 return this.dropdowninput
.getValue();
167 return this.textinput
.getValue();
174 * Handle change events on the DropdownInput
176 * @param {string|undefined} value
179 mw
.widgets
.SelectWithInputWidget
.prototype.onChange = function ( value
) {
181 value
= value
|| this.dropdowninput
.getValue();
182 this.textinput
.$element
.toggle( value
=== 'other' );
183 // It is impossible to submit a form with hidden fields failing validation, e.g. one that
184 // is required. However, validity is not checked for disabled fields, as these are not
185 // submitted with the form. So we should also disable fields when hiding them.
186 this.textinput
.setDisabled( value
!== 'other' || this.isDisabled() );
189 this.emit( 'change', this.getValue() );