Merge "user: Allow "CAS update failed" exceptions to be normalised"
[lhc/web/wiklou.git] / resources / src / mediawiki.htmlform / multiselect.js
1 /*
2 * HTMLForm enhancements:
3 * Convert multiselect fields from checkboxes to Chosen selector when requested.
4 */
5 ( function () {
6
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-htmlform-dropdown)/g, '' ),
10 $select = $( '<select>' ),
11 dataPlaceholder = mw.message( 'htmlform-chosen-placeholder' );
12 oldClass = oldClass.trim();
13 $select.attr( {
14 name: name,
15 multiple: 'multiple',
16 'data-placeholder': dataPlaceholder.plain(),
17 'class': 'htmlform-chzn-select mw-input ' + oldClass
18 } );
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' ) );
24 if ( checked ) {
25 $option.prop( 'selected', true );
26 }
27 $option.text( $oldInput.prop( 'value' ) );
28 $select.append( $option );
29 } );
30 $container.append( $select );
31 }
32
33 function convertCheckboxesToMulti( $oldContainer, type ) {
34 var $fieldLabel = $( '<td>' ),
35 $td = $( '<td>' ),
36 $fieldLabelText = $( '<label>' ),
37 $container;
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 );
46 }
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 );
52 return $container;
53 }
54
55 function convertCheckboxesWidgetToTags( fieldLayout ) {
56 var checkboxesWidget, checkboxesOptions, menuTagOptions, menuTagWidget;
57
58 checkboxesWidget = fieldLayout.fieldWidget;
59 checkboxesOptions = checkboxesWidget.checkboxMultiselectWidget.getItems();
60 menuTagOptions = checkboxesOptions.map( function ( option ) {
61 return new OO.ui.MenuOptionWidget( {
62 data: option.getData(),
63 label: option.getLabel()
64 } );
65 } );
66 menuTagWidget = new OO.ui.MenuTagMultiselectWidget( {
67 $overlay: true,
68 menu: {
69 items: menuTagOptions
70 }
71 } );
72 menuTagWidget.setValue( checkboxesWidget.getValue() );
73
74 // Data from CapsuleMultiselectWidget will not be submitted with the form, so keep the original
75 // CheckboxMultiselectInputWidget up-to-date.
76 menuTagWidget.on( 'change', function () {
77 checkboxesWidget.setValue( menuTagWidget.getValue() );
78 } );
79
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( menuTagWidget.$element );
84 }
85
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 () {
90 var $el = $( this ),
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' );
96 if ( data ) {
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 );
100 }
101 mw.loader.using( modules, function () {
102 convertCheckboxesWidgetToTags( OO.ui.FieldLayout.static.infuse( $el ) );
103 } );
104 } else {
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' } );
109 } );
110 }
111 } );
112 }
113 } );
114
115 }() );