From a474e1626309f74bf5df23ab03d0c7596f8042ab Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 13:55:45 -0800
Subject: [PATCH 01/12] $variable and more comments
Mostly changing to $naming scheme for jQuery objects and adding more comments.
---
src/jquery.multiselect.js | 419 +++++++++++++++++++-------------------
1 file changed, 204 insertions(+), 215 deletions(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index 7bd32d5..ddaeaf7 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -1,11 +1,11 @@
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */
/*
- * jQuery MultiSelect UI Widget 2.0.1
+ * jQuery MultiSelect UI Widget 3.0.0
* Copyright (c) 2012 Eric Hynds
*
* Depends:
- * - jQuery 1.4.2+
- * - jQuery UI 1.11 widget factory
+ * - jQuery 1.7+ (http://api.jquery.com/)
+ * - jQuery UI 1.11 widget factory (http://api.jqueryui.com/jQuery.widget/)
*
* Optional:
* - jQuery UI effects
@@ -25,59 +25,59 @@
// default options
options: {
- header: true,
- height: 175,
- minWidth: 225,
- classes: '',
- openIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be used here instead of the default jQuery UI icons.
- closeIcon: ' ',
- checkAllIcon: ' ',
- uncheckAllIcon: ' ',
- flipAllIcon: ' ',
- checkAllText: 'Check all', // If blank or null, link not shown.
- uncheckAllText: 'Uncheck all', // If blank or null, link not shown.
- flipAllText: 'Flip all', // If blank or null, link not shown.
- showCheckAll: true,
- showUncheckAll: true,
- showFlipAll: false,
- noneSelectedText: 'Select options',
- selectedText: '# selected',
- selectedList: 0,
- show: null,
- hide: null,
- autoOpen: false,
- position: {},
- appendTo: null,
- menuWidth:null,
- selectedListSeparator: ', ',
- disableInputsOnToggle: true,
- groupColumns: false
+ header: true, // (true | false) If true, the header is shown.
+ height: 175, // (int) Sets the height of the menu.
+ minWidth: 225, // (int) Sets the minimum width of the menu.
+ classes: '', // Classes that you can provide to be applied to the elements making up the widget.
+ openIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ closeIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ checkAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ uncheckAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ flipAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ checkAllText: 'Check all', // (str | blank | null) If blank or null, link not shown.
+ uncheckAllText: 'Uncheck all', // (str | blank | null) If blank or null, link not shown.
+ flipAllText: 'Flip all', // (str | blank | null) If blank or null, link not shown.
+ showCheckAll: true, // (true | false) Show or hide the Check All link without blanking the text.
+ showUncheckAll: true, // (true | false) Show or hide the Uncheck All link without blanking the text.
+ showFlipAll: false, // (true | false) Show or hide the Flip All link without blanking the text.
+ noneSelectedText: 'Select options', // (str) The text to show in the button where nothing is selected.
+ selectedText: '# of # selected', // (str) A "template" that indicates how to show the count of selections in the button. The "#'s" are replaced by the selection count & option count.
+ selectedList: 0, // (int) The actual list selections will be shown in the button when the count of selections is <= than this number.
+ show: null, // (array) An array containing menu opening effects.
+ hide: null, // (array) An array containing menu closing effects.
+ autoOpen: false, // (true | false) If true, then the menu will be opening immediately after initialization.
+ position: {}, // (object) A jQuery UI position object that constrains how the pop-up menu is positioned.
+ appendTo: null, // (jQuery | DOM element | selector str) If provided, this specifies what element to append the widget to in the DOM.
+ menuWidth:null, // (int | null) If a number is provided, sets the menu width.
+ selectedListSeparator: ', ', // (str) This allows customization of the list separator. Use ', ' to make the button grow vertically showing 1 selection per line.
+ disableInputsOnToggle: true, // (true | false)
+ groupColumns: false // (true | false)
},
// This method determines which element to append the menu to
// Uses the element provided in the options first, then looks for ui-front / dialog
// Otherwise appends to the body
_getAppendEl: function() {
- var element = this.options.appendTo;
- if(element) {
- element = element.jquery || element.nodeType ? $(element) : this.document.find(element).eq(0);
+ var elem = this.options.appendTo; // jQuery object, DOM element, OR selector str.
+ if(elem) {
+ elem = elem.jquery || elem.nodeType ? $(elem) : this.document.find(elem).eq(0); // Note that the find handles the selector case.
}
- if(!element || !element[0]) {
- element = this.element.closest(".ui-front, dialog");
+ if(!elem || !elem[0]) {
+ elem = this.element.closest(".ui-front, dialog");
}
- if(!element.length) {
- element = this.document[0].body;
+ if(!elem.length) {
+ elem = this.document[0].body; // Position at end of body.
}
- return element;
+ return elem;
},
// Performs the initial creation of the widget
_create: function() {
- var el = this.element;
+ var $el = this.element.hide(); // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
var o = this.options;
this.speed = $.fx.speeds._default; // default speed for effects
- this._isOpen = false; // assume no
+ this._isOpen = false; // assume no
this.inputIdCounter = 0;
// create a unique namespace for events that the widget
@@ -87,30 +87,31 @@
// bump unique ID after assigning it to the widget instance
this.multiselectID = multiselectID++;
- // The button that opens the widget menu
- var button = (this.button = $('' + o.openIcon + ' '))
+ // The button that opens the widget menu.
+ // The ui-multiselect-open span is necessary below to simplify dynamically changing the open icon.
+ var $button = (this.$button = $('' + o.openIcon + ' '))
.addClass('ui-multiselect ui-widget ui-state-default ui-corner-all ' + o.classes)
- .attr({ 'title':el.attr('title'), 'tabIndex':el.attr('tabIndex'), 'id': el.attr('id') ? el.attr('id') + '_ms' : null })
+ .attr({ title: $el.attr('title'), tabIndex: $el.attr('tabIndex'), id: $el.attr('id') ? $el.attr('id') + '_ms' : null })
.prop('aria-haspopup', true)
- .insertAfter(el);
+ .insertAfter($el);
- this.buttonlabel = $(' ')
+ this.$buttonlabel = $(' ')
.html(o.noneSelectedText)
- .appendTo(button);
+ .appendTo($button);
// This is the menu that will hold all the options
- this.menu = $('
')
+ var $menu = (this.$menu = $('
'))
.addClass('ui-multiselect-menu ui-widget ui-widget-content ui-corner-all ' + o.classes)
.appendTo(this._getAppendEl());
// Menu header to hold controls for the menu
- this.header = $('
')
+ var $header = (this.$header = $('
'))
.addClass('ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix')
- .appendTo(this.menu);
+ .appendTo($menu);
// Header controls, will contain the check all/uncheck all buttons
// Depending on how the options are set, this may be empty or simply plain text
- this.headerLinkContainer = $('')
+ this.$headerLinkContainer = $('')
.addClass('ui-helper-reset')
.html(function() {
if(o.header === true) {
@@ -132,12 +133,12 @@
}
})
.append('' + o.closeIcon + ' ')
- .appendTo(this.header);
+ .appendTo($header);
// Holds the actual check boxes for inputs
- var checkboxContainer = (this.checkboxContainer = $(''))
+ this.$checkboxContainer = $('')
.addClass('ui-multiselect-checkboxes ui-helper-reset')
- .appendTo(this.menu);
+ .appendTo($menu);
// perform event bindings
this._bindEvents();
@@ -146,26 +147,28 @@
this.refresh(true);
// If this is a single select widget, add the appropriate class
- if(!el[0].multiple) {
- this.menu.addClass('ui-multiselect-single');
+ if(!$el[0].multiple) {
+ $menu.addClass('ui-multiselect-single');
}
- el.hide();
},
// https://api.jqueryui.com/jquery.widget/#method-_init
_init: function() {
+ var $element = this.element;
+ var $headerLinks = this.$headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip');
+
if(this.options.header === false) {
- this.header.hide();
+ this.$header.hide();
}
- if(!!this.element[0].multiple) {
- this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip').show();
+ if(!!$element[0].multiple) { // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
+ $headerLinks.show();
} else {
- this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip').hide();
+ $headerLinks.hide();
}
if(this.options.autoOpen) {
this.open();
}
- if(this.element.is(':disabled')) {
+ if(!!$element[0].disabled) {
this.disable();
}
},
@@ -180,17 +183,16 @@
*
*/
_makeOption: function(option) {
- var title = option.title ? option.title : null;
- var value = option.value;
- var el = this.element;
- var id = el.attr('id') || this.multiselectID; // unique ID for the label & option tags
+ var title = option.title || null;
+ var $element = this.element; // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
+ var id = $element[0].id || this.multiselectID; // unique ID for the label & option tags
var inputID = 'ui-multiselect-' + this.multiselectID + '-' + (option.id || id + '-option-' + this.inputIdCounter++);
var isDisabled = option.disabled;
var isSelected = option.selected;
var labelClasses = [ 'ui-corner-all' ];
var liClasses = [];
var o = this.options;
- var isMultiple = !!el[0].multiple; // Pick up the select type from the underlying element
+ var isMultiple = !!$element[0].multiple; // Pick up the select type from the underlying element
if(isDisabled) {
liClasses.push('ui-multiselect-disabled');
@@ -211,7 +213,7 @@
var $input = $(" ").attr({
"name": "multiselect_" + id,
"type": isMultiple ? "checkbox" : "radio",
- "value": value,
+ "value": option.value,
"title": title,
"id": inputID,
"checked": isSelected ? "checked" : null,
@@ -231,9 +233,9 @@
// Builds a menu item for each option in the underlying select
// Option groups are built here as well
- _buildOptionList: function(element, $appendTo) {
+ _buildOptionList: function($element, $appendTo) {
var self = this;
- element.children().each(function() {
+ $element.children().each(function() {
var $this = $(this);
if(this.tagName === 'OPTGROUP') {
var $optionGroup = $("").addClass('ui-multiselect-optgroup ' + this.className).appendTo($appendTo);
@@ -252,32 +254,30 @@
// Refreshes the widget to pick up changes to the underlying select
// Rebuilds the menu, sets button width
refresh: function(init) {
- var self = this;
- var el = this.element;
- var o = this.options;
- var menu = this.menu;
- var checkboxContainer = this.checkboxContainer;
- var html = "";
+ var $el = this.element; // "element" is a jQuery object representing the underlying select
+ var $menu = this.$menu;
+ var $headerLinks = this.$headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip');
var $dropdown = $("").addClass('ui-multiselect-checkboxes ui-helper-reset');
+
this.inputIdCounter = 0;
// update header link container visibility if needed
if (this.options.header) {
- if(!!el[0].multiple) {
- this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip').show();
+ if(!!$el[0].multiple) {
+ $headerLinks.show();
} else {
- this.headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip').hide();
+ $headerLinks.hide();
}
}
- this._buildOptionList(el, $dropdown);
+ this._buildOptionList($el, $dropdown);
- this.menu.find(".ui-multiselect-checkboxes").remove();
- this.menu.append($dropdown);
+ this.$menu.find(".ui-multiselect-checkboxes").remove();
+ this.$menu.append($dropdown);
// cache some more useful elements
- this.labels = menu.find('label');
- this.inputs = this.labels.children('input');
+ this.$labels = $menu.find('label');
+ this.$inputs = this.$labels.children('input');
this._setButtonWidth();
@@ -292,7 +292,7 @@
// updates the button text. call refresh() to rebuild
update: function(isDefault) {
var o = this.options;
- var $inputs = this.inputs;
+ var $inputs = this.$inputs;
var $checked = $inputs.filter(':checked');
var numChecked = $checked.length;
var value;
@@ -311,7 +311,7 @@
this._setButtonValue(value);
if(isDefault) {
- this.button[0].defaultValue = value;
+ this.$button[0].defaultValue = value;
}
},
@@ -319,61 +319,58 @@
// this exists as a separate method so that the developer
// can easily override it.
_setButtonValue: function(value) {
- this.buttonlabel.text(value);
+ this.$buttonlabel.text(value);
},
_bindButtonEvents: function() {
var self = this;
- var button = this.button;
+ var $button = this.$button;
function clickHandler() {
self[ self._isOpen ? 'close' : 'open' ]();
return false;
}
- // webkit doesn't like it when you click on the span :(
- button
- .find('span')
- .bind('click.multiselect', clickHandler);
-
- // button events
- button.bind({
- click: clickHandler,
- keypress: function(e) {
- switch(e.which) {
- case 27: // esc
- case 38: // up
- case 37: // left
- self.close();
- break;
- case 39: // right
- case 40: // down
- self.open();
- break;
- }
- },
- mouseenter: function() {
- if(!button.hasClass('ui-state-disabled')) {
- $(this).addClass('ui-state-hover');
- }
- },
- mouseleave: function() {
- $(this).removeClass('ui-state-hover');
- },
- focus: function() {
- if(!button.hasClass('ui-state-disabled')) {
- $(this).addClass('ui-state-focus');
- }
- },
- blur: function() {
- $(this).removeClass('ui-state-focus');
- }
- });
+ $button // button events
+ .on({
+ click: clickHandler,
+ keypress: function(e) {
+ switch(e.which) {
+ case 27: // esc
+ case 38: // up
+ case 37: // left
+ self.close();
+ break;
+ case 39: // right
+ case 40: // down
+ self.open();
+ break;
+ }
+ },
+ mouseenter: function() {
+ if(!$button.hasClass('ui-state-disabled')) {
+ $button.addClass('ui-state-hover');
+ }
+ },
+ mouseleave: function() {
+ $button.removeClass('ui-state-hover');
+ },
+ focus: function() {
+ if(!$button.hasClass('ui-state-disabled')) {
+ $button.addClass('ui-state-focus');
+ }
+ },
+ blur: function() {
+ $button.removeClass('ui-state-focus');
+ }
+ })
+ .find('span') // webkit doesn't like it when you click on the span :(
+ .on('click.multiselect', clickHandler);
},
_bindMenuEvents: function() {
var self = this;
// optgroup label toggle support
- this.menu.on('click.multiselect', '.ui-multiselect-optgroup a', function(e) {
+ this.$menu.on('click.multiselect', '.ui-multiselect-optgroup a', function(e) {
e.preventDefault();
var $this = $(this);
@@ -400,7 +397,7 @@
})
.on('mouseenter.multiselect', 'label', function() {
if(!$(this).hasClass('ui-state-disabled')) {
- self.labels.removeClass('ui-state-hover');
+ self.$labels.removeClass('ui-state-hover');
$(this).addClass('ui-state-hover').find('input').focus();
}
})
@@ -415,8 +412,8 @@
switch(e.which) {
case 9: // tab
if(e.shiftKey) {
- self.menu.find(".ui-state-hover").removeClass("ui-state-hover");
- self.header.find("li").last().find("a").focus();
+ self.$menu.find(".ui-state-hover").removeClass("ui-state-hover");
+ self.$header.find("li").last().find("a").focus();
} else {
self.close();
}
@@ -451,7 +448,7 @@
var val = this.value;
var optionText = $this.parent().find("span").text();
var checked = this.checked;
- var tags = self.element.find('option');
+ var $tags = self.element.find('option');
var isMultiple = !!self.element[0].multiple;
// bail if this input is disabled or the event is cancelled
@@ -468,7 +465,7 @@
$this.prop('aria-selected', checked);
// change state on the original option tags
- tags.each(function() {
+ $tags.each(function() {
if(this.value === val) {
this.selected = checked;
} else if(!isMultiple) {
@@ -478,7 +475,7 @@
// some additional single select-specific logic
if(!isMultiple) {
- self.labels.removeClass('ui-state-active');
+ self.$labels.removeClass('ui-state-active');
$this.closest('label').toggleClass('ui-state-active', checked);
// close menu
@@ -497,7 +494,7 @@
_bindHeaderEvents: function() {
var self = this;
// header links
- this.header.on('click.multiselect', 'a', function(e) {
+ this.$header.on('click.multiselect', 'a', function(e) {
var $this = $(this);
if($this.hasClass('ui-multiselect-close')) {
self.close();
@@ -516,7 +513,7 @@
break;
case 9:
var $target = $(e.target);
- if((e.shiftKey && !$target.parent().prev().length && !self.header.find(".ui-multiselect-filter").length) || (!$target.parent().next().length && !self.labels.length && !e.shiftKey)) {
+ if((e.shiftKey && !$target.parent().prev().length && !self.$header.find(".ui-multiselect-filter").length) || (!$target.parent().next().length && !self.$labels.length && !e.shiftKey)) {
self.close();
e.preventDefault();
}
@@ -534,14 +531,14 @@
this._bindHeaderEvents();
// close each widget when clicking on any other element/anywhere else on the page
- $doc.bind('mousedown.' + self._namespaceID, function(event) {
+ $doc.on('mousedown.' + self._namespaceID, function(event) {
var target = event.target;
if(self._isOpen &&
- target !== self.button[0] &&
- target !== self.menu[0] &&
- !$.contains(self.menu[0], target) &&
- !$.contains(self.button[0], target)
+ target !== self.$button[0] &&
+ target !== self.$menu[0] &&
+ !$.contains(self.$menu[0], target) &&
+ !$.contains(self.$button[0], target)
) {
self.close();
}
@@ -569,7 +566,7 @@
var lastChar = minVal[ minVal.length -1 ];
width = minVal.match(/\d+/);
if(lastChar === '%') {
- width = this.element.parent().outerWidth() * (width/100);
+ width = this.element.parent().outerWidth() * (width/100); // element is a jQuery object
} else {
width = parseInt(minVal, 10);
}
@@ -580,40 +577,40 @@
// set button width
_setButtonWidth: function() {
- var width = this.element.outerWidth();
+ var width = this.element.outerWidth(); // element is a jQuery object
var minVal = this._getMinWidth();
if(width < minVal) {
width = minVal;
}
// set widths
- this.button.outerWidth(width);
+ this.$button.outerWidth(width);
},
// set menu width
_setMenuWidth: function() {
- var m = this.menu;
- var width = (this.button.outerWidth() <= 0) ? this._getMinWidth() : this.button.outerWidth();
+ var m = this.$menu;
+ var width = (this.$button.outerWidth() <= 0) ? this._getMinWidth() : this.$button.outerWidth();
m.outerWidth(this.options.menuWidth || width);
},
// Sets the height of the menu
// Will set a scroll bar if the menu height exceeds that of the height in options
_setMenuHeight: function() {
- var headerHeight = this.menu.children(".ui-multiselect-header:visible").outerHeight(true);
+ var headerHeight = this.$menu.children(".ui-multiselect-header:visible").outerHeight(true);
var ulHeight = 0;
- this.menu.find(".ui-multiselect-checkboxes li, .ui-multiselect-checkboxes a").each(function(idx, li) {
+ this.$menu.find(".ui-multiselect-checkboxes li, .ui-multiselect-checkboxes a").each(function(idx, li) {
ulHeight += $(li).outerHeight(true);
});
if(ulHeight > this.options.height) {
- this.menu.children(".ui-multiselect-checkboxes").css("overflow", "auto");
+ this.$menu.children(".ui-multiselect-checkboxes").css("overflow", "auto");
ulHeight = this.options.height;
} else {
- this.menu.children(".ui-multiselect-checkboxes").css("overflow", "hidden");
+ this.$menu.children(".ui-multiselect-checkboxes").css("overflow", "hidden");
}
- this.menu.children(".ui-multiselect-checkboxes").height(ulHeight);
- this.menu.height(ulHeight + headerHeight);
+ this.$menu.children(".ui-multiselect-checkboxes").height(ulHeight);
+ this.$menu.height(ulHeight + headerHeight);
},
// Resizes the menu, called every time the menu is opened
@@ -636,10 +633,10 @@
// if at the first/last element
if(!$next.length) {
- var $container = this.menu.find('ul').last();
+ var $container = this.$menu.find('ul').last();
// move to the first/last
- this.menu.find('label:visible')[ moveToLast ? 'last' : 'first' ]().trigger('mouseover');
+ this.$menu.find('label:visible')[ moveToLast ? 'last' : 'first' ]().trigger('mouseover');
// set scroll position
$container.scrollTop(moveToLast ? $container.height() : 0);
@@ -671,8 +668,9 @@
// Toggles checked state on either an option group or all inputs
_toggleChecked: function(flag, group) {
- var $inputs = (group && group.length) ? group : this.inputs;
+ var $inputs = (group && group.length) ? group : this.$inputs;
var self = this;
+ var $el = this.element; // element is a jQuery object
// toggle state on inputs
$inputs.each(this._toggleState('checked', flag));
@@ -690,8 +688,8 @@
});
// toggle state on original option tags
- this.element.selectedIndex = -1;
- this.element
+ $el.selectedIndex = -1;
+ $el
.find('option')
.each(function() {
if(!this.disabled && values[this.value]) {
@@ -701,16 +699,16 @@
// trigger the change event on the select
if($inputs.length) {
- this.element.trigger("change");
+ $el.trigger("change");
}
},
// Toggle disable state on the widget and underlying select
_toggleDisabled: function(flag) {
- this.button.prop({ 'disabled':flag, 'aria-disabled':flag })[ flag ? 'addClass' : 'removeClass' ]('ui-state-disabled');
+ this.$button.prop({ 'disabled':flag, 'aria-disabled':flag })[ flag ? 'addClass' : 'removeClass' ]('ui-state-disabled');
if(this.options.disableInputsOnToggle) {
- var checkboxes = this.menu.find(".ui-multiselect-checkboxes").get(0);
+ var checkboxes = this.$menu.find(".ui-multiselect-checkboxes").get(0);
var matchedInputs = [];
var key = "ech-multiselect-disabled";
var i = 0;
@@ -746,18 +744,18 @@
// open the menu
open: function(e) {
var self = this;
- var button = this.button;
- var menu = this.menu;
+ var $button = this.$button;
+ var $menu = this.$menu;
var speed = this.speed;
var o = this.options;
var args = [];
// bail if the multiselectopen event returns false, this widget is disabled, or is already open
- if(this._trigger('beforeopen') === false || button.hasClass('ui-state-disabled') || this._isOpen) {
+ if(this._trigger('beforeopen') === false || $button.hasClass('ui-state-disabled') || this._isOpen) {
return;
}
- var $container = menu.find('.ui-multiselect-checkboxes');
+ var $container = $menu.find('.ui-multiselect-checkboxes');
var effect = o.show;
// figure out opening effects/speeds
@@ -776,7 +774,7 @@
$container.scrollTop(0);
// show the menu, maybe with a speed/effect combo
- $.fn.show.apply(menu, args);
+ $.fn.show.apply($menu, args);
this._resizeMenu();
// positon
@@ -784,17 +782,16 @@
// select the first not disabled option or the filter input if available
- var filter = this.header.find(".ui-multiselect-filter");
+ var filter = this.$header.find(".ui-multiselect-filter");
if(filter.length) {
filter.first().find('input').trigger('focus');
- } else if(this.labels.length){
- this.labels.filter(':not(.ui-state-disabled)').eq(0).trigger('mouseover').trigger('mouseenter').find('input').trigger('focus');
+ } else if(this.$labels.length){
+ this.$labels.filter(':not(.ui-state-disabled)').eq(0).trigger('mouseover').trigger('mouseenter').find('input').trigger('focus');
} else {
- this.header.find('a').first().trigger('focus');
+ this.$header.find('a').first().trigger('focus');
}
-
- button.addClass('ui-state-active');
+ $button.addClass('ui-state-active');
this._isOpen = true;
this._trigger('open');
},
@@ -810,7 +807,7 @@
var speed = this.speed;
var args = [];
- // figure out opening effects/speeds
+ // figure out closing effects/speeds
if($.isArray(o.hide)) {
effect = o.hide[0];
speed = o.hide[1] || this.speed;
@@ -820,11 +817,11 @@
args = [ effect, speed ];
}
- $.fn.hide.apply(this.menu, args);
- this.button.removeClass('ui-state-active').trigger('blur').trigger('mouseleave');
+ $.fn.hide.apply(this.$menu, args);
+ this.$button.removeClass('ui-state-active').trigger('blur').trigger('mouseleave');
this._isOpen = false;
this._trigger('close');
- this.button.trigger('focus');
+ this.$button.trigger('focus');
},
enable: function() {
@@ -842,7 +839,7 @@
uncheckAll: function() {
this._toggleChecked(false);
- if ( !this.element[0].multiple )
+ if ( !this.element[0].multiple ) // element is a jQuery object
this.element[0].selectedIndex = -1; // Forces the underlying single-select to have no options selected.
this._trigger('uncheckAll');
},
@@ -853,11 +850,11 @@
},
getChecked: function() {
- return this.menu.find('input').filter(':checked');
+ return this.$menu.find('input').filter(':checked');
},
getUnchecked: function() {
- return this.menu.find('input').not(':checked');
+ return this.$menu.find('input').not(':checked');
},
destroy: function() {
@@ -865,11 +862,11 @@
$.Widget.prototype.destroy.call(this);
// unbind events
- $doc.unbind(this._namespaceID);
- $(this.element[0].form).unbind(this._namespaceID);
+ $doc.off(this._namespaceID);
+ $(this.element[0].form).off(this._namespaceID); // element is a jQuery object
- this.button.remove();
- this.menu.remove();
+ this.$button.remove();
+ this.$menu.remove();
this.element.show();
return this;
@@ -880,19 +877,19 @@
},
widget: function() {
- return this.menu;
+ return this.$menu;
},
getButton: function() {
- return this.button;
+ return this.$button;
},
getMenu: function() {
- return this.menu;
+ return this.$menu;
},
getLabels: function() {
- return this.labels;
+ return this.$labels;
},
/*
@@ -908,16 +905,16 @@
this.element.children("OPTGROUP").filter(function() {
return $(this).prop("label") === groupLabel;
}).append($option);
- this.menu.find(".ui-multiselect-optgroup").filter(function() {
+ this.$menu.find(".ui-multiselect-optgroup").filter(function() {
return $(this).find("a").text() === groupLabel;
}).append(this._makeOption(optionNode));
} else {
this.element.append($option);
- this.menu.find(".ui-multiselect-checkboxes").append(this._makeOption(optionNode));
+ this.$menu.find(".ui-multiselect-checkboxes").append(this._makeOption(optionNode));
}
//update cached elements
- this.labels = this.menu.find('label');
- this.inputs = this.labels.children('input');
+ this.$labels = this.$menu.find('label');
+ this.$inputs = this.$labels.children('input');
},
removeOption: function(value) {
@@ -925,18 +922,18 @@
return;
}
this.element.find("option[value=" + value + "]").remove();
- this.labels.find("input[value=" + value + "]").parents("li").remove();
+ this.$labels.find("input[value=" + value + "]").parents("li").remove();
//update cached elements
- this.labels = this.menu.find('label');
- this.inputs = this.labels.children('input');
+ this.$labels = this.$menu.find('label');
+ this.$inputs = this.$labels.children('input');
},
position: function() {
var pos = {
my: "top",
at: "bottom",
- of: this.button
+ of: this.$button
};
if(!$.isEmptyObject(this.options.position)) {
pos.my = this.options.position.my || pos.my;
@@ -944,50 +941,42 @@
pos.of = this.options.position.of || pos.of;
}
if($.ui && $.ui.position) {
- this.menu.position(pos);
+ this.$menu.position(pos);
} else {
- pos = this.button.position();
- pos.top += this.button.outerHeight(false);
- this.menu.offset(pos);
+ pos = this.$button.position();
+ pos.top += this.$button.outerHeight(false);
+ this.$menu.offset(pos);
}
},
// react to option changes after initialization
_setOption: function(key, value) {
- var menu = this.menu;
+ var $menu = this.$menu;
switch(key) {
case 'header':
if(typeof value === 'boolean') {
- this.header[value ? 'show' : 'hide']();
+ this.$header[value ? 'show' : 'hide']();
} else if(typeof value === 'string') {
- this.headerLinkContainer.children("li:not(:last-child)").remove();
- this.headerLinkContainer.prepend("" + value + " ");
+ this.$headerLinkContainer.children("li:not(:last-child)").remove();
+ this.$headerLinkContainer.prepend("" + value + " ");
}
break;
case 'checkAllText':
- menu.find('a.ui-multiselect-all span').eq(-1).text(value); // eq(-1) finds the last span
- break;
case 'uncheckAllText':
- menu.find('a.ui-multiselect-none span').eq(-1).text(value);
- break;
case 'flipAllText':
- menu.find('a.ui-multiselect-flip span').eq(-1).text(value);
+ $menu.find('a.ui-multiselect-' + {checkAllText: 'all', uncheckAllText: 'none', flipAllText: 'flip'}[key] + ' span').eq(-1).text(value); // eq(-1) finds the last span
break;
case 'checkAllIcon':
- menu.find('a.ui-multiselect-all span').eq(0).replaceWith(value);
- break;
case 'uncheckAllIcon':
- menu.find('a.ui-multiselect-none span').eq(0).replaceWith(value);
- break;
case 'flipAllIcon':
- menu.find('a.ui-multiselect-flip span').eq(0).replaceWith(value);
+ $menu.find('a.ui-multiselect-' + {checkAllIcon: 'all', uncheckAllIcon: 'none', flipAllIcon: 'flip'}[key] + ' span').eq(0).replaceWith(value); // eq(0) finds the first span
break;
case 'openIcon':
- menu.find('span.ui-multiselect-open').html(value);
+ $menu.find('span.ui-multiselect-open').html(value);
break;
case 'closeIcon':
- menu.find('a.ui-multiselect-close').html(value);
+ $menu.find('a.ui-multiselect-close').html(value);
break;
case 'height':
this.options[key] = value;
@@ -1006,13 +995,13 @@
this.update();
break;
case 'classes':
- menu.add(this.button).removeClass(this.options.classes).addClass(value);
+ $menu.add(this.$button).removeClass(this.options.classes).addClass(value);
break;
case 'multiple':
var el_0 = this.element[0];
if (!!el_0.multiple != value) {
- menu.toggleClass('ui-multiselect-multiple', value);
- menu.toggleClass('ui-multiselect-single', !value);
+ $menu.toggleClass('ui-multiselect-multiple', value);
+ $menu.toggleClass('ui-multiselect-single', !value);
el_0.multiple = value;
this.uncheckAll();
this.refresh();
From 5d0f625ec143b13ddeaaa419bae2653915a8ef60 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 13:59:13 -0800
Subject: [PATCH 02/12] $variable naming and ditch bind
bind() is deprecated. Use on() instead.
---
src/jquery.multiselect.filter.js | 65 ++++++++++++++++----------------
1 file changed, 33 insertions(+), 32 deletions(-)
diff --git a/src/jquery.multiselect.filter.js b/src/jquery.multiselect.filter.js
index 435920d..9c873d6 100644
--- a/src/jquery.multiselect.filter.js
+++ b/src/jquery.multiselect.filter.js
@@ -1,11 +1,12 @@
/* jshint forin:true, noarg:true, noempty:true, eqeqeq:true, boss:true, undef:true, curly:true, browser:true, jquery:true */
/*
- * jQuery MultiSelect UI Widget Filtering Plugin 2.0.0
+ * jQuery MultiSelect UI Widget Filtering Plugin 3.0.0
* Copyright (c) 2012 Eric Hynds
*
* http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/
*
* Depends:
+ * - jQuery 1.7+
* - jQuery UI MultiSelect widget
*
* Dual licensed under the MIT and GPL licenses:
@@ -48,30 +49,30 @@
_create: function() {
var opts = this.options;
- var elem = $(this.element);
+ var $elem = this.element;
// get the multiselect instance
- this.instance = elem.multiselect('instance');
+ this.instance = $elem.multiselect('instance');
// store header; add filter class so the close/check all/uncheck all links can be positioned correctly
- this.header = this.instance.menu.find('.ui-multiselect-header').addClass('ui-multiselect-hasfilter');
+ this.$header = this.instance.$menu.find('.ui-multiselect-header').addClass('ui-multiselect-hasfilter');
- // wrapper elem
- this.input = $(" ").attr({
+ // wrapper $elem
+ this.$input = $(" ").attr({
placeholder: opts.placeholder,
type: "search"
}).css({
width: (/\d/.test(opts.width) ? opts.width + 'px' : null)
- }).bind({
+ }).on({
keydown: function(e) {
// prevent the enter key from submitting the form / closing the widget
if(e.which === 13) {
e.preventDefault();
} else if(e.which === 27) {
- elem.multiselect('close');
+ $elem.multiselect('close');
e.preventDefault();
} else if(e.which === 9 && e.shiftKey) {
- elem.multiselect('close');
+ $elem.multiselect('close');
e.preventDefault();
} else if(e.altKey) {
switch(e.which) {
@@ -80,13 +81,13 @@
$(this).val('').trigger('input', '');
break;
case 65:
- elem.multiselect('checkAll');
+ $elem.multiselect('checkAll');
break;
case 85:
- elem.multiselect('uncheckAll');
+ $elem.multiselect('uncheckAll');
break;
case 76:
- elem.multiselect('instance').labels.first().trigger("mouseenter");
+ $elem.multiselect('instance').$labels.first().trigger("mouseenter");
break;
}
}
@@ -96,25 +97,25 @@
});
// automatically reset the widget on close?
if(this.options.autoReset) {
- elem.bind('multiselectclose', $.proxy(this._reset, this));
+ $elem.on('multiselectclose', $.proxy(this._reset, this));
}
// rebuild cache when multiselect is updated
- elem.bind('multiselectrefresh', $.proxy(function() {
+ $elem.on('multiselectrefresh', $.proxy(function() {
this.updateCache();
this._handler();
}, this));
- this.wrapper = $("
").addClass("ui-multiselect-filter").text(opts.label).append(this.input).prependTo(this.header);
+ this.$wrapper = $("
").addClass("ui-multiselect-filter").text(opts.label).append(this.$input).prependTo(this.$header);
// reference to the actual inputs
- this.inputs = this.instance.menu.find('input[type="checkbox"], input[type="radio"]');
+ this.$inputs = this.instance.$menu.find('input[type="checkbox"], input[type="radio"]');
// cache input values for searching
this.updateCache();
// rewrite internal _toggleChecked fn so that when checkAll/uncheckAll is fired,
- // only the currently filtered elements are checked
+ // only the currently filtered $elements are checked
this.instance._toggleChecked = function(flag, group) {
- var $inputs = (group && group.length) ? group : this.labels.find('input');
+ var $inputs = (group && group.length) ? group : this.$labels.find('input');
var _self = this;
// do not include hidden elems if the menu isn't open.
@@ -149,11 +150,11 @@
// thx for the logic here ben alman
_handler: function(e) {
- var term = $.trim(this.input[0].value.toLowerCase()),
+ var term = $.trim(this.$input[0].value.toLowerCase()),
// speed up lookups
- rows = this.rows, inputs = this.inputs, cache = this.cache;
- var $groups = this.instance.menu.find(".ui-multiselect-optgroup");
+ rows = this.rows, $inputs = this.$inputs, $cache = this.$cache;
+ var $groups = this.instance.$menu.find(".ui-multiselect-optgroup");
$groups.show();
if(!term) {
rows.show();
@@ -162,10 +163,10 @@
var regex = new RegExp(term.replace(rEscape, "\\$&"), 'gi');
- this._trigger("filter", e, $.map(cache, function(v, i) {
+ this._trigger("filter", e, $.map($cache, function(v, i) {
if(v.search(regex) !== -1) {
rows.eq(i).show();
- return inputs.get(i);
+ return $inputs.get(i);
}
return null;
@@ -183,36 +184,36 @@
},
_reset: function() {
- this.input.val('').trigger('input', '');
+ this.$input.val('').trigger('input', '');
},
updateCache: function() {
// each list item
- this.rows = this.instance.labels.parent();
+ this.rows = this.instance.$labels.parent();
// cache
- this.cache = this.element.children().map(function() {
- var elem = $(this);
+ this.$cache = this.element.children().map(function() {
+ var $elem = $(this);
// account for optgroups
if(this.tagName.toLowerCase() === "optgroup") {
- elem = elem.children();
+ $elem = $elem.children();
}
- return elem.map(function() {
+ return $elem.map(function() {
return this.innerHTML.toLowerCase();
}).get();
}).get();
},
widget: function() {
- return this.wrapper;
+ return this.$wrapper;
},
destroy: function() {
$.Widget.prototype.destroy.call(this);
- this.input.val('').trigger("keyup");
- this.wrapper.remove();
+ this.$input.val('').trigger("keyup");
+ this.$wrapper.remove();
}
});
From e8921e8564c7f2b570a4c54ceff39461055b6b90 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 14:12:35 -0800
Subject: [PATCH 03/12] Update limited selectedList/checkAll test
Changed the default selectedText to be "# of # selected" so that developers will be aware that this form is available. (It always has been available..)
---
tests/unit/options.js | 592 +++++++++++++++++++++---------------------
1 file changed, 296 insertions(+), 296 deletions(-)
diff --git a/tests/unit/options.js b/tests/unit/options.js
index 3388170..5ca530a 100644
--- a/tests/unit/options.js
+++ b/tests/unit/options.js
@@ -1,182 +1,182 @@
(function($){
- module("options");
+ module("options");
- test("noneSelectedText", function(){
- expect(7);
- var text;
+ test("noneSelectedText", function(){
+ expect(7);
+ var text;
- el = $("select").multiselect({
- noneSelectedText: 'None Selected'
- });
+ el = $("select").multiselect({
+ noneSelectedText: 'None Selected'
+ });
- // read from widget
- text = el.multiselect("option", "noneSelectedText");
+ // read from widget
+ text = el.multiselect("option", "noneSelectedText");
- equals( button().text(), text, 'on init, button reads "None Selected"');
- el.multiselect("checkAll");
- ok( button().text() !== text, 'after checkAll, button no longer reads "None Selected"');
- el.multiselect("uncheckAll");
- equals( button().text(), text, 'after uncheckAll, button text restored to "None Selected"');
+ equals( button().text(), text, 'on init, button reads "None Selected"');
+ el.multiselect("checkAll");
+ ok( button().text() !== text, 'after checkAll, button no longer reads "None Selected"');
+ el.multiselect("uncheckAll");
+ equals( button().text(), text, 'after uncheckAll, button text restored to "None Selected"');
- // change the option value
- el.multiselect("option", "noneSelectedText", "No Checkboxes Checked");
- equals( el.multiselect("option", "noneSelectedText"), "No Checkboxes Checked", "new noneSelectedText value set correctly");
+ // change the option value
+ el.multiselect("option", "noneSelectedText", "No Checkboxes Checked");
+ equals( el.multiselect("option", "noneSelectedText"), "No Checkboxes Checked", "new noneSelectedText value set correctly");
- // read updated value from widget
- text = el.multiselect("option", "noneSelectedText");
+ // read updated value from widget
+ text = el.multiselect("option", "noneSelectedText");
- // test against the new value
- equals( button().text(), text, 'after changing the option value, button now reads "No Checkboxes Checked"');
- el.multiselect("checkAll");
- ok( button().text() !== text, 'after checkAll, button no longer reads "No Checkboxes Checked"');
- el.multiselect("uncheckAll");
- equals( button().text(), text, 'after uncheckAll, button text restored to "No Checkboxes Checked"');
+ // test against the new value
+ equals( button().text(), text, 'after changing the option value, button now reads "No Checkboxes Checked"');
+ el.multiselect("checkAll");
+ ok( button().text() !== text, 'after checkAll, button no longer reads "No Checkboxes Checked"');
+ el.multiselect("uncheckAll");
+ equals( button().text(), text, 'after uncheckAll, button text restored to "No Checkboxes Checked"');
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
- test("selectedText", function(){
- expect(3);
- var numOptions = $("select option").length;
+ test("selectedText", function(){
+ expect(3);
+ var numOptions = $("select option").length;
- el = $("select").multiselect({
- selectedText: '# of # selected'
- });
+ el = $("select").multiselect({
+ selectedText: '# of # selected'
+ });
- el.multiselect("checkAll");
- equals( button().text(), numOptions+' of '+numOptions+' selected', 'after checkAll, button reflects the total number of checked boxes');
+ el.multiselect("checkAll");
+ equals( button().text(), numOptions+' of '+numOptions+' selected', 'after checkAll, button reflects the total number of checked boxes');
- // change option value
- el.multiselect("option", "selectedText", function( numChecked ){
- return numChecked + ' options selected';
- });
+ // change option value
+ el.multiselect("option", "selectedText", function( numChecked ){
+ return numChecked + ' options selected';
+ });
- equals( button().text(), numOptions+' options selected', 'after changing the option to a function value, button reflects the new text');
+ equals( button().text(), numOptions+' options selected', 'after changing the option to a function value, button reflects the new text');
- // uncheck all
- el.multiselect("uncheckAll");
- equals( button().text(), el.multiselect("option","noneSelectedText"), 'after unchecking all, button text now reflects noneSelectedText option value');
+ // uncheck all
+ el.multiselect("uncheckAll");
+ equals( button().text(), el.multiselect("option","noneSelectedText"), 'after unchecking all, button text now reflects noneSelectedText option value');
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
- test("selectedList", function(){
- expect(2);
+ test("selectedList", function(){
+ expect(2);
- var html = 'foo "with quotes" bar baz ';
+ var html = 'foo "with quotes" bar baz ';
- el = $(html).appendTo("body").multiselect({
- selectedList: 3
- });
+ el = $(html).appendTo("body").multiselect({
+ selectedList: 3
+ });
- el.multiselect("checkAll");
- equals( button().text(), 'foo "with quotes", bar, baz', 'after checkAll, button text is a list of all options in the select');
- el.multiselect("destroy").remove();
+ el.multiselect("checkAll");
+ equals( button().text(), 'foo "with quotes", bar, baz', 'after checkAll, button text is a list of all options in the select');
+ el.multiselect("destroy").remove();
- el = $(html).appendTo("body").multiselect({
- selectedList: 2
- });
+ el = $(html).appendTo("body").multiselect({
+ selectedList: 2
+ });
- el.multiselect("checkAll");
- equals( button().text(), '3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
- el.multiselect("destroy").remove();
- });
+ el.multiselect("checkAll");
+ equals( button().text(), '3 of 3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
+ el.multiselect("destroy").remove();
+ });
- function asyncSelectedList( useTrigger, message ){
- expect(1);
- stop();
+ function asyncSelectedList( useTrigger, message ){
+ expect(1);
+ stop();
- var html = 'foo bar baz ',
- checkboxes;
+ var html = 'foo bar baz ',
+ checkboxes;
- el = $(html).appendTo(body).multiselect({
- selectedList: 2
- });
+ el = $(html).appendTo(body).multiselect({
+ selectedList: 2
+ });
- checkboxes = el.multiselect("widget").find(":checkbox");
+ checkboxes = el.multiselect("widget").find(":checkbox");
- if( useTrigger ){
- checkboxes.eq(0).trigger('click');
- checkboxes.eq(1).trigger('click');
- } else {
- checkboxes.eq(0)[0].click();
- checkboxes.eq(1)[0].click();
- }
+ if( useTrigger ){
+ checkboxes.eq(0).trigger('click');
+ checkboxes.eq(1).trigger('click');
+ } else {
+ checkboxes.eq(0)[0].click();
+ checkboxes.eq(1)[0].click();
+ }
- setTimeout(function(){
- equals( button().text(), 'foo, bar', message);
- el.multiselect("destroy").remove();
- start();
- }, 10);
- }
+ setTimeout(function(){
+ equals( button().text(), 'foo, bar', message);
+ el.multiselect("destroy").remove();
+ start();
+ }, 10);
+ }
- test("selectedList - manual trigger - jQuery", function(){
- asyncSelectedList( true, 'manually checking items with trigger()' );
- });
+ test("selectedList - manual trigger - jQuery", function(){
+ asyncSelectedList( true, 'manually checking items with trigger()' );
+ });
- test("selectedList - manual trigger - native", function(){
- asyncSelectedList( false, 'manually checking items with element.click()' );
- });
+ test("selectedList - manual trigger - native", function(){
+ asyncSelectedList( false, 'manually checking items with element.click()' );
+ });
- test("selectedList - encoding", function() {
- expect(1);
+ test("selectedList - encoding", function() {
+ expect(1);
- el = $('A&E ')
- .appendTo("body")
- .multiselect({ selectedList: 1 });
+ el = $('A&E ')
+ .appendTo("body")
+ .multiselect({ selectedList: 1 });
- equals(button().text(), 'A&E');
- el.multiselect("destroy").remove();
- });
+ equals(button().text(), 'A&E');
+ el.multiselect("destroy").remove();
+ });
- test("height", function(){
- expect(2);
+ test("height", function(){
+ expect(2);
- var height = 100;
+ var height = 100;
- el = $("select").multiselect({ height: height }).multiselect("open");
- equals( height, menu().find("ul.ui-multiselect-checkboxes").height(), 'height after opening property set to '+ height );
+ el = $("select").multiselect({ height: height }).multiselect("open");
+ equals( height, menu().find("ul.ui-multiselect-checkboxes").height(), 'height after opening property set to '+ height );
- // change height and re-test
- height = 300;
- el.multiselect("option", "height", height);
- equals( height, menu().find(".ui-multiselect-checkboxes").height(), 'changing value through api to '+ height );
+ // change height and re-test
+ height = 300;
+ el.multiselect("option", "height", height);
+ equals( height, menu().find(".ui-multiselect-checkboxes").height(), 'changing value through api to '+ height );
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
- test("minWidth", function(){
- expect(5);
+ test("minWidth", function(){
+ expect(5);
- var minWidth = 321;
+ var minWidth = 321;
- el = $("select").multiselect({ minWidth:minWidth }).multiselect("open");
- equals( minWidth, button().outerWidth(), 'outerWidth of button is ' + minWidth );
+ el = $("select").multiselect({ minWidth:minWidth }).multiselect("open");
+ equals( minWidth, button().outerWidth(), 'outerWidth of button is ' + minWidth );
- // change height and re-test
- minWidth = 351;
- el.multiselect("option", "minWidth", minWidth);
- equals( minWidth, button().outerWidth(), 'changing value through api to '+minWidth);
+ // change height and re-test
+ minWidth = 351;
+ el.multiselect("option", "minWidth", minWidth);
+ equals( minWidth, button().outerWidth(), 'changing value through api to '+minWidth);
- // change height to something that should fail.
- minWidth = 10;
- el.multiselect("option", "minWidth", minWidth);
- var outerWidth = button().outerWidth();
- ok( minWidth !== outerWidth, 'changing value through api to '+minWidth+' (too small), outerWidth is actually ' + outerWidth);
+ // change height to something that should fail.
+ minWidth = 10;
+ el.multiselect("option", "minWidth", minWidth);
+ var outerWidth = button().outerWidth();
+ ok( minWidth !== outerWidth, 'changing value through api to '+minWidth+' (too small), outerWidth is actually ' + outerWidth);
- minWidth = "50%";
- el.multiselect("option", "minWidth", minWidth);
- outerWidth = Math.floor(button().outerWidth());
- var halfParent = Math.floor(el.parent().outerWidth()/2);
- ok(outerWidth === halfParent, 'changing value to 50%');
+ minWidth = "50%";
+ el.multiselect("option", "minWidth", minWidth);
+ outerWidth = Math.floor(button().outerWidth());
+ var halfParent = Math.floor(el.parent().outerWidth()/2);
+ ok(outerWidth === halfParent, 'changing value to 50%');
- minWidth = "351px";
- el.multiselect("option", "minWidth", minWidth);
- equals( 351, button().outerWidth(), 'minWidth supports strings suffixed with px as well as integer px values');
+ minWidth = "351px";
+ el.multiselect("option", "minWidth", minWidth);
+ equals( 351, button().outerWidth(), 'minWidth supports strings suffixed with px as well as integer px values');
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
test("menuWidth", function(){
expect(2);
@@ -194,193 +194,193 @@
el.multiselect("destroy");
});
- test("checkAllText", function(){
- expect(2);
- var text = "foo";
+ test("checkAllText", function(){
+ expect(2);
+ var text = "foo";
- el = $("select").multiselect({ checkAllText:text, showCheckAll:true });
- equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
+ el = $("select").multiselect({ checkAllText:text, showCheckAll:true });
+ equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
- // set through option
- text = "bar";
- el.multiselect("option","checkAllText","bar");
- equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
+ // set through option
+ text = "bar";
+ el.multiselect("option","checkAllText","bar");
+ equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
- test("uncheckAllText", function(){
- expect(2);
- var text = "foo";
+ test("uncheckAllText", function(){
+ expect(2);
+ var text = "foo";
- el = $("select").multiselect({ uncheckAllText:text, showUncheckAll:true });
- equals( text, menu().find(".ui-multiselect-none").text(), 'check all link reads '+text );
+ el = $("select").multiselect({ uncheckAllText:text, showUncheckAll:true });
+ equals( text, menu().find(".ui-multiselect-none").text(), 'check all link reads '+text );
- // set through option
- text = "bar";
- el.multiselect("option","uncheckAllText","bar");
- equals( text, menu().find(".ui-multiselect-none").text(), 'changing value through api to '+text );
+ // set through option
+ text = "bar";
+ el.multiselect("option","uncheckAllText","bar");
+ equals( text, menu().find(".ui-multiselect-none").text(), 'changing value through api to '+text );
- el.multiselect("destroy");
- });
+ el.multiselect("destroy");
+ });
- test("flipAllText", function(){
- expect(2);
- var text = "foo";
+ test("flipAllText", function(){
+ expect(2);
+ var text = "foo";
- el = $("select").multiselect({ flipAllText:text, showFlipAll:true });
- equals( text, menu().find(".ui-multiselect-flip").text(), 'flip all link reads '+text );
+ el = $("select").multiselect({ flipAllText:text, showFlipAll:true });
+ equals( text, menu().find(".ui-multiselect-flip").text(), 'flip all link reads '+text );
- // set through option
- text = "bar";
- el.multiselect("option","flipAllText","bar");
- equals( text, menu().find(".ui-multiselect-flip").text(), 'changing value through api to '+text );
+ // set through option
+ text = "bar";
+ el.multiselect("option","flipAllText","bar");
+ equals( text, menu().find(".ui-multiselect-flip").text(), 'changing value through api to '+text );
- el.multiselect("destroy");
- });
-
- test("autoOpen", function(){
- expect(2);
+ el.multiselect("destroy");
+ });
- el = $("select").multiselect({ autoOpen:false });
+ test("autoOpen", function(){
+ expect(2);
- ok( menu().is(":hidden"), 'menu is hidden with autoOpen off');
- el.multiselect("destroy");
+ el = $("select").multiselect({ autoOpen:false });
- el = $("select").multiselect({ autoOpen:true });
- ok( menu().is(":visible"), 'menu is visible with autoOpen on');
- el.multiselect("destroy");
+ ok( menu().is(":hidden"), 'menu is hidden with autoOpen off');
+ el.multiselect("destroy");
- // no built in support for change on the fly; not testing it.
- });
+ el = $("select").multiselect({ autoOpen:true });
+ ok( menu().is(":visible"), 'menu is visible with autoOpen on');
+ el.multiselect("destroy");
- test("multiple (false - single select)", function(){
- expect(10);
+ // no built in support for change on the fly; not testing it.
+ });
- $("select").removeAttr("multiple");
- el = $("select").multiselect({ multiple:false });
+ test("multiple (false - single select)", function(){
+ expect(10);
- // get some references
- var $menu = menu(), $header = header();
+ $("select").removeAttr("multiple");
+ el = $("select").multiselect({ multiple:false });
- ok( $header.find('a.ui-multiselect-all').is(':hidden'), 'select all link is hidden' );
- ok( $header.find('a.ui-multiselect-none').is(':hidden'), 'select none link is hidden' );
- ok( $header.find('a.ui-multiselect-close').css('display') !== 'hidden', 'close link is visible' );
- ok( !$menu.find(":checkbox").length, 'no checkboxes are present');
- ok( $menu.find(":radio").length > 0, 'but radio boxes are');
+ // get some references
+ var $menu = menu(), $header = header();
- // simulate click on ALL radios
- var radios = $menu.find(":radio").trigger("click");
+ ok( $header.find('a.ui-multiselect-all').is(':hidden'), 'select all link is hidden' );
+ ok( $header.find('a.ui-multiselect-none').is(':hidden'), 'select none link is hidden' );
+ ok( $header.find('a.ui-multiselect-close').css('display') !== 'hidden', 'close link is visible' );
+ ok( !$menu.find(":checkbox").length, 'no checkboxes are present');
+ ok( $menu.find(":radio").length > 0, 'but radio boxes are');
- // at the end of that, only one radio should be checked and the menu closed
- equals( radios.filter(":checked").length, 1, 'After checking all radios, only one is actually checked');
- equals( false, el.multiselect('isOpen'), 'Menu is closed' );
+ // simulate click on ALL radios
+ var radios = $menu.find(":radio").trigger("click");
- // uncheck boxes... should only be one
- radios.filter(":checked").trigger("click");
+ // at the end of that, only one radio should be checked and the menu closed
+ equals( radios.filter(":checked").length, 1, 'After checking all radios, only one is actually checked');
+ equals( false, el.multiselect('isOpen'), 'Menu is closed' );
- // method calls
- el.multiselect("checkAll");
- equals( $menu.find("input:radio:checked").length, 1, 'After checkAll method call only one is actually checked');
-
- el.multiselect("uncheckAll");
- equals( $menu.find("input:radio:checked").length, 0, 'After uncheckAll method nothing is checked');
-
- // check/uncheck all links
- equals( $menu.find(".ui-multiselect-all, ui-multiselect-none").filter(":visible").length, 0, "Check/uncheck all links don't exist");
-
- el.multiselect("destroy");
- $("select").attr("multiple","multiple");
- });
-
- test("multiple (changing dynamically)", function(){
- expect(6);
-
- el = $('foo ')
- .appendTo("body")
- .multiselect();
-
- el.multiselect("option", "multiple", false);
- equals(el[0].multiple, false, "When changing a multiple select to a single select, the select element no longer has the multiple property");
- equals(menu().hasClass("ui-multiselect-single"), true, "...and the menu now has the single select class");
- equals(menu().find('input[type="radio"]').length, 1, "...and the checkbox is now a radio button");
-
- el.multiselect("option", "multiple", true);
- equals(el[0].multiple, true, "When changing a single select to a multiple select, the select element has the multiple property");
- equals(menu().hasClass("ui-multiselect-single"), false, "...and the menu doesn't have the single select class");
- equals(menu().find('input[type="checkbox"]').length, 1, "...and the radio button is now a checkbox");
-
- el.multiselect("destroy").remove();
- });
-
- test("classes", function(){
- expect(6);
-
- var classname = 'foo';
-
- el = $("select").multiselect({ classes:classname });
- var $button = button(), $widget = menu();
-
- equals( $widget.hasClass(classname), true, 'menu has the class ' + classname);
- equals( $button.hasClass(classname), true, 'button has the class ' + classname);
-
- // change it up
- var newclass = 'bar';
- el.multiselect("option", "classes", newclass);
- equals( $widget.hasClass(newclass), true, 'menu has the new class ' + newclass);
- equals( $button.hasClass(newclass), true, 'button has the new class ' + newclass);
- equals( $button.hasClass(classname), false, 'menu no longer has the class ' + classname);
- equals( $button.hasClass(classname), false, 'button no longer has the class ' + classname);
- el.multiselect("destroy");
- });
-
- test("header", function(){
- expect(7);
-
- function countLinks(){
- return header().find("a").length;
- }
-
- // default
- el = $("select").multiselect({ autoOpen:true });
- ok(header().is(':visible'), "default config: header is visible" );
- el.multiselect("option", "header", false);
- ok(header().is(':hidden'), "after changing header option on default config: header is no longer visible" );
-
- // test for all links within the default header
- equals(countLinks(), 3, "number of links in the default header config");
-
- el.multiselect("destroy");
-
- // create again, this time header false
- el = $("select").multiselect({ header:false, autoOpen:true });
- ok(header().is(':hidden'), "init with header false: header is not visible" );
- el.multiselect("option", "header", true);
- ok(header().is(':visible'), "after changing header option: header is visible" );
-
- el.multiselect("destroy");
-
- // create again, this time custom header
- el = $("select").multiselect({ header:"hai guyz", autoOpen:true });
- equals(header().text(), "hai guyz", "header equals custom text");
- equals(countLinks(), 1, "number of links in the custom header config (should be close button)");
-
- el.multiselect("destroy");
- });
- test("openIcon", function(){
- expect(1);
- var icon = ' ';
- el = $("select").multiselect({ openIcon:icon });
- equals(button().find(".ui-multiselect-open").find(".ui-icon-search").length, 1);
- el.multiselect("destroy");
- });
- test("closeIcon", function(){
- expect(1);
- var icon = ' ';
- el = $("select").multiselect({ autoOpen:true, closeIcon:icon });
- equals(menu().find(".ui-multiselect-close").find(".ui-icon-search").length, 1);
- el.multiselect("destroy");
- });
+ // uncheck boxes... should only be one
+ radios.filter(":checked").trigger("click");
+
+ // method calls
+ el.multiselect("checkAll");
+ equals( $menu.find("input:radio:checked").length, 1, 'After checkAll method call only one is actually checked');
+
+ el.multiselect("uncheckAll");
+ equals( $menu.find("input:radio:checked").length, 0, 'After uncheckAll method nothing is checked');
+
+ // check/uncheck all links
+ equals( $menu.find(".ui-multiselect-all, ui-multiselect-none").filter(":visible").length, 0, "Check/uncheck all links don't exist");
+
+ el.multiselect("destroy");
+ $("select").attr("multiple","multiple");
+ });
+
+ test("multiple (changing dynamically)", function(){
+ expect(6);
+
+ el = $('foo ')
+ .appendTo("body")
+ .multiselect();
+
+ el.multiselect("option", "multiple", false);
+ equals(el[0].multiple, false, "When changing a multiple select to a single select, the select element no longer has the multiple property");
+ equals(menu().hasClass("ui-multiselect-single"), true, "...and the menu now has the single select class");
+ equals(menu().find('input[type="radio"]').length, 1, "...and the checkbox is now a radio button");
+
+ el.multiselect("option", "multiple", true);
+ equals(el[0].multiple, true, "When changing a single select to a multiple select, the select element has the multiple property");
+ equals(menu().hasClass("ui-multiselect-single"), false, "...and the menu doesn't have the single select class");
+ equals(menu().find('input[type="checkbox"]').length, 1, "...and the radio button is now a checkbox");
+
+ el.multiselect("destroy").remove();
+ });
+
+ test("classes", function(){
+ expect(6);
+
+ var classname = 'foo';
+
+ el = $("select").multiselect({ classes:classname });
+ var $button = button(), $widget = menu();
+
+ equals( $widget.hasClass(classname), true, 'menu has the class ' + classname);
+ equals( $button.hasClass(classname), true, 'button has the class ' + classname);
+
+ // change it up
+ var newclass = 'bar';
+ el.multiselect("option", "classes", newclass);
+ equals( $widget.hasClass(newclass), true, 'menu has the new class ' + newclass);
+ equals( $button.hasClass(newclass), true, 'button has the new class ' + newclass);
+ equals( $button.hasClass(classname), false, 'menu no longer has the class ' + classname);
+ equals( $button.hasClass(classname), false, 'button no longer has the class ' + classname);
+ el.multiselect("destroy");
+ });
+
+ test("header", function(){
+ expect(7);
+
+ function countLinks(){
+ return header().find("a").length;
+ }
+
+ // default
+ el = $("select").multiselect({ autoOpen:true });
+ ok(header().is(':visible'), "default config: header is visible" );
+ el.multiselect("option", "header", false);
+ ok(header().is(':hidden'), "after changing header option on default config: header is no longer visible" );
+
+ // test for all links within the default header
+ equals(countLinks(), 3, "number of links in the default header config");
+
+ el.multiselect("destroy");
+
+ // create again, this time header false
+ el = $("select").multiselect({ header:false, autoOpen:true });
+ ok(header().is(':hidden'), "init with header false: header is not visible" );
+ el.multiselect("option", "header", true);
+ ok(header().is(':visible'), "after changing header option: header is visible" );
+
+ el.multiselect("destroy");
+
+ // create again, this time custom header
+ el = $("select").multiselect({ header:"hai guyz", autoOpen:true });
+ equals(header().text(), "hai guyz", "header equals custom text");
+ equals(countLinks(), 1, "number of links in the custom header config (should be close button)");
+
+ el.multiselect("destroy");
+ });
+ test("openIcon", function(){
+ expect(1);
+ var icon = ' ';
+ el = $("select").multiselect({ openIcon:icon });
+ equals(button().find(".ui-multiselect-open").find(".ui-icon-search").length, 1);
+ el.multiselect("destroy");
+ });
+ test("closeIcon", function(){
+ expect(1);
+ var icon = ' ';
+ el = $("select").multiselect({ autoOpen:true, closeIcon:icon });
+ equals(menu().find(".ui-multiselect-close").find(".ui-icon-search").length, 1);
+ el.multiselect("destroy");
+ });
test("selectedListSeparator", function(){
expect(3);
el = $("select").multiselect({ selectedListSeparator: " ", selectedList: 15 });
From b3b16e551e752d4bfa4fd3c762e9b3dbfae750e6 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 14:15:55 -0800
Subject: [PATCH 04/12] $variable naming
---
tests/unit/methods.js | 394 +++++++++++++++++++++---------------------
1 file changed, 197 insertions(+), 197 deletions(-)
diff --git a/tests/unit/methods.js b/tests/unit/methods.js
index 784761f..675cbaa 100644
--- a/tests/unit/methods.js
+++ b/tests/unit/methods.js
@@ -1,203 +1,203 @@
(function($){
- module("methods");
-
- test("open", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("open");
- ok( el.multiselect("isOpen"), "isOpen parameter true" );
- equals( menu().css("display"), "block", "Test display CSS property" );
- el.multiselect("destroy");
- });
-
- test("close", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("open").multiselect("close");
- ok( !el.multiselect("isOpen"), "isOpen parameter false" );
- equals( menu().css("display"), "none", "Test display CSS property" );
- el.multiselect("destroy");
- });
-
- test("enable", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("disable").multiselect("enable");
- ok( button().is(":disabled") === false, "Button is enabled" );
- ok( el.is(":disabled") === false, "Original select is enabled" );
- el.multiselect("destroy");
- });
-
- test("disable", function(){
- expect(2);
-
- // clone this one so the original is not affected
- el = $("select").clone(true).appendTo(body).multiselect().multiselect("disable");
- ok( button().is(":disabled"), 'Button is disabled');
- ok( el.is(":disabled"), 'Original select is disabled');
- el.multiselect("destroy").remove();
- });
-
- test("enabling w/ pre-disabled tags (#216)", function(){
- expect(5);
-
- el = $('foo bar ')
- .appendTo(document.body)
- .multiselect();
-
- var boxes = menu().find("input");
- var disabled = boxes.first();
- var enabled = boxes.last();
- var key = "ech-multiselect-disabled";
-
- equals(disabled.is(":disabled"), true, "The first option is disabled");
- el.multiselect("disable");
- equals(disabled.attr(key), undefined, "After disabling the widget, the pre-disabled option is not flagged to re-enable");
- equals(enabled.attr(key), "true", "and the enabled option is flagged to be re-enable");
- el.multiselect("enable");
- equals(disabled.is(":disabled"), true, "After enabling, the first option is still disabled");
- equals(disabled.attr(key), undefined, "and the option no longer has the stored data flag");
- el.multiselect("destroy").remove();
- });
-
- test("widget", function(){
- expect(1);
-
- el = $("select").multiselect();
- ok( menu().is("div.ui-multiselect-menu"), 'Widget is the menu element');
- el.multiselect("destroy");
- });
-
- test("getButton", function(){
- expect(1);
-
- el = $("select").multiselect();
- var button = el.multiselect("getButton");
- ok( button.is("button.ui-multiselect"), 'Button is the button element');
- el.multiselect("destroy");
- });
-
- test("getMenu", function(){
- expect(1);
- el = $("select").multiselect();
- var menu = el.multiselect("getMenu");
- ok( menu.is(".ui-multiselect-menu"), 'Menu is the menu element');
- el.multiselect("destroy");
- });
-
- test("getLabels", function(){
- expect(1);
- el = $("select").multiselect();
- var labels = el.multiselect("getLabels");
- ok(labels.length === $(".ui-multiselect-menu label").length, 'Returns all the labels');
- el.multiselect("destroy");
- });
-
- test("addOption", function() {
- expect(2);
- el = $("select").clone().appendTo(body).multiselect();
- var attrs = {title: "Test Title", value: "newOption"};
- el.multiselect("addOption", attrs, "Option New");
- ok(el.find("option[value=newOption]").length === 1, "The option is added to the source element");
- ok(menu().find("input[value=newOption]").length === 1, "The option is added to the menu");
- el.multiselect("destroy").remove();
- });
-
- test("removeOption", function() {
- expect(4);
- el = $("select").clone().appendTo(body).multiselect();
- ok(el.find("option[value=1]").length === 1, "The option exists in the source element");
- ok(menu().find("input[value=1]").length === 1, "The option exists in the menu");
- el.multiselect("removeOption", "1");
- ok(el.find("option[value=1]").length === 0, "The option is removed from the source element");
- ok(menu().find("input[value=1]").length === 0, "The option is removed from the menu");
- el.multiselect("destroy").remove();
- });
-
- test("checkAll", function(){
- expect(1);
-
- el = $("select").multiselect().multiselect("checkAll");
- var inputs = menu().find("input");
- ok( inputs.filter(":checked").length === inputs.length, 'All inputs selected on the widget?');
- el.multiselect("destroy");
- });
-
- test("uncheckAll", function(){
- expect(1);
-
- el = $("select").multiselect().multiselect("checkAll").multiselect("uncheckAll");
- ok( menu().find("input:checked").length === 0, 'All inputs unchecked on the widget?');
- el.multiselect("destroy");
- });
-
- test("isOpen", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("open");
- ok( el.multiselect("isOpen"), 'Testing isOpen method after calling open method');
- el = $("select").multiselect("close");
- ok( !el.multiselect("isOpen"), 'Testing isOpen method after calling close method');
- el.multiselect("destroy");
- });
-
- test("destroy", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("destroy");
- ok( !$(".ui-multiselect").length , 'button.ui-multiselect removed from the DOM');
- ok( !el.data("multiselect") , 'no more multiselect obj attached to elem');
- });
-
- test("getChecked", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("checkAll");
- equals( el.multiselect("getChecked").length, 9, 'number of checkboxes returned after checking all and calling getChecked');
- el.multiselect("uncheckAll");
- equals( el.multiselect("getChecked").length, 0, 'number of checkboxes returned after unchecking all and calling getChecked');
- el.multiselect("destroy");
- });
+ module("methods");
+
+ test("open", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("open");
+ ok( el.multiselect("isOpen"), "isOpen parameter true" );
+ equals( menu().css("display"), "block", "Test display CSS property" );
+ el.multiselect("destroy");
+ });
+
+ test("close", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("open").multiselect("close");
+ ok( !el.multiselect("isOpen"), "isOpen parameter false" );
+ equals( menu().css("display"), "none", "Test display CSS property" );
+ el.multiselect("destroy");
+ });
+
+ test("enable", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("disable").multiselect("enable");
+ ok( button().is(":disabled") === false, "Button is enabled" );
+ ok( el.is(":disabled") === false, "Original select is enabled" );
+ el.multiselect("destroy");
+ });
+
+ test("disable", function(){
+ expect(2);
+
+ // clone this one so the original is not affected
+ el = $("select").clone(true).appendTo(body).multiselect().multiselect("disable");
+ ok( button().is(":disabled"), 'Button is disabled');
+ ok( el.is(":disabled"), 'Original select is disabled');
+ el.multiselect("destroy").remove();
+ });
+
+ test("enabling w/ pre-disabled tags (#216)", function(){
+ expect(5);
+
+ el = $('foo bar ')
+ .appendTo(document.body)
+ .multiselect();
+
+ var boxes = menu().find("input");
+ var disabled = boxes.first();
+ var enabled = boxes.last();
+ var key = "ech-multiselect-disabled";
+
+ equals(disabled.is(":disabled"), true, "The first option is disabled");
+ el.multiselect("disable");
+ equals(disabled.attr(key), undefined, "After disabling the widget, the pre-disabled option is not flagged to re-enable");
+ equals(enabled.attr(key), "true", "and the enabled option is flagged to be re-enable");
+ el.multiselect("enable");
+ equals(disabled.is(":disabled"), true, "After enabling, the first option is still disabled");
+ equals(disabled.attr(key), undefined, "and the option no longer has the stored data flag");
+ el.multiselect("destroy").remove();
+ });
+
+ test("widget", function(){
+ expect(1);
+
+ el = $("select").multiselect();
+ ok( menu().is("div.ui-multiselect-menu"), 'Widget is the menu element');
+ el.multiselect("destroy");
+ });
+
+ test("getButton", function(){
+ expect(1);
+
+ el = $("select").multiselect();
+ var button = el.multiselect("getButton");
+ ok( button.is("button.ui-multiselect"), 'Button is the button element');
+ el.multiselect("destroy");
+ });
+
+ test("getMenu", function(){
+ expect(1);
+ el = $("select").multiselect();
+ var menu = el.multiselect("getMenu");
+ ok( menu.is(".ui-multiselect-menu"), 'Menu is the menu element');
+ el.multiselect("destroy");
+ });
+
+ test("getLabels", function(){
+ expect(1);
+ el = $("select").multiselect();
+ var labels = el.multiselect("getLabels");
+ ok(labels.length === $(".ui-multiselect-menu label").length, 'Returns all the labels');
+ el.multiselect("destroy");
+ });
+
+ test("addOption", function() {
+ expect(2);
+ el = $("select").clone().appendTo(body).multiselect();
+ var attrs = {title: "Test Title", value: "newOption"};
+ el.multiselect("addOption", attrs, "Option New");
+ ok(el.find("option[value=newOption]").length === 1, "The option is added to the source element");
+ ok(menu().find("input[value=newOption]").length === 1, "The option is added to the menu");
+ el.multiselect("destroy").remove();
+ });
+
+ test("removeOption", function() {
+ expect(4);
+ el = $("select").clone().appendTo(body).multiselect();
+ ok(el.find("option[value=1]").length === 1, "The option exists in the source element");
+ ok(menu().find("input[value=1]").length === 1, "The option exists in the menu");
+ el.multiselect("removeOption", "1");
+ ok(el.find("option[value=1]").length === 0, "The option is removed from the source element");
+ ok(menu().find("input[value=1]").length === 0, "The option is removed from the menu");
+ el.multiselect("destroy").remove();
+ });
+
+ test("checkAll", function(){
+ expect(1);
+
+ el = $("select").multiselect().multiselect("checkAll");
+ var inputs = menu().find("input");
+ ok( inputs.filter(":checked").length === inputs.length, 'All inputs selected on the widget?');
+ el.multiselect("destroy");
+ });
+
+ test("uncheckAll", function(){
+ expect(1);
+
+ el = $("select").multiselect().multiselect("checkAll").multiselect("uncheckAll");
+ ok( menu().find("input:checked").length === 0, 'All inputs unchecked on the widget?');
+ el.multiselect("destroy");
+ });
+
+ test("isOpen", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("open");
+ ok( el.multiselect("isOpen"), 'Testing isOpen method after calling open method');
+ el = $("select").multiselect("close");
+ ok( !el.multiselect("isOpen"), 'Testing isOpen method after calling close method');
+ el.multiselect("destroy");
+ });
+
+ test("destroy", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("destroy");
+ ok( !$(".ui-multiselect").length , 'button.ui-multiselect removed from the DOM');
+ ok( !el.data("multiselect") , 'no more multiselect obj attached to elem');
+ });
+
+ test("getChecked", function(){
+ expect(2);
+
+ el = $("select").multiselect().multiselect("checkAll");
+ equals( el.multiselect("getChecked").length, 9, 'number of checkboxes returned after checking all and calling getChecked');
+ el.multiselect("uncheckAll");
+ equals( el.multiselect("getChecked").length, 0, 'number of checkboxes returned after unchecking all and calling getChecked');
+ el.multiselect("destroy");
+ });
test("getUnchecked", function(){
- expect(2);
-
- el = $("select").multiselect().multiselect("checkAll");
- equals( el.multiselect("getUnchecked").length, 0, 'number of checkboxes returned after checking all and calling getUnchecked');
- el.multiselect("uncheckAll");
- equals( el.multiselect("getUnchecked").length, 9, 'number of checkboxes returned after unchecking all and calling getUnchecked');
- el.multiselect("destroy");
- });
-
- test("refresh", function(){
- expect(6);
-
- el = $("select").clone().appendTo(body).multiselect();
- el.empty().html('foo bar ');
- el.multiselect('refresh');
-
- var checkboxes, getCheckboxes = (function hai(){
- checkboxes = menu().find('input[type="checkbox"]');
- return hai;
- })();
-
- equals( checkboxes.length, 2, "After clearing the select, adding 2 options, and refresh(), only 2 checkboxes exist");
- equals( checkboxes.eq(0).val(), 'foo', 'first is foo' );
- equals( checkboxes.eq(1).val(), 'bar', 'second is bar' );
-
- // add one more w/ append, just for safety's sake
- el.append('baz ');
- el.multiselect('refresh');
- getCheckboxes();
- equals( checkboxes.eq(2).val(), 'baz', 'after an append() call, the third option is now baz' );
- equals($(el.multiselect("instance").inputs[0]).data().testval, 123, "the first input has the data attribute testval with value 123");
- equals($(el.multiselect("instance").inputs[2]).data().testval, "something", "the third input has the data attribute testval with value something");
-
- el.multiselect("destroy").remove();
- });
-
- test("position", function() {
+ expect(2);
+
+ el = $("select").multiselect().multiselect("checkAll");
+ equals( el.multiselect("getUnchecked").length, 0, 'number of checkboxes returned after checking all and calling getUnchecked');
+ el.multiselect("uncheckAll");
+ equals( el.multiselect("getUnchecked").length, 9, 'number of checkboxes returned after unchecking all and calling getUnchecked');
+ el.multiselect("destroy");
+ });
+
+ test("refresh", function(){
+ expect(6);
+
+ el = $("select").clone().appendTo(body).multiselect();
+ el.empty().html('foo bar ');
+ el.multiselect('refresh');
+
+ var checkboxes, getCheckboxes = (function hai(){
+ checkboxes = menu().find('input[type="checkbox"]');
+ return hai;
+ })();
+
+ equals( checkboxes.length, 2, "After clearing the select, adding 2 options, and refresh(), only 2 checkboxes exist");
+ equals( checkboxes.eq(0).val(), 'foo', 'first is foo' );
+ equals( checkboxes.eq(1).val(), 'bar', 'second is bar' );
+
+ // add one more w/ append, just for safety's sake
+ el.append('baz ');
+ el.multiselect('refresh');
+ getCheckboxes();
+ equals( checkboxes.eq(2).val(), 'baz', 'after an append() call, the third option is now baz' );
+ equals($(el.multiselect("instance").$inputs[0]).data().testval, 123, "the first input has the data attribute testval with value 123");
+ equals($(el.multiselect("instance").$inputs[2]).data().testval, "something", "the third input has the data attribute testval with value something");
+
+ el.multiselect("destroy").remove();
+ });
+
+ test("position", function() {
expect(2);
var left = "500px";
@@ -216,6 +216,6 @@
equals(menu().css("left"), left, "After calling position(), the menu has updated to the same left value as the button");
el.multiselect("destroy").remove();
- });
+ });
})(jQuery);
From 730198a6961b76f5d539b85ee866b34910ac7748 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 14:37:33 -0800
Subject: [PATCH 05/12] Fix comment alignment
---
src/jquery.multiselect.js | 58 +++++++++++++++++++--------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index ddaeaf7..4f4517d 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -4,7 +4,7 @@
* Copyright (c) 2012 Eric Hynds
*
* Depends:
- * - jQuery 1.7+ (http://api.jquery.com/)
+ * - jQuery 1.7+ (http://api.jquery.com/)
* - jQuery UI 1.11 widget factory (http://api.jqueryui.com/jQuery.widget/)
*
* Optional:
@@ -25,48 +25,48 @@
// default options
options: {
- header: true, // (true | false) If true, the header is shown.
- height: 175, // (int) Sets the height of the menu.
- minWidth: 225, // (int) Sets the minimum width of the menu.
- classes: '', // Classes that you can provide to be applied to the elements making up the widget.
+ header: true, // (true | false) If true, the header is shown.
+ height: 175, // (int) Sets the height of the menu.
+ minWidth: 225, // (int) Sets the minimum width of the menu.
+ classes: '', // Classes that you can provide to be applied to the elements making up the widget.
openIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
- closeIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
- checkAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ closeIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
+ checkAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
uncheckAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
flipAllIcon: ' ', // Scaleable HTML Entities or Font-Awesome icons can be specified here instead of the default jQuery UI icons.
- checkAllText: 'Check all', // (str | blank | null) If blank or null, link not shown.
- uncheckAllText: 'Uncheck all', // (str | blank | null) If blank or null, link not shown.
- flipAllText: 'Flip all', // (str | blank | null) If blank or null, link not shown.
- showCheckAll: true, // (true | false) Show or hide the Check All link without blanking the text.
- showUncheckAll: true, // (true | false) Show or hide the Uncheck All link without blanking the text.
- showFlipAll: false, // (true | false) Show or hide the Flip All link without blanking the text.
- noneSelectedText: 'Select options', // (str) The text to show in the button where nothing is selected.
- selectedText: '# of # selected', // (str) A "template" that indicates how to show the count of selections in the button. The "#'s" are replaced by the selection count & option count.
- selectedList: 0, // (int) The actual list selections will be shown in the button when the count of selections is <= than this number.
- show: null, // (array) An array containing menu opening effects.
- hide: null, // (array) An array containing menu closing effects.
- autoOpen: false, // (true | false) If true, then the menu will be opening immediately after initialization.
- position: {}, // (object) A jQuery UI position object that constrains how the pop-up menu is positioned.
- appendTo: null, // (jQuery | DOM element | selector str) If provided, this specifies what element to append the widget to in the DOM.
- menuWidth:null, // (int | null) If a number is provided, sets the menu width.
- selectedListSeparator: ', ', // (str) This allows customization of the list separator. Use ', ' to make the button grow vertically showing 1 selection per line.
- disableInputsOnToggle: true, // (true | false)
- groupColumns: false // (true | false)
+ checkAllText: 'Check all', // (str | blank | null) If blank or null, link not shown.
+ uncheckAllText: 'Uncheck all', // (str | blank | null) If blank or null, link not shown.
+ flipAllText: 'Flip all', // (str | blank | null) If blank or null, link not shown.
+ showCheckAll: true, // (true | false) Show or hide the Check All link without blanking the text.
+ showUncheckAll: true, // (true | false) Show or hide the Uncheck All link without blanking the text.
+ showFlipAll: false, // (true | false) Show or hide the Flip All link without blanking the text.
+ noneSelectedText: 'Select options', // (str) The text to show in the button where nothing is selected.
+ selectedText: '# of # selected', // (str) A "template" that indicates how to show the count of selections in the button. The "#'s" are replaced by the selection count & option count.
+ selectedList: 0, // (int) The actual list selections will be shown in the button when the count of selections is <= than this number.
+ show: null, // (array) An array containing menu opening effects.
+ hide: null, // (array) An array containing menu closing effects.
+ autoOpen: false, // (true | false) If true, then the menu will be opening immediately after initialization.
+ position: {}, // (object) A jQuery UI position object that constrains how the pop-up menu is positioned.
+ appendTo: null, // (jQuery | DOM element | selector str) If provided, this specifies what element to append the widget to in the DOM.
+ menuWidth:null, // (int | null) If a number is provided, sets the menu width.
+ selectedListSeparator: ', ', // (str) This allows customization of the list separator. Use ', ' to make the button grow vertically showing 1 selection per line.
+ disableInputsOnToggle: true, // (true | false)
+ groupColumns: false // (true | false)
},
// This method determines which element to append the menu to
// Uses the element provided in the options first, then looks for ui-front / dialog
// Otherwise appends to the body
_getAppendEl: function() {
- var elem = this.options.appendTo; // jQuery object, DOM element, OR selector str.
+ var elem = this.options.appendTo; // jQuery object, DOM element, OR selector str.
if(elem) {
- elem = elem.jquery || elem.nodeType ? $(elem) : this.document.find(elem).eq(0); // Note that the find handles the selector case.
+ elem = elem.jquery || elem.nodeType ? $(elem) : this.document.find(elem).eq(0); // Note that the find handles the selector case.
}
if(!elem || !elem[0]) {
elem = this.element.closest(".ui-front, dialog");
}
if(!elem.length) {
- elem = this.document[0].body; // Position at end of body.
+ elem = this.document[0].body; // Position at end of body.
}
return elem;
},
@@ -184,7 +184,7 @@
*/
_makeOption: function(option) {
var title = option.title || null;
- var $element = this.element; // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
+ var $element = this.element; // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
var id = $element[0].id || this.multiselectID; // unique ID for the label & option tags
var inputID = 'ui-multiselect-' + this.multiselectID + '-' + (option.id || id + '-option-' + this.inputIdCounter++);
var isDisabled = option.disabled;
From 12eea3879e05dd0aa02e6e15a1b8b7950ce74520 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 15:00:44 -0800
Subject: [PATCH 06/12] Added comment
---
src/jquery.multiselect.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index 4f4517d..a415244 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -63,7 +63,7 @@
elem = elem.jquery || elem.nodeType ? $(elem) : this.document.find(elem).eq(0); // Note that the find handles the selector case.
}
if(!elem || !elem[0]) {
- elem = this.element.closest(".ui-front, dialog");
+ elem = this.element.closest(".ui-front, dialog"); // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
}
if(!elem.length) {
elem = this.document[0].body; // Position at end of body.
From 79274babcc3c1ac55cc26b287d130bb35ed59f17 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 15:13:16 -0800
Subject: [PATCH 07/12] Consistently set var $element = this.element
---
src/jquery.multiselect.js | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index a415244..8b951ec 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -254,7 +254,7 @@
// Refreshes the widget to pick up changes to the underlying select
// Rebuilds the menu, sets button width
refresh: function(init) {
- var $el = this.element; // "element" is a jQuery object representing the underlying select
+ var $element = this.element; // "element" is a jQuery object representing the underlying select
var $menu = this.$menu;
var $headerLinks = this.$headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip');
var $dropdown = $("").addClass('ui-multiselect-checkboxes ui-helper-reset');
@@ -263,14 +263,14 @@
// update header link container visibility if needed
if (this.options.header) {
- if(!!$el[0].multiple) {
+ if(!!$element[0].multiple) {
$headerLinks.show();
} else {
$headerLinks.hide();
}
}
- this._buildOptionList($el, $dropdown);
+ this._buildOptionList($element, $dropdown);
this.$menu.find(".ui-multiselect-checkboxes").remove();
this.$menu.append($dropdown);
@@ -448,7 +448,7 @@
var val = this.value;
var optionText = $this.parent().find("span").text();
var checked = this.checked;
- var $tags = self.element.find('option');
+ var $tags = self.element.find('option'); // "element" is a jQuery object representing the underlying select
var isMultiple = !!self.element[0].multiple;
// bail if this input is disabled or the event is cancelled
@@ -670,7 +670,7 @@
_toggleChecked: function(flag, group) {
var $inputs = (group && group.length) ? group : this.$inputs;
var self = this;
- var $el = this.element; // element is a jQuery object
+ var $element = this.element; // element is a jQuery object
// toggle state on inputs
$inputs.each(this._toggleState('checked', flag));
@@ -688,8 +688,8 @@
});
// toggle state on original option tags
- $el.selectedIndex = -1;
- $el
+ $element.selectedIndex = -1;
+ $element
.find('option')
.each(function() {
if(!this.disabled && values[this.value]) {
@@ -699,7 +699,7 @@
// trigger the change event on the select
if($inputs.length) {
- $el.trigger("change");
+ $element.trigger("change");
}
},
From 2884af22c2ce84cd362fd81f71b2de6e9bdf1e3a Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 15:40:03 -0800
Subject: [PATCH 08/12] Relocate comment in init
---
src/jquery.multiselect.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index 8b951ec..ea5a145 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -154,13 +154,13 @@
// https://api.jqueryui.com/jquery.widget/#method-_init
_init: function() {
- var $element = this.element;
+ var $element = this.element; // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
var $headerLinks = this.$headerLinkContainer.find('.ui-multiselect-all, .ui-multiselect-none, .ui-multiselect-flip');
if(this.options.header === false) {
this.$header.hide();
}
- if(!!$element[0].multiple) { // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
+ if(!!$element[0].multiple) {
$headerLinks.show();
} else {
$headerLinks.hide();
From a94c0a16ab00d5b3214e307e9f074953b32a24fa Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 16:52:54 -0800
Subject: [PATCH 09/12] Use $element instead of $el
---
src/jquery.multiselect.js | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index ea5a145..f0ba55f 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -73,7 +73,7 @@
// Performs the initial creation of the widget
_create: function() {
- var $el = this.element.hide(); // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
+ var $element = this.element.hide(); // element is a jQuery object per http://api.jqueryui.com/jQuery.widget/
var o = this.options;
this.speed = $.fx.speeds._default; // default speed for effects
@@ -91,9 +91,12 @@
// The ui-multiselect-open span is necessary below to simplify dynamically changing the open icon.
var $button = (this.$button = $('' + o.openIcon + ' '))
.addClass('ui-multiselect ui-widget ui-state-default ui-corner-all ' + o.classes)
- .attr({ title: $el.attr('title'), tabIndex: $el.attr('tabIndex'), id: $el.attr('id') ? $el.attr('id') + '_ms' : null })
+ .attr({ title: $element.attr('title'),
+ tabIndex: $element.attr('tabIndex'),
+ id: $element.attr('id') ? $element.attr('id') + '_ms' : null
+ })
.prop('aria-haspopup', true)
- .insertAfter($el);
+ .insertAfter($element);
this.$buttonlabel = $(' ')
.html(o.noneSelectedText)
@@ -147,7 +150,7 @@
this.refresh(true);
// If this is a single select widget, add the appropriate class
- if(!$el[0].multiple) {
+ if(!$element[0].multiple) {
$menu.addClass('ui-multiselect-single');
}
},
From 09f7a077f613b593043a046ee8afa556624ec13f Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 19:02:29 -0800
Subject: [PATCH 10/12] Implement selectedMax feature
---
src/jquery.multiselect.js | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/jquery.multiselect.js b/src/jquery.multiselect.js
index f0ba55f..7dba363 100644
--- a/src/jquery.multiselect.js
+++ b/src/jquery.multiselect.js
@@ -43,6 +43,7 @@
noneSelectedText: 'Select options', // (str) The text to show in the button where nothing is selected.
selectedText: '# of # selected', // (str) A "template" that indicates how to show the count of selections in the button. The "#'s" are replaced by the selection count & option count.
selectedList: 0, // (int) The actual list selections will be shown in the button when the count of selections is <= than this number.
+ selectedMax: null, // (int | function) If selected count > selectedMax or if function returns 1, then message is displayed, and new selection is undone.
show: null, // (array) An array containing menu opening effects.
hide: null, // (array) An array containing menu closing effects.
autoOpen: false, // (true | false) If true, then the menu will be opening immediately after initialization.
@@ -453,13 +454,32 @@
var checked = this.checked;
var $tags = self.element.find('option'); // "element" is a jQuery object representing the underlying select
var isMultiple = !!self.element[0].multiple;
-
+ var inputCount = self.$inputs.length;
+ var numChecked = self.$inputs.filter(":checked").length;
+ var selectedMax = self.options.selectedMax;
+
// bail if this input is disabled or the event is cancelled
if(this.disabled || self._trigger('click', e, { value: val, text: optionText, checked: checked }) === false) {
e.preventDefault();
return;
}
+ if ( selectedMax && checked && ( $.isFunction(selectedMax) ? !!selectedMax.call(this, self.$inputs) : numChecked > selectedMax ) ) {
+ var o = self.options;
+ var saveText = o.selectedText;
+
+ // The following warning is shown in the button and then cleared after a second.
+ o.selectedText = "LIMIT OF " + (numChecked - 1) + " REACHED! ";
+ self.update();
+ setTimeout( function() {
+ o.selectedText = saveText;
+ self.update();
+ }, 1000 );
+
+ e.preventDefault(); // Kill the event.
+ return false;
+ }
+
// make sure the input has focus. otherwise, the esc key
// won't close the menu after clicking an item.
$this.focus();
@@ -993,6 +1013,7 @@
break;
case 'selectedText':
case 'selectedList':
+ case 'selectedMax':
case 'noneSelectedText':
this.options[key] = value; // these all needs to update immediately for the update() call
this.update();
From c711b5999222ccf70c6148bbf30a9a8257464184 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 19:04:19 -0800
Subject: [PATCH 11/12] Add test for selectedMax
---
tests/unit/options.js | 633 +++++++++++++++++++++---------------------
1 file changed, 324 insertions(+), 309 deletions(-)
diff --git a/tests/unit/options.js b/tests/unit/options.js
index 5ca530a..b430c94 100644
--- a/tests/unit/options.js
+++ b/tests/unit/options.js
@@ -1,182 +1,197 @@
(function($){
- module("options");
+ module("options");
- test("noneSelectedText", function(){
- expect(7);
- var text;
+ test("noneSelectedText", function(){
+ expect(7);
+ var text;
- el = $("select").multiselect({
- noneSelectedText: 'None Selected'
- });
+ el = $("select").multiselect({
+ noneSelectedText: 'None Selected'
+ });
- // read from widget
- text = el.multiselect("option", "noneSelectedText");
+ // read from widget
+ text = el.multiselect("option", "noneSelectedText");
- equals( button().text(), text, 'on init, button reads "None Selected"');
- el.multiselect("checkAll");
- ok( button().text() !== text, 'after checkAll, button no longer reads "None Selected"');
- el.multiselect("uncheckAll");
- equals( button().text(), text, 'after uncheckAll, button text restored to "None Selected"');
+ equals( button().text(), text, 'on init, button reads "None Selected"');
+ el.multiselect("checkAll");
+ ok( button().text() !== text, 'after checkAll, button no longer reads "None Selected"');
+ el.multiselect("uncheckAll");
+ equals( button().text(), text, 'after uncheckAll, button text restored to "None Selected"');
- // change the option value
- el.multiselect("option", "noneSelectedText", "No Checkboxes Checked");
- equals( el.multiselect("option", "noneSelectedText"), "No Checkboxes Checked", "new noneSelectedText value set correctly");
+ // change the option value
+ el.multiselect("option", "noneSelectedText", "No Checkboxes Checked");
+ equals( el.multiselect("option", "noneSelectedText"), "No Checkboxes Checked", "new noneSelectedText value set correctly");
+
+ // read updated value from widget
+ text = el.multiselect("option", "noneSelectedText");
+
+ // test against the new value
+ equals( button().text(), text, 'after changing the option value, button now reads "No Checkboxes Checked"');
+ el.multiselect("checkAll");
+ ok( button().text() !== text, 'after checkAll, button no longer reads "No Checkboxes Checked"');
+ el.multiselect("uncheckAll");
+ equals( button().text(), text, 'after uncheckAll, button text restored to "No Checkboxes Checked"');
+
+ el.multiselect("destroy");
+ });
+
+ test("selectedText", function(){
+ expect(3);
+ var numOptions = $("select option").length;
+
+ el = $("select").multiselect({
+ selectedText: '# of # selected'
+ });
+
+ el.multiselect("checkAll");
+ equals( button().text(), numOptions+' of '+numOptions+' selected', 'after checkAll, button reflects the total number of checked boxes');
+
+ // change option value
+ el.multiselect("option", "selectedText", function( numChecked ){
+ return numChecked + ' options selected';
+ });
+
+ equals( button().text(), numOptions+' options selected', 'after changing the option to a function value, button reflects the new text');
- // read updated value from widget
- text = el.multiselect("option", "noneSelectedText");
+ // uncheck all
+ el.multiselect("uncheckAll");
+ equals( button().text(), el.multiselect("option","noneSelectedText"), 'after unchecking all, button text now reflects noneSelectedText option value');
- // test against the new value
- equals( button().text(), text, 'after changing the option value, button now reads "No Checkboxes Checked"');
- el.multiselect("checkAll");
- ok( button().text() !== text, 'after checkAll, button no longer reads "No Checkboxes Checked"');
- el.multiselect("uncheckAll");
- equals( button().text(), text, 'after uncheckAll, button text restored to "No Checkboxes Checked"');
+ el.multiselect("destroy");
+ });
- el.multiselect("destroy");
- });
+ test("selectedList", function(){
+ expect(2);
- test("selectedText", function(){
- expect(3);
- var numOptions = $("select option").length;
+ var html = 'foo "with quotes" bar baz ';
- el = $("select").multiselect({
- selectedText: '# of # selected'
- });
+ el = $(html).appendTo("body").multiselect({
+ selectedList: 3
+ });
- el.multiselect("checkAll");
- equals( button().text(), numOptions+' of '+numOptions+' selected', 'after checkAll, button reflects the total number of checked boxes');
+ el.multiselect("checkAll");
+ equals( button().text(), 'foo "with quotes", bar, baz', 'after checkAll, button text is a list of all options in the select');
+ el.multiselect("destroy").remove();
- // change option value
- el.multiselect("option", "selectedText", function( numChecked ){
- return numChecked + ' options selected';
- });
+ el = $(html).appendTo("body").multiselect({
+ selectedList: 2
+ });
- equals( button().text(), numOptions+' options selected', 'after changing the option to a function value, button reflects the new text');
+ el.multiselect("checkAll");
+ equals( button().text(), '3 of 3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
+ el.multiselect("destroy").remove();
+ });
- // uncheck all
- el.multiselect("uncheckAll");
- equals( button().text(), el.multiselect("option","noneSelectedText"), 'after unchecking all, button text now reflects noneSelectedText option value');
+ test("selectedMax", function(){
+ expect(1);
- el.multiselect("destroy");
- });
+ var html = 'foo "with quotes" bar baz ';
+
+ el = $(html).appendTo("body").multiselect({
+ selectedMax: 2
+ });
+
+ el.multiselect("checkAll");
+ equals( menu().find("input").filter(":checked").length, 2 , 'after checkAll, count of checked restored to selectedMax of 2');
+ el.multiselect("destroy").remove();
+
+ });
+
+ function asyncSelectedList( useTrigger, message ){
+ expect(1);
+ stop();
- test("selectedList", function(){
- expect(2);
+ var html = 'foo bar baz ',
+ checkboxes;
- var html = 'foo "with quotes" bar baz ';
+ el = $(html).appendTo(body).multiselect({
+ selectedList: 2
+ });
- el = $(html).appendTo("body").multiselect({
- selectedList: 3
- });
+ checkboxes = el.multiselect("widget").find(":checkbox");
- el.multiselect("checkAll");
- equals( button().text(), 'foo "with quotes", bar, baz', 'after checkAll, button text is a list of all options in the select');
- el.multiselect("destroy").remove();
+ if( useTrigger ){
+ checkboxes.eq(0).trigger('click');
+ checkboxes.eq(1).trigger('click');
+ } else {
+ checkboxes.eq(0)[0].click();
+ checkboxes.eq(1)[0].click();
+ }
- el = $(html).appendTo("body").multiselect({
- selectedList: 2
- });
+ setTimeout(function(){
+ equals( button().text(), 'foo, bar', message);
+ el.multiselect("destroy").remove();
+ start();
+ }, 10);
+ }
- el.multiselect("checkAll");
- equals( button().text(), '3 of 3 selected', 'after checkAll with a limited selectedList value, button value displays number of checked');
- el.multiselect("destroy").remove();
- });
+ test("selectedList - manual trigger - jQuery", function(){
+ asyncSelectedList( true, 'manually checking items with trigger()' );
+ });
- function asyncSelectedList( useTrigger, message ){
- expect(1);
- stop();
+ test("selectedList - manual trigger - native", function(){
+ asyncSelectedList( false, 'manually checking items with element.click()' );
+ });
- var html = 'foo bar baz ',
- checkboxes;
+ test("selectedList - encoding", function() {
+ expect(1);
- el = $(html).appendTo(body).multiselect({
- selectedList: 2
- });
+ el = $('A&E ')
+ .appendTo("body")
+ .multiselect({ selectedList: 1 });
- checkboxes = el.multiselect("widget").find(":checkbox");
+ equals(button().text(), 'A&E');
+ el.multiselect("destroy").remove();
+ });
- if( useTrigger ){
- checkboxes.eq(0).trigger('click');
- checkboxes.eq(1).trigger('click');
- } else {
- checkboxes.eq(0)[0].click();
- checkboxes.eq(1)[0].click();
- }
+ test("height", function(){
+ expect(2);
- setTimeout(function(){
- equals( button().text(), 'foo, bar', message);
- el.multiselect("destroy").remove();
- start();
- }, 10);
- }
+ var height = 100;
- test("selectedList - manual trigger - jQuery", function(){
- asyncSelectedList( true, 'manually checking items with trigger()' );
- });
+ el = $("select").multiselect({ height: height }).multiselect("open");
+ equals( height, menu().find("ul.ui-multiselect-checkboxes").height(), 'height after opening property set to '+ height );
- test("selectedList - manual trigger - native", function(){
- asyncSelectedList( false, 'manually checking items with element.click()' );
- });
+ // change height and re-test
+ height = 300;
+ el.multiselect("option", "height", height);
+ equals( height, menu().find(".ui-multiselect-checkboxes").height(), 'changing value through api to '+ height );
- test("selectedList - encoding", function() {
- expect(1);
+ el.multiselect("destroy");
+ });
- el = $('A&E ')
- .appendTo("body")
- .multiselect({ selectedList: 1 });
+ test("minWidth", function(){
+ expect(5);
- equals(button().text(), 'A&E');
- el.multiselect("destroy").remove();
- });
-
- test("height", function(){
- expect(2);
-
- var height = 100;
-
- el = $("select").multiselect({ height: height }).multiselect("open");
- equals( height, menu().find("ul.ui-multiselect-checkboxes").height(), 'height after opening property set to '+ height );
-
- // change height and re-test
- height = 300;
- el.multiselect("option", "height", height);
- equals( height, menu().find(".ui-multiselect-checkboxes").height(), 'changing value through api to '+ height );
-
- el.multiselect("destroy");
- });
-
- test("minWidth", function(){
- expect(5);
-
- var minWidth = 321;
-
- el = $("select").multiselect({ minWidth:minWidth }).multiselect("open");
- equals( minWidth, button().outerWidth(), 'outerWidth of button is ' + minWidth );
-
- // change height and re-test
- minWidth = 351;
- el.multiselect("option", "minWidth", minWidth);
- equals( minWidth, button().outerWidth(), 'changing value through api to '+minWidth);
-
- // change height to something that should fail.
- minWidth = 10;
- el.multiselect("option", "minWidth", minWidth);
- var outerWidth = button().outerWidth();
- ok( minWidth !== outerWidth, 'changing value through api to '+minWidth+' (too small), outerWidth is actually ' + outerWidth);
-
- minWidth = "50%";
- el.multiselect("option", "minWidth", minWidth);
- outerWidth = Math.floor(button().outerWidth());
- var halfParent = Math.floor(el.parent().outerWidth()/2);
- ok(outerWidth === halfParent, 'changing value to 50%');
-
- minWidth = "351px";
- el.multiselect("option", "minWidth", minWidth);
- equals( 351, button().outerWidth(), 'minWidth supports strings suffixed with px as well as integer px values');
-
- el.multiselect("destroy");
- });
+ var minWidth = 321;
+
+ el = $("select").multiselect({ minWidth:minWidth }).multiselect("open");
+ equals( minWidth, button().outerWidth(), 'outerWidth of button is ' + minWidth );
+
+ // change height and re-test
+ minWidth = 351;
+ el.multiselect("option", "minWidth", minWidth);
+ equals( minWidth, button().outerWidth(), 'changing value through api to '+minWidth);
+
+ // change height to something that should fail.
+ minWidth = 10;
+ el.multiselect("option", "minWidth", minWidth);
+ var outerWidth = button().outerWidth();
+ ok( minWidth !== outerWidth, 'changing value through api to '+minWidth+' (too small), outerWidth is actually ' + outerWidth);
+
+ minWidth = "50%";
+ el.multiselect("option", "minWidth", minWidth);
+ outerWidth = Math.floor(button().outerWidth());
+ var halfParent = Math.floor(el.parent().outerWidth()/2);
+ ok(outerWidth === halfParent, 'changing value to 50%');
+
+ minWidth = "351px";
+ el.multiselect("option", "minWidth", minWidth);
+ equals( 351, button().outerWidth(), 'minWidth supports strings suffixed with px as well as integer px values');
+
+ el.multiselect("destroy");
+ });
test("menuWidth", function(){
expect(2);
@@ -194,193 +209,193 @@
el.multiselect("destroy");
});
- test("checkAllText", function(){
- expect(2);
- var text = "foo";
-
- el = $("select").multiselect({ checkAllText:text, showCheckAll:true });
- equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
-
- // set through option
- text = "bar";
- el.multiselect("option","checkAllText","bar");
- equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
-
- el.multiselect("destroy");
- });
-
- test("uncheckAllText", function(){
- expect(2);
- var text = "foo";
-
- el = $("select").multiselect({ uncheckAllText:text, showUncheckAll:true });
- equals( text, menu().find(".ui-multiselect-none").text(), 'check all link reads '+text );
-
- // set through option
- text = "bar";
- el.multiselect("option","uncheckAllText","bar");
- equals( text, menu().find(".ui-multiselect-none").text(), 'changing value through api to '+text );
-
- el.multiselect("destroy");
- });
-
- test("flipAllText", function(){
- expect(2);
- var text = "foo";
-
- el = $("select").multiselect({ flipAllText:text, showFlipAll:true });
- equals( text, menu().find(".ui-multiselect-flip").text(), 'flip all link reads '+text );
-
- // set through option
- text = "bar";
- el.multiselect("option","flipAllText","bar");
- equals( text, menu().find(".ui-multiselect-flip").text(), 'changing value through api to '+text );
-
- el.multiselect("destroy");
- });
-
- test("autoOpen", function(){
- expect(2);
+ test("checkAllText", function(){
+ expect(2);
+ var text = "foo";
- el = $("select").multiselect({ autoOpen:false });
+ el = $("select").multiselect({ checkAllText:text, showCheckAll:true });
+ equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
- ok( menu().is(":hidden"), 'menu is hidden with autoOpen off');
- el.multiselect("destroy");
+ // set through option
+ text = "bar";
+ el.multiselect("option","checkAllText","bar");
+ equals( text, menu().find(".ui-multiselect-all").text(), 'check all link reads '+text );
- el = $("select").multiselect({ autoOpen:true });
- ok( menu().is(":visible"), 'menu is visible with autoOpen on');
- el.multiselect("destroy");
+ el.multiselect("destroy");
+ });
- // no built in support for change on the fly; not testing it.
- });
+ test("uncheckAllText", function(){
+ expect(2);
+ var text = "foo";
- test("multiple (false - single select)", function(){
- expect(10);
+ el = $("select").multiselect({ uncheckAllText:text, showUncheckAll:true });
+ equals( text, menu().find(".ui-multiselect-none").text(), 'check all link reads '+text );
- $("select").removeAttr("multiple");
- el = $("select").multiselect({ multiple:false });
+ // set through option
+ text = "bar";
+ el.multiselect("option","uncheckAllText","bar");
+ equals( text, menu().find(".ui-multiselect-none").text(), 'changing value through api to '+text );
- // get some references
- var $menu = menu(), $header = header();
+ el.multiselect("destroy");
+ });
- ok( $header.find('a.ui-multiselect-all').is(':hidden'), 'select all link is hidden' );
- ok( $header.find('a.ui-multiselect-none').is(':hidden'), 'select none link is hidden' );
- ok( $header.find('a.ui-multiselect-close').css('display') !== 'hidden', 'close link is visible' );
- ok( !$menu.find(":checkbox").length, 'no checkboxes are present');
- ok( $menu.find(":radio").length > 0, 'but radio boxes are');
+ test("flipAllText", function(){
+ expect(2);
+ var text = "foo";
- // simulate click on ALL radios
- var radios = $menu.find(":radio").trigger("click");
+ el = $("select").multiselect({ flipAllText:text, showFlipAll:true });
+ equals( text, menu().find(".ui-multiselect-flip").text(), 'flip all link reads '+text );
- // at the end of that, only one radio should be checked and the menu closed
- equals( radios.filter(":checked").length, 1, 'After checking all radios, only one is actually checked');
- equals( false, el.multiselect('isOpen'), 'Menu is closed' );
+ // set through option
+ text = "bar";
+ el.multiselect("option","flipAllText","bar");
+ equals( text, menu().find(".ui-multiselect-flip").text(), 'changing value through api to '+text );
- // uncheck boxes... should only be one
- radios.filter(":checked").trigger("click");
+ el.multiselect("destroy");
+ });
+
+ test("autoOpen", function(){
+ expect(2);
- // method calls
- el.multiselect("checkAll");
- equals( $menu.find("input:radio:checked").length, 1, 'After checkAll method call only one is actually checked');
+ el = $("select").multiselect({ autoOpen:false });
- el.multiselect("uncheckAll");
- equals( $menu.find("input:radio:checked").length, 0, 'After uncheckAll method nothing is checked');
+ ok( menu().is(":hidden"), 'menu is hidden with autoOpen off');
+ el.multiselect("destroy");
- // check/uncheck all links
- equals( $menu.find(".ui-multiselect-all, ui-multiselect-none").filter(":visible").length, 0, "Check/uncheck all links don't exist");
+ el = $("select").multiselect({ autoOpen:true });
+ ok( menu().is(":visible"), 'menu is visible with autoOpen on');
+ el.multiselect("destroy");
- el.multiselect("destroy");
- $("select").attr("multiple","multiple");
- });
+ // no built in support for change on the fly; not testing it.
+ });
- test("multiple (changing dynamically)", function(){
- expect(6);
+ test("multiple (false - single select)", function(){
+ expect(10);
- el = $('foo ')
- .appendTo("body")
- .multiselect();
+ $("select").removeAttr("multiple");
+ el = $("select").multiselect({ multiple:false });
- el.multiselect("option", "multiple", false);
- equals(el[0].multiple, false, "When changing a multiple select to a single select, the select element no longer has the multiple property");
- equals(menu().hasClass("ui-multiselect-single"), true, "...and the menu now has the single select class");
- equals(menu().find('input[type="radio"]').length, 1, "...and the checkbox is now a radio button");
+ // get some references
+ var $menu = menu(), $header = header();
- el.multiselect("option", "multiple", true);
- equals(el[0].multiple, true, "When changing a single select to a multiple select, the select element has the multiple property");
- equals(menu().hasClass("ui-multiselect-single"), false, "...and the menu doesn't have the single select class");
- equals(menu().find('input[type="checkbox"]').length, 1, "...and the radio button is now a checkbox");
-
- el.multiselect("destroy").remove();
- });
+ ok( $header.find('a.ui-multiselect-all').is(':hidden'), 'select all link is hidden' );
+ ok( $header.find('a.ui-multiselect-none').is(':hidden'), 'select none link is hidden' );
+ ok( $header.find('a.ui-multiselect-close').css('display') !== 'hidden', 'close link is visible' );
+ ok( !$menu.find(":checkbox").length, 'no checkboxes are present');
+ ok( $menu.find(":radio").length > 0, 'but radio boxes are');
- test("classes", function(){
- expect(6);
+ // simulate click on ALL radios
+ var radios = $menu.find(":radio").trigger("click");
- var classname = 'foo';
-
- el = $("select").multiselect({ classes:classname });
- var $button = button(), $widget = menu();
+ // at the end of that, only one radio should be checked and the menu closed
+ equals( radios.filter(":checked").length, 1, 'After checking all radios, only one is actually checked');
+ equals( false, el.multiselect('isOpen'), 'Menu is closed' );
- equals( $widget.hasClass(classname), true, 'menu has the class ' + classname);
- equals( $button.hasClass(classname), true, 'button has the class ' + classname);
+ // uncheck boxes... should only be one
+ radios.filter(":checked").trigger("click");
- // change it up
- var newclass = 'bar';
- el.multiselect("option", "classes", newclass);
- equals( $widget.hasClass(newclass), true, 'menu has the new class ' + newclass);
- equals( $button.hasClass(newclass), true, 'button has the new class ' + newclass);
- equals( $button.hasClass(classname), false, 'menu no longer has the class ' + classname);
- equals( $button.hasClass(classname), false, 'button no longer has the class ' + classname);
- el.multiselect("destroy");
- });
-
- test("header", function(){
- expect(7);
-
- function countLinks(){
- return header().find("a").length;
- }
-
- // default
- el = $("select").multiselect({ autoOpen:true });
- ok(header().is(':visible'), "default config: header is visible" );
- el.multiselect("option", "header", false);
- ok(header().is(':hidden'), "after changing header option on default config: header is no longer visible" );
-
- // test for all links within the default header
- equals(countLinks(), 3, "number of links in the default header config");
-
- el.multiselect("destroy");
-
- // create again, this time header false
- el = $("select").multiselect({ header:false, autoOpen:true });
- ok(header().is(':hidden'), "init with header false: header is not visible" );
- el.multiselect("option", "header", true);
- ok(header().is(':visible'), "after changing header option: header is visible" );
-
- el.multiselect("destroy");
-
- // create again, this time custom header
- el = $("select").multiselect({ header:"hai guyz", autoOpen:true });
- equals(header().text(), "hai guyz", "header equals custom text");
- equals(countLinks(), 1, "number of links in the custom header config (should be close button)");
-
- el.multiselect("destroy");
- });
- test("openIcon", function(){
- expect(1);
- var icon = ' ';
- el = $("select").multiselect({ openIcon:icon });
- equals(button().find(".ui-multiselect-open").find(".ui-icon-search").length, 1);
- el.multiselect("destroy");
- });
- test("closeIcon", function(){
- expect(1);
- var icon = ' ';
- el = $("select").multiselect({ autoOpen:true, closeIcon:icon });
- equals(menu().find(".ui-multiselect-close").find(".ui-icon-search").length, 1);
- el.multiselect("destroy");
- });
+ // method calls
+ el.multiselect("checkAll");
+ equals( $menu.find("input:radio:checked").length, 1, 'After checkAll method call only one is actually checked');
+
+ el.multiselect("uncheckAll");
+ equals( $menu.find("input:radio:checked").length, 0, 'After uncheckAll method nothing is checked');
+
+ // check/uncheck all links
+ equals( $menu.find(".ui-multiselect-all, ui-multiselect-none").filter(":visible").length, 0, "Check/uncheck all links don't exist");
+
+ el.multiselect("destroy");
+ $("select").attr("multiple","multiple");
+ });
+
+ test("multiple (changing dynamically)", function(){
+ expect(6);
+
+ el = $('foo ')
+ .appendTo("body")
+ .multiselect();
+
+ el.multiselect("option", "multiple", false);
+ equals(el[0].multiple, false, "When changing a multiple select to a single select, the select element no longer has the multiple property");
+ equals(menu().hasClass("ui-multiselect-single"), true, "...and the menu now has the single select class");
+ equals(menu().find('input[type="radio"]').length, 1, "...and the checkbox is now a radio button");
+
+ el.multiselect("option", "multiple", true);
+ equals(el[0].multiple, true, "When changing a single select to a multiple select, the select element has the multiple property");
+ equals(menu().hasClass("ui-multiselect-single"), false, "...and the menu doesn't have the single select class");
+ equals(menu().find('input[type="checkbox"]').length, 1, "...and the radio button is now a checkbox");
+
+ el.multiselect("destroy").remove();
+ });
+
+ test("classes", function(){
+ expect(6);
+
+ var classname = 'foo';
+
+ el = $("select").multiselect({ classes:classname });
+ var $button = button(), $widget = menu();
+
+ equals( $widget.hasClass(classname), true, 'menu has the class ' + classname);
+ equals( $button.hasClass(classname), true, 'button has the class ' + classname);
+
+ // change it up
+ var newclass = 'bar';
+ el.multiselect("option", "classes", newclass);
+ equals( $widget.hasClass(newclass), true, 'menu has the new class ' + newclass);
+ equals( $button.hasClass(newclass), true, 'button has the new class ' + newclass);
+ equals( $button.hasClass(classname), false, 'menu no longer has the class ' + classname);
+ equals( $button.hasClass(classname), false, 'button no longer has the class ' + classname);
+ el.multiselect("destroy");
+ });
+
+ test("header", function(){
+ expect(7);
+
+ function countLinks(){
+ return header().find("a").length;
+ }
+
+ // default
+ el = $("select").multiselect({ autoOpen:true });
+ ok(header().is(':visible'), "default config: header is visible" );
+ el.multiselect("option", "header", false);
+ ok(header().is(':hidden'), "after changing header option on default config: header is no longer visible" );
+
+ // test for all links within the default header
+ equals(countLinks(), 3, "number of links in the default header config");
+
+ el.multiselect("destroy");
+
+ // create again, this time header false
+ el = $("select").multiselect({ header:false, autoOpen:true });
+ ok(header().is(':hidden'), "init with header false: header is not visible" );
+ el.multiselect("option", "header", true);
+ ok(header().is(':visible'), "after changing header option: header is visible" );
+
+ el.multiselect("destroy");
+
+ // create again, this time custom header
+ el = $("select").multiselect({ header:"hai guyz", autoOpen:true });
+ equals(header().text(), "hai guyz", "header equals custom text");
+ equals(countLinks(), 1, "number of links in the custom header config (should be close button)");
+
+ el.multiselect("destroy");
+ });
+ test("openIcon", function(){
+ expect(1);
+ var icon = ' ';
+ el = $("select").multiselect({ openIcon:icon });
+ equals(button().find(".ui-multiselect-open").find(".ui-icon-search").length, 1);
+ el.multiselect("destroy");
+ });
+ test("closeIcon", function(){
+ expect(1);
+ var icon = ' ';
+ el = $("select").multiselect({ autoOpen:true, closeIcon:icon });
+ equals(menu().find(".ui-multiselect-close").find(".ui-icon-search").length, 1);
+ el.multiselect("destroy");
+ });
test("selectedListSeparator", function(){
expect(3);
el = $("select").multiselect({ selectedListSeparator: " ", selectedList: 15 });
From 4712685366d1df303aaed3c9aea8555a6d530c88 Mon Sep 17 00:00:00 2001
From: Steve James <4stevejames@gmail.com>
Date: Sat, 13 Jan 2018 19:28:33 -0800
Subject: [PATCH 12/12] Fixed updated test.
---
tests/unit/options.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tests/unit/options.js b/tests/unit/options.js
index b430c94..f751ccb 100644
--- a/tests/unit/options.js
+++ b/tests/unit/options.js
@@ -92,8 +92,12 @@
selectedMax: 2
});
- el.multiselect("checkAll");
- equals( menu().find("input").filter(":checked").length, 2 , 'after checkAll, count of checked restored to selectedMax of 2');
+ checkboxes = el.multiselect("widget").find(":checkbox");
+ checkboxes.eq(0).trigger('click');
+ checkboxes.eq(1).trigger('click');
+ checkboxes.eq(2).trigger('click');
+
+ equals( menu().find("input").filter(":checked").length, 2 , 'after clicking each checkbox, count of checked restored to selectedMax of 2');
el.multiselect("destroy").remove();
});