HTMLCheckMatrix: Treat row/column labels as HTML in OOUI mode
[lhc/web/wiklou.git] / resources / src / mediawiki.widgets / mw.widgets.CheckMatrixWidget.js
1 ( function ( $, mw ) {
2 /**
3 * A JavaScript version of CheckMatrixWidget.
4 *
5 * @class
6 * @extends OO.ui.Widget
7 *
8 * @constructor
9 * @param {Object} [config] Configuration options
10 * @cfg {Object} columns Required object mapping column labels (as HTML) to
11 * their tags.
12 * @cfg {Object} rows Required object mapping row labels (as HTML) to their
13 * tags.
14 * @cfg {string[]} [forcedOn] Array of column-row tags to be displayed as
15 * enabled but unavailable to change.
16 * @cfg {string[]} [forcedOff] Array of column-row tags to be displayed as
17 * disabled but unavailable to change.
18 * @cfg {Object} [tooltips] Optional object mapping row labels to tooltips
19 * (as text, will be escaped).
20 */
21 mw.widgets.CheckMatrixWidget = function MWWCheckMatrixWidget( config ) {
22 var $headRow = $( '<tr>' ),
23 $table = $( '<table>' ),
24 widget = this;
25 config = config || {};
26
27 // Parent constructor
28 mw.widgets.CheckMatrixWidget.parent.call( this, config );
29 this.checkboxes = {};
30 this.name = config.name;
31 this.id = config.id;
32 this.rows = config.rows || {};
33 this.columns = config.columns || {};
34 this.tooltips = config.tooltips || [];
35 this.values = config.values || [];
36 this.forcedOn = config.forcedOn || [];
37 this.forcedOff = config.forcedOff || [];
38
39 // Build header
40 $headRow.append( $( '<td>' ).text( '\u00A0' ) );
41
42 // Iterate over the columns object (ignore the value)
43 $.each( this.columns, function ( columnLabel ) {
44 $headRow.append( $( '<td>' ).html( columnLabel ) );
45 } );
46 $table.append( $headRow );
47
48 // Build table
49 $.each( this.rows, function ( rowLabel, rowTag ) {
50 var $row = $( '<tr>' ),
51 labelField = new OO.ui.FieldLayout(
52 new OO.ui.Widget(), // Empty widget, since we don't have the checkboxes here
53 {
54 label: new OO.ui.HtmlSnippet( rowLabel ),
55 help: widget.tooltips[ rowLabel ],
56 align: 'inline'
57 }
58 );
59
60 // Label
61 $row.append( $( '<td>' ).append( labelField.$element ) );
62
63 // Columns
64 $.each( widget.columns, function ( columnLabel, columnTag ) {
65 var thisTag = columnTag + '-' + rowTag,
66 checkbox = new OO.ui.CheckboxInputWidget( {
67 value: thisTag,
68 name: widget.name ? widget.name + '[]' : undefined,
69 id: widget.id ? widget.id + '-' + thisTag : undefined,
70 selected: widget.isTagSelected( thisTag ),
71 disabled: widget.isTagDisabled( thisTag )
72 } );
73
74 widget.checkboxes[ thisTag ] = checkbox;
75 $row.append( $( '<td>' ).append( checkbox.$element ) );
76 } );
77
78 $table.append( $row );
79 } );
80
81 this.$element
82 .addClass( 'mw-widget-checkMatrixWidget' )
83 .append( $table );
84 };
85
86 /* Setup */
87
88 OO.inheritClass( mw.widgets.CheckMatrixWidget, OO.ui.Widget );
89
90 /* Methods */
91
92 /**
93 * Check whether the given tag is selected
94 *
95 * @param {string} tagName Tag name
96 * @return {boolean} Tag is selected
97 */
98 mw.widgets.CheckMatrixWidget.prototype.isTagSelected = function ( tagName ) {
99 return (
100 // If tag is not forced off
101 this.forcedOff.indexOf( tagName ) === -1 &&
102 (
103 // If tag is in values
104 this.values.indexOf( tagName ) > -1 ||
105 // If tag is forced on
106 this.forcedOn.indexOf( tagName ) > -1
107 )
108 );
109 };
110
111 /**
112 * Check whether the given tag is disabled
113 *
114 * @param {string} tagName Tag name
115 * @return {boolean} Tag is disabled
116 */
117 mw.widgets.CheckMatrixWidget.prototype.isTagDisabled = function ( tagName ) {
118 return (
119 // If the entire widget is disabled
120 this.isDisabled() ||
121 // If tag is forced off or forced on
122 this.forcedOff.indexOf( tagName ) > -1 ||
123 this.forcedOn.indexOf( tagName ) > -1
124 );
125 };
126 /**
127 * @inheritdoc
128 */
129 mw.widgets.CheckMatrixWidget.prototype.setDisabled = function ( isDisabled ) {
130 var widget = this;
131
132 // Parent method
133 mw.widgets.CheckMatrixWidget.parent.prototype.setDisabled.call( this, isDisabled );
134
135 // setDisabled sometimes gets called before the widget is ready
136 if ( this.checkboxes && Object.keys( this.checkboxes ).length > 0 ) {
137 // Propagate to all checkboxes and update their disabled state
138 $.each( this.checkboxes, function ( name, checkbox ) {
139 checkbox.setDisabled( widget.isTagDisabled( name ) );
140 } );
141 }
142 };
143 }( jQuery, mediaWiki ) );