diff --git a/dist/css/bootstrap-multiselect.css b/dist/css/bootstrap-multiselect.css index 6a6b68a2..6283cb97 100644 --- a/dist/css/bootstrap-multiselect.css +++ b/dist/css/bootstrap-multiselect.css @@ -1 +1 @@ -span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container .multiselect-reset .input-group{width:93%}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.checkbox,.multiselect-container>li>a>label.radio{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container label.checkbox,.form-inline .multiselect-container label.radio{padding:3px 20px 3px 40px}.form-inline .multiselect-container li a label.checkbox input[type=checkbox],.form-inline .multiselect-container li a label.radio input[type=radio]{margin-left:-20px;margin-right:0} \ No newline at end of file +span.multiselect-native-select{position:relative}span.multiselect-native-select select{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px -1px -1px -3px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;left:50%;top:30px}.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container .multiselect-reset .input-group{width:93%}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li.multiselect-group label{margin:0;width:100%;height:100%;font-weight:700}.multiselect-container>li.multiselect-group-clickable label{cursor:pointer}.multiselect-container>li>div>label{margin:0;width:100%;height:100%;cursor:pointer;font-weight:400}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.form-inline .multiselect-container li a label.checkbox input[type="checkbox"],.form-inline .multiselect-container li a label.radio input[type="radio"]{margin-left:-20px;margin-right:0}.multiselect-filter{padding-right:1rem} .optgroup-container{display:inline-flex;} \ No newline at end of file diff --git a/dist/js/bootstrap-multiselect.js b/dist/js/bootstrap-multiselect.js index 2a028b77..f38a6b4e 100644 --- a/dist/js/bootstrap-multiselect.js +++ b/dist/js/bootstrap-multiselect.js @@ -250,8 +250,7 @@ */ buttonText: function(options, select) { if (this.disabledText.length > 0 - && (select.prop('disabled') || (options.length == 0 && this.disableIfEmpty))) { - + && (select.prop('disabled') || (select.children().length === 0 && this.disableIfEmpty))) { return this.disabledText; } else if (options.length === 0) { @@ -269,7 +268,7 @@ return this.allSelectedText; } } - else if (this.numberDisplayed != 0 && options.length > this.numberDisplayed) { + else if (this.numberDisplayed != -1 && options.length > this.numberDisplayed) { return options.length + ' ' + this.nSelectedText; } else { @@ -400,10 +399,10 @@ }, enableHTML: false, - buttonClass: 'btn btn-default', + buttonClass: 'btn btn-secondary', inheritClass: false, buttonWidth: 'auto', - buttonContainer: '
', + buttonContainer: '
', dropRight: false, dropUp: false, selectedClass: 'active', @@ -439,14 +438,14 @@ includeResetDivider: false, resetText: 'Reset', templates: { - button: '', + button: '', ul: '', - filter: '
  • ', - filterClearBtn: '', - li: '
  • ', - divider: '
  • ', - liGroup: '
  • ', - resetButton: '
  • ' + filter: '
  • ', + filterClearBtn: '
    ', + li: '', + divider: '', + liGroup: '', + resetButton: '
  • ' } }, @@ -509,7 +508,7 @@ this.$ul = $(this.options.templates.ul); if (this.options.dropRight) { - this.$ul.addClass('pull-right'); + this.$ul.addClass('float-right'); } // Set max height of dropdown menu to activate auto scrollbar. @@ -535,6 +534,13 @@ }); } + if (this.options.multiple) { + // Prevent the dropdown from closing after each click + this.$ul.on("click", function(e) { + e.stopPropagation(); + }); + } + this.$container.append(this.$ul); }, @@ -625,9 +631,6 @@ $($checkboxesNotThis).prop('checked', false); $optionsNotThis.prop('selected', false); - - // It's a single selection, so close. - this.$button.click(); } if (this.options.selectedClass === "active") { @@ -739,7 +742,7 @@ } var index = $items.index($items.filter(':focus')); - + // Navigation up. if (event.keyCode === 38 && index > 0) { index--; @@ -826,7 +829,7 @@ } if (this.options.enableCollapsibleOptGroups && this.options.multiple) { - $("li.multiselect-group .caret-container", this.$ul).on("click", $.proxy(function(event) { + $("li.multiselect-group .optgroup-container", this.$ul).on("click", $.proxy(function(event) { var $li = $(event.target).closest('li'); var $inputs = $li.nextUntil("li.multiselect-group") .not('.multiselect-filter-hidden'); @@ -837,11 +840,11 @@ }); if (visible) { - $inputs.hide() + $inputs.attr('hidden', true) .addClass('multiselect-collapsible-hidden'); } else { - $inputs.show() + $inputs.removeAttr('hidden') .removeClass('multiselect-collapsible-hidden'); } }, this)); @@ -869,16 +872,26 @@ var value = $element.val(); var inputType = this.options.multiple ? "checkbox" : "radio"; + // Generate a random number between 0 and MAX_SAFE_INTEGER to use as a highly unique ID + var randomNum = Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER)); + + // This element ID is required for the label and checkbox so that Bootstrap 4 will select the option when the label is clicked + // Ex: "bootstrap-multiselect-option-7-2193414947069541" + var optionComponentId = "bootstrap-multiselect-option-" + value + "-" + randomNum; + var $li = $(this.options.templates.li); var $label = $('label', $li); + var $div = $('div', $li); $label.addClass(inputType); + $label.addClass("form-check-label"); $label.attr("title", label); + $label.attr("for", optionComponentId); $li.addClass(classes); // Hide all children items when collapseOptGroupsByDefault is true if (this.options.collapseOptGroupsByDefault && $(element).parent().prop("tagName").toLowerCase() === "optgroup") { $li.addClass("multiselect-collapsible-hidden"); - $li.hide(); + $li.attr('hidden', true); } if (this.options.enableHTML) { @@ -890,19 +903,22 @@ var $checkbox = $('').attr('type', inputType); + $checkbox.attr('id', optionComponentId); + $checkbox.addClass('form-check-input'); + var name = this.options.checkboxName($element); if (name) { $checkbox.attr('name', name); } - $label.prepend($checkbox); + $div.prepend($checkbox); var selected = $element.prop('selected') || false; $checkbox.val(value); if (value === this.options.selectAllValue) { $li.addClass("multiselect-item multiselect-all"); - $checkbox.parent().parent() + $checkbox.parent().parent().parent() .addClass('multiselect-all'); } @@ -945,7 +961,7 @@ createOptgroup: function(group) { var label = $(group).attr("label"); var value = $(group).attr("value"); - var $li = $('
  • '); + var $li = $('
  • '); var classes = this.options.optionClass(group); $li.addClass(classes); @@ -958,11 +974,11 @@ } if (this.options.enableCollapsibleOptGroups && this.options.multiple) { - $('a', $li).append(''); + $('.optgroup-container', $li).append(''); } if (this.options.enableClickableOptGroups && this.options.multiple) { - $('a label', $li).prepend(''); + $('.optgroup-container label', $li).prepend(''); } if ($(group).is(':disabled')) { @@ -991,13 +1007,13 @@ var $resetButton = $(this.options.templates.resetButton); if (this.options.enableHTML) { - $('a', $resetButton).html(this.options.resetText); + $('button', $resetButton).html(this.options.resetText); } else { - $('a', $resetButton).text(this.options.resetText); + $('button', $resetButton).text(this.options.resetText); } - $('a', $resetButton).click($.proxy(function(){ + $('button', $resetButton).click($.proxy(function(){ this.clearSelection(); }, this)); @@ -1046,7 +1062,7 @@ $checkbox.val(this.options.selectAllValue); $li.addClass("multiselect-item multiselect-all"); - $checkbox.parent().parent() + $checkbox.parent().parent().parent() .addClass('multiselect-all'); this.$ul.prepend($li); @@ -1077,7 +1093,7 @@ this.query = ''; this.$filter.find('.multiselect-search').val(''); - $('li', this.$ul).show().removeClass('multiselect-filter-hidden'); + $('li', this.$ul).removeAttr('hidden').removeClass('multiselect-filter-hidden'); this.updateSelectAll(); @@ -1146,11 +1162,11 @@ // Toggle current element (group or group item) according to showElement boolean. if(!showElement){ - $(element).css('display', 'none'); + $(element).attr('hidden', true); $(element).addClass('multiselect-filter-hidden'); } if(showElement){ - $(element).css('display', 'block'); + $(element).removeAttr('hidden'); $(element).removeClass('multiselect-filter-hidden'); } @@ -1163,13 +1179,13 @@ else { // Show group name when at least one of its items is visible. if (showElement) { - $(currentGroup).show() + $(currentGroup).removeAttr('hidden') .removeClass('multiselect-filter-hidden'); } // Show all group items when group name satisfies filter. if (!showElement && currentGroupVisible) { - $(element).show() + $(element).removeAttr('hidden') .removeClass('multiselect-filter-hidden'); } } @@ -1196,7 +1212,7 @@ */ destroy: function() { this.$container.remove(); - this.$select.show(); + this.$select.removeAttr('hidden'); // reset original state this.$select.prop('disabled', this.options.wasDisabled); @@ -1382,7 +1398,7 @@ var justVisible = typeof justVisible === 'undefined' ? true : justVisible; var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul); - var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible'); + var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapsible-hidden)", this.$ul).filter(':visible'); if(justVisible) { $('input:enabled' , visibleLis).prop('checked', true); @@ -1427,7 +1443,7 @@ var justVisible = typeof justVisible === 'undefined' ? true : justVisible; var allLis = $("li:not(.divider):not(.disabled):not(.multiselect-group)", this.$ul); - var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapisble-hidden)", this.$ul).filter(':visible'); + var visibleLis = $("li:not(.divider):not(.disabled):not(.multiselect-group):not(.multiselect-filter-hidden):not(.multiselect-collapsible-hidden)", this.$ul).filter(':visible'); if(justVisible) { $('input[type="checkbox"]:enabled' , visibleLis).prop('checked', false); diff --git a/dist/less/bootstrap-multiselect.less b/dist/less/bootstrap-multiselect.less index deec16fe..89a77610 100644 --- a/dist/less/bootstrap-multiselect.less +++ b/dist/less/bootstrap-multiselect.less @@ -75,15 +75,13 @@ span.multiselect-native-select select{ } > li { - padding: 0; - > a.multiselect-all label { font-weight: bold; } &.multiselect-group label { margin: 0; - padding: 3px 20px 3px 20px; + width: 100%; height: 100%; font-weight: bold; } @@ -92,23 +90,13 @@ span.multiselect-native-select select{ cursor: pointer; } - > a { - padding: 0; - + > div { > label { margin: 0; + width: 100%; height: 100%; cursor: pointer; font-weight: normal; - padding: 3px 20px 3px 40px; - - &.radio, &.checkbox { - margin: 0; - } - - > input[type="checkbox"] { - margin-bottom:5px; - } } } } @@ -120,11 +108,6 @@ span.multiselect-native-select select{ } .form-inline .multiselect-container{ - - label.checkbox, label.radio{ - padding: 3px 20px 3px 40px; - } - li a label{ &.checkbox input[type="checkbox"], &.radio input[type="radio"]{ @@ -133,3 +116,7 @@ span.multiselect-native-select select{ } } } + +.multiselect-filter { + padding-right: 1rem; +} \ No newline at end of file diff --git a/index.html b/index.html index fa4385fc..aea5e686 100644 --- a/index.html +++ b/index.html @@ -861,7 +861,7 @@

    Configuration Options

    This option will collapse all optgroups by default.

    There is also an example in the Further Examples section demonstrating an alternative way of collapsing optgroups by default.

    - +