all files / src/src/widgets/ CheckboxInputWidget.js

74.6% Statements 47/63
60% Branches 18/30
63.64% Functions 7/11
74.6% Lines 47/63
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229                                                                                        964×     964×     964×           964×           964×       964× 964×                                                     336× 336× 336×   336×                 628×                                               2014× 2014× 964× 964× 964× 964× 964×           2014× 964× 964×   2014×                   636× 636×     636×                     1928× 1928× 964× 964× 964×         1928×                                                         336× 336×        
/**
 * CheckboxInputWidgets, like HTML checkboxes, can be selected and/or configured with a value.
 * Note that these {@link OO.ui.InputWidget input widgets} are best laid out
 * in {@link OO.ui.FieldLayout field layouts} that use the {@link OO.ui.FieldLayout#align inline}
 * alignment. For more information, please see the [OOUI documentation on MediaWiki][1].
 *
 * This widget can be used inside an HTML form, such as a OO.ui.FormLayout.
 *
 * [1]: https://www.mediawiki.org/wiki/OOUI/Widgets/Inputs
 *
 *     @example
 *     // An example of selected, unselected, and disabled checkbox inputs.
 *     const checkbox1 = new OO.ui.CheckboxInputWidget( {
 *             value: 'a',
 *              selected: true
 *         } ),
 *         checkbox2 = new OO.ui.CheckboxInputWidget( {
 *             value: 'b'
 *         } ),
 *         checkbox3 = new OO.ui.CheckboxInputWidget( {
 *             value:'c',
 *             disabled: true
 *         } ),
 *         // Create a fieldset layout with fields for each checkbox.
 *         fieldset = new OO.ui.FieldsetLayout( {
 *             label: 'Checkboxes'
 *         } );
 *     fieldset.addItems( [
 *         new OO.ui.FieldLayout( checkbox1, { label: 'Selected checkbox', align: 'inline' } ),
 *         new OO.ui.FieldLayout( checkbox2, { label: 'Unselected checkbox', align: 'inline' } ),
 *         new OO.ui.FieldLayout( checkbox3, { label: 'Disabled checkbox', align: 'inline' } ),
 *     ] );
 *     $( document.body ).append( fieldset.$element );
 *
 * @class
 * @extends OO.ui.InputWidget
 *
 * @constructor
 * @param {Object} [config] Configuration options
 * @param {boolean} [config.selected=false] Select the checkbox initially. By default, the checkbox is
 *  not selected.
 * @param {boolean} [config.indeterminate=false] Whether the checkbox is in the indeterminate state.
 */
OO.ui.CheckboxInputWidget = function OoUiCheckboxInputWidget( config ) {
	// Configuration initialization
	config = config || {};
 
	// Parent constructor
	OO.ui.CheckboxInputWidget.super.call( this, config );
 
	// Mixin constructors
	OO.ui.mixin.RequiredElement.call( this, $.extend( {}, {
		// TODO: Display the required indicator somewhere
		indicatorElement: null
	}, config ) );
 
	// Properties
	this.checkIcon = new OO.ui.IconWidget( {
		icon: 'check',
		classes: [ 'oo-ui-checkboxInputWidget-checkIcon' ]
	} );
 
	// Initialization
	this.$element
		.addClass( 'oo-ui-checkboxInputWidget' )
		// Required for pretty styling in WikimediaUI theme
		.append( this.checkIcon.$element );
	this.setSelected( config.selected !== undefined ? config.selected : false );
	this.setIndeterminate( config.indeterminate !== undefined ? config.indeterminate : false );
};
 
/* Setup */
 
OO.inheritClass( OO.ui.CheckboxInputWidget, OO.ui.InputWidget );
OO.mixinClass( OO.ui.CheckboxInputWidget, OO.ui.mixin.RequiredElement );
 
/* Events */
 
/**
 * A change event is emitted when the state of the input changes.
 *
 * @event OO.ui.CheckboxInputWidget#change
 * @param {boolean} selected
 * @param {boolean} indeterminate
 */
 
/* Static Properties */
 
/**
 * @inheritdoc
 */
OO.ui.CheckboxInputWidget.static.tagName = 'span';
 
/* Static Methods */
 
/**
 * @inheritdoc
 */
