this.conflicts = config.conflicts || {};
this.defaultParams = {};
+ this.defaultFilters = {};
this.aggregate( { update: 'filterItemUpdate' } );
this.connect( this, { filterItemUpdate: 'onFilterItemUpdate' } );
var subsetNames = [],
filterItem = new mw.rcfilters.dm.FilterItem( filter.name, model, {
group: model.getName(),
+ useDefaultAsBaseValue: !!filter.useDefaultAsBaseValue,
label: filter.label || filter.name,
description: filter.description || '',
labelPrefixKey: model.labelPrefixKey,
items.push( filterItem );
// Store default parameter state; in this case, default is defined per filter
- if ( model.getType() === 'send_unselected_if_any' ) {
+ if (
+ model.getType() === 'send_unselected_if_any' ||
+ model.getType() === 'boolean'
+ ) {
// Store the default parameter state
// For this group type, parameter values are direct
// We need to convert from a boolean to a string ('1' and '0')
// or select the first option
this.selectItemByParamName( defaultParam );
}
+
+ // Store default filter state based on default params
+ this.defaultFilters = this.getFilterRepresentation( this.getDefaultParams() );
+
+ // Check for filters that should be initially selected by their default value
+ this.getItems().forEach( function ( item ) {
+ if (
+ item.isUsingDefaultAsBaseValue() &&
+ (
+ // This setting can only be applied to these groups
+ // the other groups are way too complex for that
+ model.getType() === 'single_option' ||
+ model.getType() === 'boolean'
+ )
+ ) {
+ // Apply selection
+ item.toggleSelected( !!model.defaultFilters[ item.getName() ] );
+ }
+ } );
};
/**
return this.defaultParams;
};
+ /**
+ * Get the default filter state of this group
+ *
+ * @return {Object} Default filter state
+ */
+ mw.rcfilters.dm.FilterGroup.prototype.getDefaultFilters = function () {
+ return this.defaultFilters;
+ };
+
/**
* This is for a single_option and string_options group types
* it returns the value of the default
var values,
areAnySelected = false,
buildFromCurrentState = !filterRepresentation,
+ defaultFilters = this.getDefaultFilters(),
result = {},
model = this,
filterParamNames = {},
} else if ( !filterRepresentation[ item.getName() ] ) {
// We are given a filter representation, but we have to make
// sure that we fill in the missing filters if there are any
- // we will assume they are all falsey
- filterRepresentation[ item.getName() ] = false;
+ // we will assume they are all falsey, unless they have
+ // isUsingDefaultAsBaseValue, in which case they get their
+ // default state
+ if (
+ item.isUsingDefaultAsBaseValue() &&
+ (
+ // This setting can only be applied to these groups
+ // the other groups are way too complex for that
+ model.getType() === 'single_option' ||
+ model.getType() === 'boolean'
+ )
+ ) {
+ filterRepresentation[ item.getName() ] = !!defaultFilters[ item.getName() ];
+ } else {
+ filterRepresentation[ item.getName() ] = false;
+ }
}
if ( filterRepresentation[ item.getName() ] ) {
} );
// Build result
- if ( this.getType() === 'send_unselected_if_any' ) {
+ if (
+ this.getType() === 'send_unselected_if_any' ||
+ this.getType() === 'boolean'
+ ) {
// First, check if any of the items are selected at all.
// If none is selected, we're treating it as if they are
// all false
// Go over the items and define the correct values
$.each( filterRepresentation, function ( name, value ) {
// We must store all parameter values as strings '0' or '1'
- result[ filterParamNames[ name ] ] = areAnySelected ?
- String( Number( !value ) ) :
- '0';
+ if ( model.getType() === 'send_unselected_if_any' ) {
+ result[ filterParamNames[ name ] ] = areAnySelected ?
+ String( Number( !value ) ) :
+ '0';
+ } else if ( model.getType() === 'boolean' ) {
+ // Representation is straight-forward and direct from
+ // the parameter value to the filter state
+ result[ filterParamNames[ name ] ] = String( Number( !!value ) );
+ }
} );
} else if ( this.getType() === 'string_options' ) {
values = [];
* Get the filter representation this group would provide
* based on given parameter states.
*
- * @param {Object|string} [paramRepresentation] An object defining a parameter
+ * @param {Object} [paramRepresentation] An object defining a parameter
* state to translate the filter state from. If not given, an object
* representing all filters as falsey is returned; same as if the parameter
* given were an empty object, or had some of the filters missing.
* @return {Object} Filter representation
*/
mw.rcfilters.dm.FilterGroup.prototype.getFilterRepresentation = function ( paramRepresentation ) {
- var areAnySelected, paramValues, defaultValue, item,
+ var areAnySelected, paramValues, defaultValue, item, currentValue,
oneWasSelected = false,
+ defaultParams = this.getDefaultParams(),
+ defaultFilters = this.getDefaultFilters(),
+ expandedParams = $.extend( true, {}, paramRepresentation ),
model = this,
paramToFilterMap = {},
result = {};
- if ( this.getType() === 'send_unselected_if_any' ) {
- paramRepresentation = paramRepresentation || {};
- // Expand param representation to include all filters in the group
+ paramRepresentation = paramRepresentation || {};
+ if (
+ this.getType() === 'send_unselected_if_any' ||
+ this.getType() === 'boolean'
+ ) {
+ // Go over param representation; map and check for selections
this.getItems().forEach( function ( filterItem ) {
var paramName = filterItem.getParamName();
- paramRepresentation[ paramName ] = paramRepresentation[ paramName ] || '0';
+ expandedParams[ paramName ] = paramRepresentation[ paramName ] || '0';
paramToFilterMap[ paramName ] = filterItem;
if ( Number( paramRepresentation[ filterItem.getParamName() ] ) ) {
}
} );
- $.each( paramRepresentation, function ( paramName, paramValue ) {
- var filterItem = paramToFilterMap[ paramName ];
-
- // Flip the definition between the parameter
- // state and the filter state
- // This is what the 'toggleSelected' value of the filter is
- result[ filterItem.getName() ] = areAnySelected ?
- !Number( paramValue ) :
- // Otherwise, there are no selected items in the
- // group, which means the state is false
- false;
+ $.each( expandedParams, function ( paramName, paramValue ) {
+ var value = paramValue,
+ filterItem = paramToFilterMap[ paramName ];
+
+ if ( model.getType() === 'send_unselected_if_any' ) {
+ // Flip the definition between the parameter
+ // state and the filter state
+ // This is what the 'toggleSelected' value of the filter is
+ result[ filterItem.getName() ] = areAnySelected ?
+ !Number( paramValue ) :
+ // Otherwise, there are no selected items in the
+ // group, which means the state is false
+ false;
+ } else if ( model.getType() === 'boolean' ) {
+ // Straight-forward definition of state
+ if (
+ filterItem.isUsingDefaultAsBaseValue() &&
+ paramRepresentation[ filterItem.getParamName() ] === undefined
+ ) {
+ value = defaultParams[ filterItem.getParamName() ];
+ }
+ result[ filterItem.getName() ] = !!Number( value );
+ }
} );
} else if ( this.getType() === 'string_options' ) {
- paramRepresentation = paramRepresentation || '';
+ currentValue = paramRepresentation[ this.getName() ] || '';
// Normalize the given parameter values
paramValues = mw.rcfilters.utils.normalizeParamOptions(
// Given
- paramRepresentation.split(
+ currentValue.split(
this.getSeparator()
),
// Allowed values
} else if ( this.getType() === 'single_option' ) {
// There is parameter that fits a single filter and if not, get the default
this.getItems().forEach( function ( filterItem ) {
- result[ filterItem.getName() ] = filterItem.getParamName() === paramRepresentation;
- oneWasSelected = oneWasSelected || filterItem.getParamName() === paramRepresentation;
+ var selected = false;
+
+ if (
+ filterItem.isUsingDefaultAsBaseValue() &&
+ paramRepresentation[ model.getName() ] === undefined
+ ) {
+ selected = !!Number( paramRepresentation[ model.getName() ] );
+ } else {
+ selected = filterItem.getParamName() === paramRepresentation[ model.getName() ];
+ }
+ result[ filterItem.getName() ] = selected;
+ oneWasSelected = oneWasSelected || selected;
} );
}
// Go over result and make sure all filters are represented.
// If any filters are missing, they will get a falsey value
this.getItems().forEach( function ( filterItem ) {
- result[ filterItem.getName() ] = !!result[ filterItem.getName() ];
+ if (
+ (
+ // This setting can only be applied to these groups
+ // the other groups are way too complex for that
+ model.getType() === 'single_option' ||
+ model.getType() === 'boolean'
+ ) &&
+ result[ filterItem.getName() ] === undefined &&
+ filterItem.isUsingDefaultAsBaseValue()
+ ) {
+ result[ filterItem.getName() ] = !!defaultFilters[ filterItem.getName() ];
+ }
oneWasSelected = oneWasSelected || !!result[ filterItem.getName() ];
} );
{ name: 'option2', label: 'group5option2-label', description: 'group5option2-desc' },
{ name: 'option3', label: 'group5option3-label', description: 'group5option3-desc' }
]
+ }, {
+ name: 'group6',
+ type: 'boolean',
+ filters: [
+ { name: 'group6option1', label: 'group6option1-label', description: 'group5option1-desc' },
+ { name: 'group6option2', label: 'group6option2-label', description: 'group5option2-desc', default: true, useDefaultAsBaseValue: true },
+ { name: 'group6option3', label: 'group6option3-label', description: 'group5option3-desc', default: true }
+ ]
} ],
viewsDefinition = {
namespaces: {
group3: 'filter8',
group4: 'option2',
group5: 'option1',
+ group6option1: '0',
+ group6option2: '1',
+ group6option3: '1',
namespace: ''
},
baseParamRepresentation = {
group3: '',
group4: 'option2',
group5: 'option1',
+ group6option1: '0',
+ group6option2: '1',
+ group6option3: '0',
namespace: ''
},
baseFilterRepresentation = {
group5__option1: true, // No default set, first item is default value
group5__option2: false,
group5__option3: false,
+ group6__group6option1: false,
+ group6__group6option2: true,
+ group6__group6option3: false,
namespace__0: false,
namespace__1: false,
namespace__2: false,
group5__option1: { selected: true, conflicted: false, included: false },
group5__option2: { selected: false, conflicted: false, included: false },
group5__option3: { selected: false, conflicted: false, included: false },
+ group6__group6option1: { selected: false, conflicted: false, included: false },
+ group6__group6option2: { selected: true, conflicted: false, included: false },
+ group6__group6option3: { selected: false, conflicted: false, included: false },
namespace__0: { selected: false, conflicted: false, included: false },
namespace__1: { selected: false, conflicted: false, included: false },
namespace__2: { selected: false, conflicted: false, included: false },