3 * Filter-specific CapsuleMultiselectWidget
6 * @extends OO.ui.CapsuleMultiselectWidget
9 * @param {mw.rcfilters.Controller} controller RCFilters controller
10 * @param {mw.rcfilters.dm.FiltersViewModel} model RCFilters view model
11 * @param {OO.ui.InputWidget} filterInput A filter input that focuses the capsule widget
12 * @param {Object} config Configuration object
13 * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
15 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
= function MwRcfiltersUiFilterCapsuleMultiselectWidget( controller
, model
, filterInput
, config
) {
17 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.parent
.call( this, $.extend( {
18 $autoCloseIgnore
: filterInput
.$element
21 this.controller
= controller
;
23 this.$overlay
= config
.$overlay
|| this.$element
;
25 this.filterInput
= filterInput
;
27 this.$content
.prepend(
29 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content-title' )
30 .text( mw
.msg( 'rcfilters-activefilters' ) )
33 this.resetButton
= new OO
.ui
.ButtonWidget( {
36 title
: mw
.msg( 'rcfilters-clear-all-filters' ),
37 classes
: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-resetButton' ]
40 this.emptyFilterMessage
= new OO
.ui
.LabelWidget( {
41 label
: mw
.msg( 'rcfilters-empty-filter' ),
42 classes
: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-emptyFilters' ]
46 this.resetButton
.connect( this, { click
: 'onResetButtonClick' } );
47 this.model
.connect( this, { itemUpdate
: 'onModelItemUpdate' } );
48 // Add the filterInput as trigger
49 this.filterInput
.$input
50 .on( 'focus', this.focus
.bind( this ) );
53 this.$content
.append( this.emptyFilterMessage
.$element
);
56 // The content and button should appear side by side regardless of how
57 // wide the button is; the button also changes its width depending
58 // on language and its state, so the safest way to present both side
59 // by side is with a table layout
61 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-table' )
64 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-row' )
67 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content' )
68 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
69 .append( this.$content
),
71 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
72 .append( this.resetButton
.$element
)
78 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget' );
80 this.reevaluateResetRestoreState();
85 OO
.inheritClass( mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
, OO
.ui
.CapsuleMultiselectWidget
);
91 * @param {string[]} filters Array of names of removed filters
93 * Filters were removed
99 * Respond to model itemUpdate event
101 * @param {mw.rcfilters.dm.FilterItem} item Filter item model
103 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.onModelItemUpdate = function ( item
) {
104 if ( item
.isSelected() ) {
105 this.addItemByName( item
.getName() );
107 this.removeItemByName( item
.getName() );
110 // Re-evaluate reset state
111 this.reevaluateResetRestoreState();
115 * Respond to click event on the reset button
117 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.onResetButtonClick = function () {
118 if ( this.model
.areCurrentFiltersEmpty() ) {
119 // Reset to default filters
120 this.controller
.resetToDefaults();
122 // Reset to have no filters
123 this.controller
.emptyFilters();
128 * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
130 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.reevaluateResetRestoreState = function () {
131 var defaultsAreEmpty
= this.model
.areDefaultFiltersEmpty(),
132 currFiltersAreEmpty
= this.model
.areCurrentFiltersEmpty(),
133 hideResetButton
= currFiltersAreEmpty
&& defaultsAreEmpty
;
135 this.resetButton
.setIcon(
136 currFiltersAreEmpty
? 'history' : 'trash'
139 this.resetButton
.setLabel(
140 currFiltersAreEmpty
? mw
.msg( 'rcfilters-restore-default-filters' ) : ''
143 this.resetButton
.toggle( !hideResetButton
);
144 this.emptyFilterMessage
.toggle( currFiltersAreEmpty
);
150 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.createItemWidget = function ( data
) {
151 var item
= this.model
.getItemByName( data
);
157 return new mw
.rcfilters
.ui
.CapsuleItemWidget(
160 { $overlay
: this.$overlay
}
165 * Add items by their filter name
167 * @param {string} name Filter name
169 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.addItemByName = function ( name
) {
170 var item
= this.model
.getItemByName( name
);
176 // Check that the item isn't already added
177 if ( !this.getItemFromData( name
) ) {
178 this.addItems( [ this.createItemWidget( name
) ] );
183 * Remove items by their filter name
185 * @param {string} name Filter name
187 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.removeItemByName = function ( name
) {
188 this.removeItemsFromData( [ name
] );
194 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.focus = function () {
195 // Override this method; we don't want to focus on the popup, and we
196 // don't want to bind the size to the handle.
197 if ( !this.isDisabled() ) {
198 this.popup
.toggle( true );
199 this.filterInput
.$input
.get( 0 ).focus();
207 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.onFocusForPopup = function () {
208 // HACK can be removed once I21b8cff4048 is merged in oojs-ui
215 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.onKeyDown = function () {};
220 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.onPopupFocusOut = function () {};
225 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.clearInput = function () {
226 if ( this.filterInput
) {
227 this.filterInput
.setValue( '' );
229 this.menu
.toggle( false );
230 this.menu
.selectItem();
231 this.menu
.highlightItem();
237 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.prototype.removeItems = function ( items
) {
239 mw
.rcfilters
.ui
.FilterCapsuleMultiselectWidget
.parent
.prototype.removeItems
.call( this, items
);
241 // Destroy the item widget when it is removed
242 // This is done because we re-add items by recreating them, rather than hiding them
243 // and items include popups, that will just continue to be created and appended
245 items
.forEach( function ( widget
) {
250 }( mediaWiki
, jQuery
) );