OO.ui.CheckboxInputWidget.static.gatherPreInfuseState = function ( node, config ) {
	const state = OO.ui.CheckboxInputWidget.super.static.gatherPreInfuseState( node, config );
	Eif ( config.$input ) {
		state.checked = config.$input.prop( 'checked' );
	}
	return state;
};
 
/* Methods */
 
/**
 * @inheritdoc
 * @protected
 */
OO.ui.CheckboxInputWidget.prototype.getInputElement = function () {
	return $( '<input>' ).attr( 'type', 'checkbox' );
};
 
/**
 * @inheritdoc
 */
OO.ui.CheckboxInputWidget.prototype.onEdit = function () {
	const widget = this;
	if ( !this.isDisabled() ) {
		// Allow the stack to clear so the value will be updated
		setTimeout( function () {
			widget.setSelected( widget.$input.prop( 'checked' ) );
			widget.setIndeterminate( widget.$input.prop( 'indeterminate' ) );
		} );
	}
};
 
/**
 * Set selection state of this checkbox.
 *
 * @param {boolean} [state=false] Selected state
 * @param {boolean} [internal=false] Used for internal calls to suppress events
 * @chainable
 * @return {OO.ui.CheckboxInputWidget} The widget, for chaining
 */
OO.ui.CheckboxInputWidget.prototype.setSelected = function ( state, internal ) {
	state = !!state;
	if ( this.selected !== state ) {
		this.selected = state;
		this.$input.prop( 'checked', this.selected );
		Eif ( !internal ) {
			this.setIndeterminate( false, true );
			this.emit( 'change', this.selected, this.indeterminate );
		}
	}
	// The first time that the selection state is set (probably while constructing the widget),
	// remember it in defaultSelected. This property can be later used to check whether
	// the selection state of the input has been changed since it was created.
	if ( this.defaultSelected === undefined ) {
		this.defaultSelected = this.selected;
		this.$input[ 0 ].defaultChecked = this.defaultSelected;
	}
	return this;
};
 
/**
 * Check if this checkbox is selected.
 *
 * @return {boolean} Checkbox is selected
 */
OO.ui.CheckboxInputWidget.prototype.isSelected = function () {
	// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
	// it, and we won't know unless they're kind enough to trigger a 'change' event.
	const selected = this.$input.prop( 'checked' );
	Iif ( this.selected !== selected ) {
		this.setSelected( selected );
	}
	return this.selected;
};
 
/**
 * Set indeterminate state of this checkbox.
 *
 * @param {boolean} [state=false] Indeterminate state
 * @param {boolean} [internal=false] Used for internal calls to suppress events
 * @chainable
 * @return {OO.ui.CheckboxInputWidget} The widget, for chaining
 */
OO.ui.CheckboxInputWidget.prototype.setIndeterminate = function ( state, internal ) {
	state = !!state;
	if ( this.indeterminate !== state ) {
		this.indeterminate = state;
		this.$input.prop( 'indeterminate', this.indeterminate );
		Iif ( !internal ) {
			this.setSelected( false, true );
			this.emit( 'change', this.selected, this.indeterminate );
		}
	}
	return this;
};
 
/**
 * Check if this checkbox is selected.
 *
 * @return {boolean} Checkbox is selected
 */
OO.ui.CheckboxInputWidget.prototype.isIndeterminate = function () {
	// Resynchronize our internal data with DOM data. Other scripts executing on the page can modify
	// it, and we won't know unless they're kind enough to trigger a 'change' event.
	const indeterminate = this.$input.prop( 'indeterminate' );
	if ( this.indeterminate !== indeterminate ) {
		this.setIndeterminate( indeterminate );
	}
	return this.indeterminate;
};
 
/**
 * @inheritdoc
 */
OO.ui.CheckboxInputWidget.prototype.simulateLabelClick = function () {
	if ( !this.isDisabled() ) {
		this.$handle.trigger( 'click' );
	}
	this.focus();
};
 
/**
 * @inheritdoc
 */
OO.ui.CheckboxInputWidget.prototype.restorePreInfuseState = function ( state ) {
	OO.ui.CheckboxInputWidget.super.prototype.restorePreInfuseState.call( this, state );
	Iif ( state.checked !== undefined && state.checked !== this.isSelected() ) {
		this.setSelected( state.checked );
	}
};