diff --git a/opengrok-indexer/src/main/java/org/opengrok/indexer/web/Scripts.java b/opengrok-indexer/src/main/java/org/opengrok/indexer/web/Scripts.java index 0e5f6af6c69..43a5883c6b9 100644 --- a/opengrok-indexer/src/main/java/org/opengrok/indexer/web/Scripts.java +++ b/opengrok-indexer/src/main/java/org/opengrok/indexer/web/Scripts.java @@ -19,7 +19,7 @@ /* * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved. - * Portions Copyright (c) 2017, Chris Fraire . + * Portions Copyright (c) 2017, 2020, Chris Fraire . */ package org.opengrok.indexer.web; @@ -111,7 +111,7 @@ public String toHtml() { SCRIPTS.put("jquery-tablesorter", new FileScript("js/jquery-tablesorter-2.26.6.min.js", 12)); SCRIPTS.put("tablesorter-parsers", new FileScript("js/tablesorter-parsers-0.0.2.min.js", 13)); SCRIPTS.put("tablesorter-parsers" + DEBUG_SUFFIX, new FileScript("js/tablesorter-parsers-0.0.2.js", 13)); - SCRIPTS.put("searchable-option-list", new FileScript("js/searchable-option-list-2.0.8.min.js", 14)); + SCRIPTS.put("searchable-option-list", new FileScript("js/searchable-option-list-2.0.9.min.js", 14)); SCRIPTS.put("utils", new FileScript("js/utils-0.0.34.min.js", 15)); SCRIPTS.put("utils" + DEBUG_SUFFIX, new FileScript("js/utils-0.0.34.js", 15)); SCRIPTS.put("repos", new FileScript("js/repos-0.0.2.min.js", 20)); diff --git a/opengrok-web/src/main/webapp/js/searchable-option-list-2.0.8.js b/opengrok-web/src/main/webapp/js/searchable-option-list-2.0.9.js similarity index 94% rename from opengrok-web/src/main/webapp/js/searchable-option-list-2.0.8.js rename to opengrok-web/src/main/webapp/js/searchable-option-list-2.0.9.js index 05261b91f66..3575d76adbc 100644 --- a/opengrok-web/src/main/webapp/js/searchable-option-list-2.0.8.js +++ b/opengrok-web/src/main/webapp/js/searchable-option-list-2.0.9.js @@ -4,6 +4,7 @@ * https://pbauerochse.github.io/searchable-option-list/ * * Copyright 2015, Patrick Bauerochse + * Portions Copyright (c) 2020, Chris Fraire . * * Licensed under the MIT license: * http://www.opensource.org/licenses/MIT @@ -149,6 +150,9 @@ // initialize the plugin init: function () { + this.numSelected = 0; + this.valMap = null; + this.bulkMode = false; this.config = $.extend(true, {}, this.defaults, this.options, this.metadata); var originalName = this._getNameAttribute(), @@ -988,14 +992,22 @@ // e.g. $('#myPreviousSelectWhichNowIsSol').val() if (this.$originalElement && this.$originalElement.prop('tagName').toLowerCase() === 'select') { var self = this; - this.$originalElement.find('option').each(function (index, item) { - var $currentOriginalOption = $(item); - if ($currentOriginalOption.val() === $changeItem.val()) { - $currentOriginalOption.prop('selected', $changeItem.prop('checked')); + if (this.valMap == null) { + this.$originalElement.find('option').each(function (index, item) { + var $currentOriginalOption = $(item); + if ($currentOriginalOption.val() === $changeItem.val()) { + $currentOriginalOption.prop('selected', $changeItem.prop('checked')); + self.$originalElement.trigger('change'); + return false; // stop the loop + } + }); + } else { + var mappedVal = this.valMap.get($changeItem.val()); + if (mappedVal) { + mappedVal.prop('selected', $changeItem.prop('checked')); self.$originalElement.trigger('change'); - return; } - }); + } } if ($changeItem.prop('checked')) { @@ -1019,16 +1031,34 @@ } }, + _setXItemsSelected: function() { + if (this.config.maxShow !== 0 && this.numSelected > this.config.maxShow) { + var xItemsText = this.config.texts.itemsSelected.replace('{$a}', + this.numSelected - this.config.maxShow); + this.$xItemsSelected.html('
' + + xItemsText + '
'); + this.$showSelectionContainer.append(this.$xItemsSelected); + this.$xItemsSelected.show(); + } else { + this.$xItemsSelected.hide(); + } + }, + _addSelectionDisplayItem: function ($changedItem) { var solOptionItem = $changedItem.data('sol-item'), $existingDisplayItem = solOptionItem.displaySelectionItem, $displayItemText; - if (!$existingDisplayItem) { + this.numSelected = 1 + this.numSelected; + + if (this.config.maxShow !== 0 && this.numSelected > this.config.maxShow) { + if (!this.bulkMode) { + this._setXItemsSelected(); + } + } else { /* * Modified for OpenGrok in 2016, 2019. */ - var selected = this.$showSelectionContainer.children('.sol-selected-display-item'); var label = solOptionItem.label; if ($changedItem.data('messages-available')) { label += ' ' + xitemstext + '
'); - this.$showSelectionContainer.append(this.$xItemsSelected); - this.$xItemsSelected.show(); - $existingDisplayItem.hide(); - } - + solOptionItem.displaySelectionItem = $existingDisplayItem; } }, @@ -1084,32 +1104,15 @@ var solOptionItem = $changedItem.data('sol-item'), $myDisplayItem = solOptionItem.displaySelectionItem; - if ($myDisplayItem) { - /* - * Modified for OpenGrok in 2016. - */ - var selected = this.$showSelectionContainer.children('.sol-selected-display-item'); - if (this.config.maxShow != 0 && selected.length - 1 > this.config.maxShow) { - var xitemstext = this.config.texts.itemsSelected.replace('{$a}', selected.length - 1 - this.config.maxShow); - this.$xItemsSelected.html('
' + xitemstext + '
'); - this.$showSelectionContainer.append(this.$xItemsSelected); - this.$xItemsSelected.show(); - } else { - this.$xItemsSelected.hide(); - } + this.numSelected = this.numSelected - 1; - if ($myDisplayItem.is(":visible")) { - $myDisplayItem - .siblings('.sol-selected-display-item') - .not(":visible") - .not(this.$xItemsSelected) - .first() - .show(); - } - + if ($myDisplayItem) { $myDisplayItem.remove(); solOptionItem.displaySelectionItem = undefined; } + if (!this.bulkMode) { + this._setXItemsSelected(); + } }, _setNoResultsItemVisible: function (visible) { @@ -1130,6 +1133,17 @@ } }, + _buildValMap: function () { + if (this.$originalElement && this.$originalElement.prop('tagName').toLowerCase() === 'select') { + var self = this; + this.valMap = new Map(); + this.$originalElement.find('option').each(function (index, item) { + var $currentOriginalOption = $(item); + self.valMap.set($currentOriginalOption.val(), $currentOriginalOption); + }); + } + }, + isOpen: function () { return this.$container.hasClass('sol-active'); }, @@ -1184,6 +1198,9 @@ */ selectAll: function (/* string or undefined */optgroup) { if (this.config.multiple) { + this._buildValMap(); + this.bulkMode = true; + var $changedInputs = !optgroup ? this.$selectionContainer : this.$selectionContainer .find(".sol-optiongroup-label") @@ -1200,6 +1217,10 @@ if ($.isFunction(this.config.events.onChange)) { this.config.events.onChange.call(this, this, $changedInputs); } + + this.bulkMode = false; + this.valMap = null; + this._setXItemsSelected(); } }, /* @@ -1207,6 +1228,9 @@ */ invert: function () { if (this.config.multiple) { + this._buildValMap(); + this.bulkMode = true; + var $closedInputs = this.$selectionContainer .find('input[type="checkbox"][name=project]:not([disabled], :checked)') var $openedInputs = this.$selectionContainer @@ -1222,6 +1246,10 @@ if ($.isFunction(this.config.events.onChange)) { this.config.events.onChange.call(this, this, $openedInputs.add($closedInputs)); } + + this.bulkMode = false; + this.valMap = null; + this._setXItemsSelected(); } }, /* @@ -1229,6 +1257,9 @@ */ deselectAll: function ( /* string or undefined */ optgroup) { if (this.config.multiple) { + this._buildValMap(); + this.bulkMode = true; + var $changedInputs = !optgroup ? this.$selectionContainer : this.$selectionContainer .find(".sol-optiongroup-label") @@ -1245,6 +1276,10 @@ if ($.isFunction(this.config.events.onChange)) { this.config.events.onChange.call(this, this, $changedInputs); } + + this.bulkMode = false; + this.valMap = null; + this._setXItemsSelected(); } },