Commit c1c3e173 authored by Tyf0x's avatar Tyf0x

** Huge performance and usability improvements on SHIFT + click multi-selection **

-> Now able to select/deselect ranges
-> The range is based on the previously active checkbox. (i.e: the user clicks a checkbox no 1 then checkbox no 5. The interval will be [1,5].)
-> The range new state (selected or deselected) depends on the last option clicked new value. Example: If the checkbox is Shift-clicked and becomes selected, the whole range will be too.
-> Improved the range select speed tremendously by only notifying the select for the "change" event once the whole range finished changing and manually doing the selection or deselection.
parent a5c1ab46
......@@ -99,6 +99,7 @@
this.originalOptions = this.$select.clone()[0].options;
this.query = '';
this.searchTimeout = null;
this.lastToggledInput = null
this.options.multiple = this.$select.attr('multiple') === "multiple";
this.options.onChange = $.proxy(this.options.onChange, this);
......@@ -458,48 +459,62 @@
}
});
$('li a', this.$ul).on('touchstart click', function(event) {
$('li a', this.$ul).on('touchstart click', $.proxy(function(event) {
event.stopPropagation();
var $target = $(event.target);
if (event.shiftKey) {
if (event.shiftKey && this.options.multiple) {
if($target.is("label")){ // Handles checkbox selection manually (see https://github.com/davidstutz/bootstrap-multiselect/issues/431)
event.preventDefault();
$target = $(this).find("input");
$target.prop("checked", !$target.prop("checked")).trigger("change");
$target = $target.find("input");
$target.prop("checked", !$target.prop("checked"));
}
var checked = $target.prop('checked') || false;
if (checked) {
var prev = $target.closest('li')
.siblings('li[class="active"]:first');
var currentIdx = $target.closest('li')
.index();
var prevIdx = prev.index();
if (this.lastToggledInput !== null && this.lastToggledInput !== $target) { // Make sure we actually have a range
var from = $target.closest("li").index();
var to = this.lastToggledInput.closest("li").index();
if (currentIdx > prevIdx) {
$target.closest("li").prevUntil(prev).each(
function() {
$(this).find("input:first").prop("checked", true)
.trigger("change");
if (from > to) { // Swap the indices
var tmp = to;
to = from;
from = tmp;
}
);
// Make sure we grab all elements since slice excludes the last index
++to;
// Change the checkboxes and underlying options
var range = this.$ul.find("li").slice(from, to).find("input");
range.prop('checked', checked);
if (this.options.selectedClass) {
range.closest('li')
.toggleClass(this.options.selectedClass, checked);
}
else {
$target.closest("li").nextUntil(prev).each(
function() {
$(this).find("input:first").prop("checked", true)
.trigger("change");
for (var i = 0, j = range.length; i < j; i++) {
var $checkbox = $(range[i]);
var $option = this.getOptionByValue($checkbox.val());
$option.prop('selected', checked);
}
);
}
// Trigger the select "change" event
$target.trigger("change");
}
// Remembers last clicked option
if($target.is("input") && !$target.closest("li").is(".multiselect-item")){
this.lastToggledInput = $target;
}
$target.blur();
});
}, this));
// Keyboard support.
this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
......
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