Commit 8ed8c4d0 authored by David Stutz's avatar David Stutz

Updated tests and fixed select all + clickable + collapsible issues.

parent 3a5c6069
...@@ -193,6 +193,7 @@ ...@@ -193,6 +193,7 @@
this.options.multiple = this.$select.attr('multiple') === "multiple"; this.options.multiple = this.$select.attr('multiple') === "multiple";
this.options.onChange = $.proxy(this.options.onChange, this); this.options.onChange = $.proxy(this.options.onChange, this);
this.options.onSelectAll = $.proxy(this.options.onSelectAll, this); this.options.onSelectAll = $.proxy(this.options.onSelectAll, this);
this.options.onDeselectAll = $.proxy(this.options.onDeselectAll, this);
this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this); this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this); this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this); this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this);
...@@ -356,7 +357,13 @@ ...@@ -356,7 +357,13 @@
/** /**
* Triggered on select all. * Triggered on select all.
*/ */
onSelectAll: function(checked) { onSelectAll: function() {
},
/**
* Triggered on deselect all.
*/
onDeselectAll: function() {
}, },
/** /**
...@@ -565,6 +572,7 @@ ...@@ -565,6 +572,7 @@
var $checkboxesNotThis = $('input', this.$container).not($target); var $checkboxesNotThis = $('input', this.$container).not($target);
if (isSelectAllOption) { if (isSelectAllOption) {
if (checked) { if (checked) {
this.selectAll(this.options.selectAllJustVisible); this.selectAll(this.options.selectAllJustVisible);
} }
...@@ -604,16 +612,17 @@ ...@@ -604,16 +612,17 @@
// To prevent select all from firing onChange: #575 // To prevent select all from firing onChange: #575
this.options.onChange($option, checked); this.options.onChange($option, checked);
// Do not update select all or optgroups on select all change!
this.updateSelectAll();
if (this.options.enableClickableOptGroups && this.options.multiple) {
this.updateOptGroups();
}
} }
this.$select.change(); this.$select.change();
this.updateButtonText(); this.updateButtonText();
this.updateSelectAll();
if (this.options.enableClickableOptGroups && this.options.multiple) {
this.updateOptGroup($target, checked);
}
if(this.options.preventInputChangeEvent) { if(this.options.preventInputChangeEvent) {
return false; return false;
...@@ -737,7 +746,10 @@ ...@@ -737,7 +746,10 @@
var checked = $target.prop('checked') || false; var checked = $target.prop('checked') || false;
var $li = $(event.target).closest('li'); var $li = $(event.target).closest('li');
var $group = $li.nextUntil("li.multiselect-group").filter(":visible:not(.disabled)"); var $group = $li.nextUntil("li.multiselect-group")
.not('.multiselect-filter-hidden')
.not('.disabled');
var $inputs = $group.find("input"); var $inputs = $group.find("input");
var values = []; var values = [];
...@@ -774,18 +786,25 @@ ...@@ -774,18 +786,25 @@
}, this)); }, this));
} }
if (this.options.enableCollapsibleOptGroups && this.options.multiple) { if (this.options.enableCollapsibleOptGroups && this.options.multiple) {
//$("li.multiselect-group input", this.$ul).off();
$("li.multiselect-group", this.$ul).siblings().not("li.multiselect-group, li.multiselect-all", this.$ul).each(function () {
$(this).toggleClass('multiselect-collapsible-hidden', true);
});
$("li.multiselect-group .caret-container", this.$ul).on("click", $.proxy(function(event) { $("li.multiselect-group .caret-container", this.$ul).on("click", $.proxy(function(event) {
event.stopPropagation();
var $li = $(event.target).closest('li'); var $li = $(event.target).closest('li');
var $inputs = $li.nextUntil("li.multiselect-group"); var $inputs = $li.nextUntil("li.multiselect-group")
.not('.multiselect-filter-hidden');
$inputs.toggleClass('multiselect-collapsible-hidden'); var visible = true;
$inputs.each(function() {
visible = visible && $(this).is(':visible');
});
if (visible) {
$inputs.hide()
.addClass('multiselect-collapsible-hidden');
}
else {
$inputs.show()
.removeClass('multiselect-collapsible-hidden');
}
}, this)); }, this));
$("li.multiselect-all", this.$ul).css('background', '#f3f3f3').css('border-bottom', '1px solid #eaeaea'); $("li.multiselect-all", this.$ul).css('background', '#f3f3f3').css('border-bottom', '1px solid #eaeaea');
...@@ -974,7 +993,7 @@ ...@@ -974,7 +993,7 @@
$('input', this.$filter).attr('placeholder', this.options.filterPlaceholder); $('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
// Adds optional filter clear button // Adds optional filter clear button
if(this.options.includeFilterClearBtn){ if(this.options.includeFilterClearBtn) {
var clearBtn = $(this.options.templates.filterClearBtn); var clearBtn = $(this.options.templates.filterClearBtn);
clearBtn.on('click', $.proxy(function(event){ clearBtn.on('click', $.proxy(function(event){
clearTimeout(this.searchTimeout); clearTimeout(this.searchTimeout);
...@@ -1048,7 +1067,8 @@ ...@@ -1048,7 +1067,8 @@
} }
// Toggle current element (group or group item) according to showElement boolean. // Toggle current element (group or group item) according to showElement boolean.
$(element).toggle(showElement).toggleClass('multiselect-filter-hidden', !showElement); $(element).toggle(showElement)
.toggleClass('multiselect-filter-hidden', !showElement);
// Differentiate groups and group items. // Differentiate groups and group items.
if ($(element).hasClass('multiselect-group')) { if ($(element).hasClass('multiselect-group')) {
...@@ -1059,12 +1079,14 @@ ...@@ -1059,12 +1079,14 @@
else { else {
// Show group name when at least one of its items is visible. // Show group name when at least one of its items is visible.
if (showElement) { if (showElement) {
$(currentGroup).show().removeClass('multiselect-filter-hidden'); $(currentGroup).show()
.removeClass('multiselect-filter-hidden');
} }
// Show all group items when group name satisfies filter. // Show all group items when group name satisfies filter.
if (!showElement && currentGroupVisible) { if (!showElement && currentGroupVisible) {
$(element).show().removeClass('multiselect-filter-hidden'); $(element).show()
.removeClass('multiselect-filter-hidden');
} }
} }
} }
...@@ -1269,34 +1291,36 @@ ...@@ -1269,34 +1291,36 @@
* @param {Boolean} triggerOnSelectAll * @param {Boolean} triggerOnSelectAll
*/ */
selectAll: function (justVisible, triggerOnSelectAll) { selectAll: function (justVisible, triggerOnSelectAll) {
justVisible = (this.options.enableCollapsibleOptGroups && this.options.multiple) ? false : justVisible;
var justVisible = typeof justVisible === 'undefined' ? true : justVisible; var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul); var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul);
var visibleCheckboxes = allCheckboxes.filter(":visible"); var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible');
var allCheckboxesCount = allCheckboxes.length;
var visibleCheckboxesCount = visibleCheckboxes.length;
if(justVisible) { if(justVisible) {
visibleCheckboxes.prop('checked', true); $('input:enabled' , visibleLis).prop('checked', true);
$("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul).filter(":visible").addClass(this.options.selectedClass); visibleLis.addClass(this.options.selectedClass);
}
else {
allCheckboxes.prop('checked', true);
$("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul).addClass(this.options.selectedClass);
}
if (allCheckboxesCount === visibleCheckboxesCount || justVisible === false) { $('input:enabled' , visibleLis).each($.proxy(function(index, element) {
$("option:not([data-role='divider']):enabled", this.$select).prop('selected', true); var value = $(element).val();
var option = this.getOptionByValue(value);
$(option).prop('selected', true);
}, this));
} }
else { else {
var values = visibleCheckboxes.map(function() { $('input:enabled' , allLis).prop('checked', true);
return $(this).val(); allLis.addClass(this.options.selectedClass);
}).get();
$("option:enabled", this.$select).filter(function(index) { $('input:enabled' , allLis).each($.proxy(function(index, element) {
return $.inArray($(this).val(), values) !== -1; var value = $(element).val();
}).prop('selected', true); var option = this.getOptionByValue(value);
$(option).prop('selected', true);
}, this));
}
$('li input[value="' + this.options.selectAllValue + '"]').prop('checked', true);
if (this.options.enableClickableOptGroups && this.options.multiple) {
this.updateOptGroups();
} }
if (triggerOnSelectAll) { if (triggerOnSelectAll) {
...@@ -1311,33 +1335,41 @@ ...@@ -1311,33 +1335,41 @@
* *
* @param {Boolean} justVisible * @param {Boolean} justVisible
*/ */
deselectAll: function (justVisible) { deselectAll: function (justVisible, triggerOnDeselectAll) {
justVisible = (this.options.enableCollapsibleOptGroups && this.options.multiple) ? false : justVisible;
justVisible = typeof justVisible === 'undefined' ? true : justVisible;
if(justVisible) { var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
var visibleCheckboxes = $("li input[type='checkbox']:not(:disabled)", this.$ul).filter(":visible"); var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul);
visibleCheckboxes.prop('checked', false); var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible');
var values = visibleCheckboxes.map(function() { if(justVisible) {
return $(this).val(); $('input[type="checkbox"]:enabled' , visibleLis).prop('checked', false);
}).get(); visibleLis.removeClass(this.options.selectedClass);
$("option:enabled", this.$select).filter(function(index) {
return $.inArray($(this).val(), values) !== -1;
}).prop('selected', false);
if (this.options.selectedClass) { $('input[type="checkbox"]:enabled' , visibleLis).each($.proxy(function(index, element) {
$("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").removeClass(this.options.selectedClass); var value = $(element).val();
} var option = this.getOptionByValue(value);
$(option).prop('selected', false);
}, this));
} }
else { else {
$("li input[type='checkbox']:enabled", this.$ul).prop('checked', false); $('input[type="checkbox"]:enabled' , allLis).prop('checked', false);
$("option:enabled", this.$select).prop('selected', false); allLis.removeClass(this.options.selectedClass);
if (this.options.selectedClass) { $('input[type="checkbox"]:enabled' , allLis).each($.proxy(function(index, element) {
$("li:not(.divider):not(.disabled)", this.$ul).removeClass(this.options.selectedClass); var value = $(element).val();
} var option = this.getOptionByValue(value);
$(option).prop('selected', false);
}, this));
}
$('li input[value="' + this.options.selectAllValue + '"]').prop('checked', false);
if (this.options.enableClickableOptGroups && this.options.multiple) {
this.updateOptGroups();
}
if (triggerOnDeselectAll) {
this.options.onDeselectAll();
} }
}, },
...@@ -1483,36 +1515,6 @@ ...@@ -1483,36 +1515,6 @@
return $('li.multiselect-all', this.$ul).length > 0; return $('li.multiselect-all', this.$ul).length > 0;
}, },
/**
* Update a particular opt group.
*/
updateOptGroup: function($element, checked) {
var $prevs = $element.closest('li').prevUntil('li.multiselect-group').filter(":visible:not(.disabled)");
var $nexts = $element.closest('li').nextUntil('li.multiselect-group').filter(":visible:not(.disabled)");
var selected = checked;
$prevs.each(function() {
if (!$('input', this).prop('checked')) {
selected = false;
}
});
$nexts.each(function() {
if (!$('input', this).prop('checked')) {
selected = false;
}
});
var $group = $element.closest('li').prevAll('li.multiselect-group')[0];
if (selected) {
$('input', $group).prop('checked', true);
}
else {
$('input', $group).prop('checked', false);
}
},
/** /**
* Update opt groups. * Update opt groups.
*/ */
...@@ -1520,8 +1522,10 @@ ...@@ -1520,8 +1522,10 @@
var $groups = $('li.multiselect-group', this.$ul) var $groups = $('li.multiselect-group', this.$ul)
$groups.each(function() { $groups.each(function() {
var $options = $(this).nextUntil('li.multiselect-group').filter(":not(.disabled)"); var $options = $(this).nextUntil('li.multiselect-group')
.not('.multiselect-filter-hidden')
.not('.disabled');
var checked = true; var checked = true;
$options.each(function() { $options.each(function() {
var $input = $('input', this); var $input = $('input', this);
...@@ -1540,7 +1544,7 @@ ...@@ -1540,7 +1544,7 @@
*/ */
updateSelectAll: function(notTriggerOnSelectAll) { updateSelectAll: function(notTriggerOnSelectAll) {
if (this.hasSelectAll()) { if (this.hasSelectAll()) {
var allBoxes = $("li:not(.multiselect-item):not(.multiselect-filter-hidden) input:enabled", this.$ul); var allBoxes = $("li:not(.multiselect-item):not(.multiselect-filter-hidden):not(.multiselect-group):not(.disabled) input:enabled", this.$ul);
var allBoxesLength = allBoxes.length; var allBoxesLength = allBoxes.length;
var checkedBoxesLength = allBoxes.filter(":checked").length; var checkedBoxesLength = allBoxes.filter(":checked").length;
var selectAllLi = $("li.multiselect-all", this.$ul); var selectAllLi = $("li.multiselect-all", this.$ul);
......
...@@ -2322,6 +2322,39 @@ ...@@ -2322,6 +2322,39 @@
}); });
}); });
</script> </script>
</pre>
</div>
<p>
The select all element naturally respects disabled elements:
</p>
<div class="example">
<script type="text/javascript">
$(document).ready(function() {
$('#example-includeSelectAllOption-disbled').multiselect({
includeSelectAllOption: true
});
});
</script>
<select id="example-includeSelectAllOption-disbled" multiple="multiple">
<option value="1" disabled="disabled">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
<option value="4">Option 4</option>
<option value="5">Option 5</option>
<option value="6">Option 6</option>
</select>
</div>
<div class="highlight">
<pre class="prettyprint linenums">
&lt;script type="text/javascript"&gt;
$(document).ready(function() {
$('#example-includeSelectAllOption-disbled').multiselect({
includeSelectAllOption: true
});
});
&lt;/script&gt;
</pre> </pre>
</div> </div>
</td> </td>
......
...@@ -516,14 +516,16 @@ describe('Bootstrap Multiselect "Collapsible Optgroups"', function() { ...@@ -516,14 +516,16 @@ describe('Bootstrap Multiselect "Collapsible Optgroups"', function() {
var $lis = $group.nextUntil('li.multiselect-group'); var $lis = $group.nextUntil('li.multiselect-group');
$lis.each(function() { $lis.each(function() {
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(false); expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(true);
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe($(this).is(':hidden'));
}); });
$('.caret-container', $group).click(); $('.caret-container', $group).click();
var $lis = $group.nextUntil('li.multiselect-group'); var $lis = $group.nextUntil('li.multiselect-group');
$lis.each(function() { $lis.each(function() {
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(true); expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(false);
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe($(this).is(':hidden'));
}); });
}); });
...@@ -616,14 +618,16 @@ describe('Bootstrap Multiselect "Clickable+Collapsible Optgroups"', function() { ...@@ -616,14 +618,16 @@ describe('Bootstrap Multiselect "Clickable+Collapsible Optgroups"', function() {
var $lis = $group.nextUntil('li.multiselect-group'); var $lis = $group.nextUntil('li.multiselect-group');
$lis.each(function() { $lis.each(function() {
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(false); expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(true);
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe($(this).is(':hidden'));
}); });
$('.caret-container', $group).click(); $('.caret-container', $group).click();
var $lis = $group.nextUntil('li.multiselect-group'); var $lis = $group.nextUntil('li.multiselect-group');
$lis.each(function() { $lis.each(function() {
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(true); expect($(this).hasClass('multiselect-collapsible-hidden')).toBe(false);
expect($(this).hasClass('multiselect-collapsible-hidden')).toBe($(this).is(':hidden'));
}); });
}); });
...@@ -664,7 +668,6 @@ describe('Bootstrap Multiselect "Clickable+Collapsible+SelectAll Optgroups"', fu ...@@ -664,7 +668,6 @@ describe('Bootstrap Multiselect "Clickable+Collapsible+SelectAll Optgroups"', fu
it('Should handle option groups differently, i.e. not set class to active.', function() { it('Should handle option groups differently, i.e. not set class to active.', function() {
// Otherwise they are hidden. // Otherwise they are hidden.
$('#multiselect-container li.multiselect-group .caret-container').click();
$('#multiselect-container input[value="multiselect-all"]').click(); $('#multiselect-container input[value="multiselect-all"]').click();
var $groups = $('#multiselect-container li.multiselect-group'); var $groups = $('#multiselect-container li.multiselect-group');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment