Skip to content

Commit 210cc57

Browse files
author
Harris
committed
Fix #722 Adding more comments to the widget code
1 parent 23c5447 commit 210cc57

File tree

1 file changed

+87
-53
lines changed

1 file changed

+87
-53
lines changed

src/jquery.multiselect.js

Lines changed: 87 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
groupColumns: false
5050
},
5151

52+
// This method determines which element to append the menu to
53+
// Uses the element provided in the options first, then looks for ui-front / dialog
54+
// Otherwise appends to the body
5255
_getAppendEl: function() {
5356
var element = this.options.appendTo;
5457
if(element) {
@@ -63,13 +66,14 @@
6366
return element;
6467
},
6568

69+
// Performs the initial creation of the widget
6670
_create: function() {
6771
var el = this.element;
6872
var o = this.options;
6973

7074
this.speed = $.fx.speeds._default; // default speed for effects
7175
this._isOpen = false; // assume no
72-
this.inputIdCounter = 0;
76+
this.inputIdCounter = 0; // Incremented for each input item (option)
7377

7478
// create a unique namespace for events that the widget
7579
// factory cannot unbind automatically. Use eventNamespace if on
@@ -78,62 +82,68 @@
7882
// bump unique ID after assigning it to the widget instance
7983
this.multiselectID = multiselectID++;
8084

85+
// The button that opens the widget menu
8186
var button = (this.button = $('<button type="button"><span class="ui-icon ui-icon-triangle-1-s"></span></button>'))
8287
.addClass('ui-multiselect ui-widget ui-state-default ui-corner-all ' + o.classes)
8388
.attr({ 'title':el.attr('title'), 'tabIndex':el.attr('tabIndex'), 'id': el.attr('id') ? el.attr('id') + '_ms' : null })
8489
.prop('aria-haspopup', true)
8590
.insertAfter(el);
8691

87-
this.buttonlabel = $('<span />')
88-
.html(o.noneSelectedText)
89-
.appendTo(button);
90-
91-
this.menu = $('<div />')
92-
.addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all ' + o.classes)
93-
.appendTo(this._getAppendEl());
94-
95-
this.header = $('<div />')
96-
.addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix')
97-
.appendTo(this.menu);
98-
99-
this.headerLinkContainer = $('<ul />')
100-
.addClass('ui-helper-reset')
101-
.html(function() {
102-
if(o.header === true) {
103-
var header_lis = '';
104-
if(o.showCheckAll) {
105-
header_lis = '<li><a class="ui-multiselect-all" href="#"><span class="ui-icon ui-icon-check"></span><span>' + o.checkAllText + '</span></a></li>';
106-
}
107-
if(o.showUncheckAll) {
108-
header_lis += '<li><a class="ui-multiselect-none" href="#"><span class="ui-icon ui-icon-closethick"></span><span>' + o.uncheckAllText + '</span></a></li>';
109-
}
110-
return header_lis;
111-
} else if(typeof o.header === "string") {
112-
return '<li>' + o.header + '</li>';
113-
} else {
114-
return '';
92+
this.buttonlabel = $('<span />')
93+
.html(o.noneSelectedText)
94+
.appendTo(button);
95+
96+
// This is the menu that will hold all the options
97+
this.menu = $('<div />')
98+
.addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all ' + o.classes)
99+
.appendTo(this._getAppendEl());
100+
101+
// Menu header to hold controls for the menu
102+
this.header = $('<div />')
103+
.addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix')
104+
.appendTo(this.menu);
105+
106+
// Header controls, will contain the check all/uncheck all buttons
107+
// Depending on how the options are set, this may be empty or simply plain text
108+
this.headerLinkContainer = $('<ul />')
109+
.addClass('ui-helper-reset')
110+
.html(function() {
111+
if(o.header === true) {
112+
var header_lis = '';
113+
if(o.showCheckAll) {
114+
header_lis = '<li><a class="ui-multiselect-all" href="#"><span class="ui-icon ui-icon-check"></span><span>' + o.checkAllText + '</span></a></li>';
115+
}
116+
if(o.showUncheckAll) {
117+
header_lis += '<li><a class="ui-multiselect-none" href="#"><span class="ui-icon ui-icon-closethick"></span><span>' + o.uncheckAllText + '</span></a></li>';
115118
}
116-
})
117-
.append('<li class="ui-multiselect-close"><a href="#" class="ui-multiselect-close"><span class="ui-icon '+o.closeIcon+'"></span></a></li>')
118-
.appendTo(this.header);
119+
return header_lis;
120+
} else if(typeof o.header === "string") {
121+
return '<li>' + o.header + '</li>';
122+
} else {
123+
return '';
124+
}
125+
})
126+
.append('<li class="ui-multiselect-close"><a href="#" class="ui-multiselect-close"><span class="ui-icon '+o.closeIcon+'"></span></a></li>')
127+
.appendTo(this.header);
119128

120-
var checkboxContainer = (this.checkboxContainer = $('<ul />'))
121-
.addClass('ui-multiselect-checkboxes ui-helper-reset')
122-
.appendTo(this.menu);
129+
// Holds the actual check boxes for inputs
130+
var checkboxContainer = (this.checkboxContainer = $('<ul />'))
131+
.addClass('ui-multiselect-checkboxes ui-helper-reset')
132+
.appendTo(this.menu);
123133

124-
// perform event bindings
125-
this._bindEvents();
134+
this._bindEvents();
126135

127-
// build menu
128-
this.refresh(true);
136+
// build menu
137+
this.refresh(true);
129138

130-
// some addl. logic for single selects
131-
if(!o.multiple) {
132-
this.menu.addClass('ui-multiselect-single');
133-
}
134-
el.hide();
139+
// If this is a single select widget, add the appropriate class
140+
if(!o.multiple) {
141+
this.menu.addClass('ui-multiselect-single');
142+
}
143+
el.hide();
135144
},
136145

146+
// https://api.jqueryui.com/jquery.widget/#method-_init
137147
_init: function() {
138148
if(this.options.header === false) {
139149
this.header.hide();
@@ -151,6 +161,15 @@
151161
}
152162
},
153163

164+
/*
165+
* Builds an option item for the menu
166+
* <li>
167+
* <label>
168+
* <input /> checkbox or radio depending on single/multiple select
169+
* <span /> option text
170+
* </label>
171+
* </li>
172+
*/
154173
_makeOption: function(option) {
155174
var title = option.title ? option.title : null;
156175
var value = option.value;
@@ -198,7 +217,8 @@
198217

199218
return $item;
200219
},
201-
220+
// Builds a menu item for each option in the underlying select
221+
// Option groups are built here as well
202222
_buildOptionList: function(element, $appendTo) {
203223
var self = this;
204224
element.children().each(function() {
@@ -217,13 +237,14 @@
217237

218238
},
219239

240+
// Refreshes the widget to pick up changes to the underlying select
241+
// Rebuilds the menu, sets button width
220242
refresh: function(init) {
221243
var self = this;
222244
var el = this.element;
223245
var o = this.options;
224246
var menu = this.menu;
225247
var checkboxContainer = this.checkboxContainer;
226-
var html = "";
227248
var $dropdown = $("<ul/>").addClass('ui-multiselect-checkboxes ui-helper-reset');
228249
this.inputIdCounter = 0;
229250

@@ -284,7 +305,7 @@
284305
},
285306

286307
// this exists as a separate method so that the developer
287-
// can easily override it.
308+
// can easily override it, usually to allow injecting HTML if they really want it
288309
_setButtonValue: function(value) {
289310
this.buttonlabel.text(value);
290311
},
@@ -398,15 +419,15 @@
398419
self._traverse(e.which, this);
399420
break;
400421
case 13: // enter
401-
case 32:
422+
case 32: //space
402423
$(this).find('input')[0].click();
403424
break;
404-
case 65:
425+
case 65: // a
405426
if(e.altKey) {
406427
self.checkAll();
407428
}
408429
break;
409-
case 85:
430+
case 85: // u
410431
if(e.altKey) {
411432
self.uncheckAll();
412433
}
@@ -475,10 +496,10 @@
475496
e.preventDefault();
476497
}).on('keydown.multiselect', 'a', function(e) {
477498
switch(e.which) {
478-
case 27:
499+
case 27: // esc
479500
self.close();
480501
break;
481-
case 9:
502+
case 9: // tab
482503
var $target = $(e.target);
483504
if((e.shiftKey && !$target.parent().prev().length && !self.header.find(".ui-multiselect-filter").length) || (!$target.parent().next().length && !self.labels.length && !e.shiftKey)) {
484505
self.close();
@@ -489,7 +510,6 @@
489510
});
490511
},
491512

492-
// binds events
493513
_bindEvents: function() {
494514
var self = this;
495515

@@ -519,6 +539,9 @@
519539
setTimeout($.proxy(self.refresh, self), 10);
520540
});
521541
},
542+
543+
// Determines the minimum width for the button and menu
544+
// Can be a number, a digit string, or a percentage
522545
_getMinWidth: function() {
523546
var minVal = this.options.minWidth;
524547
var width = 0;
@@ -557,6 +580,8 @@
557580
m.outerWidth(this.options.menuWidth || width);
558581
},
559582

583+
// Sets the height of the menu
584+
// Will set a scroll bar if the menu height exceeds that of the height in options
560585
_setMenuHeight: function() {
561586
var headerHeight = this.menu.children(".ui-multiselect-header:visible").outerHeight(true);
562587
var ulHeight = 0;
@@ -574,6 +599,7 @@
574599
this.menu.height(ulHeight + headerHeight);
575600
},
576601

602+
// Resizes the menu, called every time the menu is opened
577603
_resizeMenu: function() {
578604
this._setMenuWidth();
579605
this._setMenuHeight();
@@ -624,6 +650,7 @@
624650
};
625651
},
626652

653+
// Toggles checked state on either an option group or all inputs
627654
_toggleChecked: function(flag, group) {
628655
var $inputs = (group && group.length) ? group : this.inputs;
629656
var self = this;
@@ -658,6 +685,7 @@
658685
}
659686
},
660687

688+
// Toggle disable state on the widget and underlying select
661689
_toggleDisabled: function(flag) {
662690
this.button.prop({ 'disabled':flag, 'aria-disabled':flag })[ flag ? 'addClass' : 'removeClass' ]('ui-state-disabled');
663691

@@ -840,6 +868,12 @@
840868
return this.labels;
841869
},
842870

871+
/*
872+
* Adds an option to the widget and underlying select
873+
* attributes: Attributes hash to add to the option
874+
* text: text of the option
875+
* groupLabel: Option Group to add the option to
876+
*/
843877
addOption: function(attributes, text, groupLabel) {
844878
var $option = $("<option/>").attr(attributes).text(text);
845879
var optionNode = $option.get(0);

0 commit comments

Comments
 (0)