2 * HTMLForm enhancements:
3 * Convert multiselect fields from checkboxes to Chosen selector when requested.
7 function addMulti( $oldContainer
, $container
) {
8 var name
= $oldContainer
.find( 'input:first-child' ).attr( 'name' ),
9 oldClass
= ( ' ' + $oldContainer
.attr( 'class' ) + ' ' ).replace( /(mw-htmlform-field-HTMLMultiSelectField|mw-chosen|mw-htmlform-dropdown)/g, '' ),
10 $select
= $( '<select>' ),
11 dataPlaceholder
= mw
.message( 'htmlform-chosen-placeholder' );
12 oldClass
= $.trim( oldClass
);
16 'data-placeholder': dataPlaceholder
.plain(),
17 'class': 'htmlform-chzn-select mw-input ' + oldClass
19 $oldContainer
.find( 'input' ).each( function () {
20 var $oldInput
= $( this ),
21 checked
= $oldInput
.prop( 'checked' ),
22 $option
= $( '<option>' );
23 $option
.prop( 'value', $oldInput
.prop( 'value' ) );
25 $option
.prop( 'selected', true );
27 $option
.text( $oldInput
.prop( 'value' ) );
28 $select
.append( $option
);
30 $container
.append( $select
);
33 function convertCheckboxesToMulti( $oldContainer
, type
) {
34 var $fieldLabel
= $( '<td>' ),
36 $fieldLabelText
= $( '<label>' ),
38 if ( type
=== 'tr' ) {
39 addMulti( $oldContainer
, $td
);
40 $container
= $( '<tr>' );
41 $container
.append( $td
);
42 } else if ( type
=== 'div' ) {
43 $fieldLabel
= $( '<div>' );
44 $container
= $( '<div>' );
45 addMulti( $oldContainer
, $container
);
47 $fieldLabel
.attr( 'class', 'mw-label' );
48 $fieldLabelText
.text( $oldContainer
.find( '.mw-label label' ).text() );
49 $fieldLabel
.append( $fieldLabelText
);
50 $container
.prepend( $fieldLabel
);
51 $oldContainer
.replaceWith( $container
);
55 function convertCheckboxesWidgetToCapsules( fieldLayout
) {
56 var checkboxesWidget
, checkboxesOptions
, capsulesOptions
, capsulesWidget
;
58 checkboxesWidget
= fieldLayout
.fieldWidget
;
59 checkboxesOptions
= checkboxesWidget
.checkboxMultiselectWidget
.getItems();
60 capsulesOptions
= checkboxesOptions
.map( function ( option
) {
61 return new OO
.ui
.MenuOptionWidget( {
62 data
: option
.getData(),
63 label
: option
.getLabel()
66 capsulesWidget
= new OO
.ui
.CapsuleMultiselectWidget( {
69 items
: capsulesOptions
72 capsulesWidget
.setItemsFromData( checkboxesWidget
.getValue() );
74 // Data from CapsuleMultiselectWidget will not be submitted with the form, so keep the original
75 // CheckboxMultiselectInputWidget up-to-date.
76 capsulesWidget
.on( 'change', function () {
77 checkboxesWidget
.setValue( capsulesWidget
.getItemsData() );
80 // Hide original widget and add new one in its place. This is a bit hacky, since the FieldLayout
81 // still thinks it's connected to the old widget.
82 checkboxesWidget
.toggle( false );
83 checkboxesWidget
.$element
.after( capsulesWidget
.$element
);
86 mw
.hook( 'htmlform.enhance' ).add( function ( $root
) {
87 var $dropdowns
= $root
.find( '.mw-htmlform-field-HTMLMultiSelectField.mw-htmlform-dropdown' );
88 if ( $dropdowns
.length
) {
89 $dropdowns
.each( function () {
91 data
, modules
, extraModules
;
92 if ( $el
.is( '[data-ooui]' ) ) {
93 // Load 'oojs-ui-widgets' for CapsuleMultiselectWidget
94 modules
= [ 'mediawiki.htmlform.ooui', 'oojs-ui-widgets' ];
95 data
= $el
.data( 'mw-modules' );
97 // We can trust this value, 'data-mw-*' attributes are banned from user content in Sanitizer
98 extraModules
= data
.split( ',' );
99 modules
.push
.apply( modules
, extraModules
);
101 mw
.loader
.using( modules
, function () {
102 convertCheckboxesWidgetToCapsules( OO
.ui
.FieldLayout
.static.infuse( $el
) );
105 mw
.loader
.using( 'jquery.chosen', function () {
106 var type
= $el
.is( 'tr' ) ? 'tr' : 'div',
107 $converted
= convertCheckboxesToMulti( $el
, type
);
108 $converted
.find( '.htmlform-chzn-select' ).chosen( { width
: 'auto' } );
115 }( mediaWiki
, jQuery
) );