2 * MediaWiki Widgets - TitlesMultiselectWidget class.
4 * @copyright 2011-2015 MediaWiki Widgets Team and others; see AUTHORS.txt
5 * @license The MIT License (MIT); see LICENSE.txt
10 * Creates an mw.widgets.TitlesMultiselectWidget object
13 * @extends OO.ui.MenuTagMultiselectWidget
14 * @mixins OO.ui.mixin.RequestManager
15 * @mixins OO.ui.mixin.PendingElement
16 * @mixins mw.widgets.TitleWidget
19 * @param {Object} [config] Configuration options
21 mw
.widgets
.TitlesMultiselectWidget
= function MwWidgetsTitlesMultiselectWidget( config
) {
22 config
= $.extend( true, {
23 // Shouldn't this be handled by MenuTagMultiselectWidget?
24 options
: config
.selected
? config
.selected
.map( function ( title
) {
33 mw
.widgets
.TitlesMultiselectWidget
.parent
.call( this, $.extend( true,
35 clearInputOnChoose
: true,
36 inputPosition
: 'inline',
43 mw
.widgets
.TitleWidget
.call( this, $.extend( true, {
45 highlightSearchQuery
: false
47 OO
.ui
.mixin
.RequestManager
.call( this, config
);
48 OO
.ui
.mixin
.PendingElement
.call( this, $.extend( true, {}, config
, {
49 $pending
: this.$handle
52 // Validate from mw.widgets.TitleWidget
53 this.input
.setValidation( this.isQueryValid
.bind( this ) );
55 if ( this.maxLength
!== undefined ) {
56 // maxLength is defined through TitleWidget parent
57 this.input
.$input
.attr( 'maxlength', this.maxLength
);
62 .addClass( 'mw-widgets-titlesMultiselectWidget' );
65 // For consistency, use the same classes as TitleWidget
66 // expects for menu results
67 .addClass( 'mw-widget-titleWidget-menu' )
68 .toggleClass( 'mw-widget-titleWidget-menu-withImages', this.showImages
)
69 .toggleClass( 'mw-widget-titleWidget-menu-withDescriptions', this.showDescriptions
);
71 if ( 'name' in config
) {
72 // Use this instead of <input type="hidden">, because hidden inputs do not have separate
73 // 'value' and 'defaultValue' properties. The script on Special:Preferences
74 // (mw.special.preferences.confirmClose) checks this property to see if a field was changed.
75 this.hiddenInput
= $( '<textarea>' )
76 .addClass( 'oo-ui-element-hidden' )
77 .attr( 'name', config
.name
)
78 .appendTo( this.$element
);
79 // Update with preset values
80 // Set the default value (it might be different from just being empty)
81 this.hiddenInput
.prop( 'defaultValue', this.getItems().map( function ( item
) {
82 return item
.getData();
84 this.on( 'change', function ( items
) {
85 this.hiddenInput
.val( items
.map( function ( item
) {
86 return item
.getData();
88 // Trigger a 'change' event as if a user edited the text
89 // (it is not triggered when changing the value from JS code).
90 this.hiddenInput
.trigger( 'change' );
98 OO
.inheritClass( mw
.widgets
.TitlesMultiselectWidget
, OO
.ui
.MenuTagMultiselectWidget
);
99 OO
.mixinClass( mw
.widgets
.TitlesMultiselectWidget
, OO
.ui
.mixin
.RequestManager
);
100 OO
.mixinClass( mw
.widgets
.TitlesMultiselectWidget
, OO
.ui
.mixin
.PendingElement
);
101 OO
.mixinClass( mw
.widgets
.TitlesMultiselectWidget
, mw
.widgets
.TitleWidget
);
105 mw
.widgets
.TitlesMultiselectWidget
.prototype.getQueryValue = function () {
106 return this.input
.getValue();
110 * @inheritdoc OO.ui.MenuTagMultiselectWidget
112 mw
.widgets
.TitlesMultiselectWidget
.prototype.onInputChange = function () {
115 this.getRequestData()
116 .then( function ( data
) {
118 widget
.menu
.clearItems();
119 widget
.menu
.addItems( widget
.getOptionsFromData( data
) );
120 } ).always( function () {
122 mw
.widgets
.TitlesMultiselectWidget
.parent
.prototype.onInputChange
.call( widget
);
127 * @inheritdoc OO.ui.mixin.RequestManager
129 mw
.widgets
.TitlesMultiselectWidget
.prototype.getRequestQuery = function () {
130 return this.getQueryValue();
134 * @inheritdoc OO.ui.mixin.RequestManager
136 mw
.widgets
.TitlesMultiselectWidget
.prototype.getRequest = function () {
137 return this.getSuggestionsPromise();
141 * @inheritdoc OO.ui.mixin.RequestManager
143 mw
.widgets
.TitlesMultiselectWidget
.prototype.getRequestCacheDataFromResponse = function ( response
) {
144 return response
.query
|| {};