|
4 | 4 | * https://pbauerochse.github.io/searchable-option-list/ |
5 | 5 | * |
6 | 6 | * Copyright 2015, Patrick Bauerochse |
| 7 | + * Portions Copyright (c) 2020, Chris Fraire <cfraire@me.com>. |
7 | 8 | * |
8 | 9 | * Licensed under the MIT license: |
9 | 10 | * http://www.opensource.org/licenses/MIT |
|
149 | 150 |
|
150 | 151 | // initialize the plugin |
151 | 152 | init: function () { |
| 153 | + this.numSelected = 0; |
| 154 | + this.valMap = null; |
| 155 | + this.bulkMode = false; |
152 | 156 | this.config = $.extend(true, {}, this.defaults, this.options, this.metadata); |
153 | 157 |
|
154 | 158 | var originalName = this._getNameAttribute(), |
|
988 | 992 | // e.g. $('#myPreviousSelectWhichNowIsSol').val() |
989 | 993 | if (this.$originalElement && this.$originalElement.prop('tagName').toLowerCase() === 'select') { |
990 | 994 | var self = this; |
991 | | - this.$originalElement.find('option').each(function (index, item) { |
992 | | - var $currentOriginalOption = $(item); |
993 | | - if ($currentOriginalOption.val() === $changeItem.val()) { |
994 | | - $currentOriginalOption.prop('selected', $changeItem.prop('checked')); |
| 995 | + if (this.valMap == null) { |
| 996 | + this.$originalElement.find('option').each(function (index, item) { |
| 997 | + var $currentOriginalOption = $(item); |
| 998 | + if ($currentOriginalOption.val() === $changeItem.val()) { |
| 999 | + $currentOriginalOption.prop('selected', $changeItem.prop('checked')); |
| 1000 | + self.$originalElement.trigger('change'); |
| 1001 | + return false; // stop the loop |
| 1002 | + } |
| 1003 | + }); |
| 1004 | + } else { |
| 1005 | + var mappedVal = this.valMap.get($changeItem.val()); |
| 1006 | + if (mappedVal) { |
| 1007 | + mappedVal.prop('selected', $changeItem.prop('checked')); |
995 | 1008 | self.$originalElement.trigger('change'); |
996 | | - return; |
997 | 1009 | } |
998 | | - }); |
| 1010 | + } |
999 | 1011 | } |
1000 | 1012 |
|
1001 | 1013 | if ($changeItem.prop('checked')) { |
|
1019 | 1031 | } |
1020 | 1032 | }, |
1021 | 1033 |
|
| 1034 | + _setXItemsSelected: function() { |
| 1035 | + if (this.config.maxShow !== 0 && this.numSelected > this.config.maxShow) { |
| 1036 | + var xItemsText = this.config.texts.itemsSelected.replace('{$a}', |
| 1037 | + this.numSelected - this.config.maxShow); |
| 1038 | + this.$xItemsSelected.html('<div class="sol-selected-display-item-text">' + |
| 1039 | + xItemsText + '<div>'); |
| 1040 | + this.$showSelectionContainer.append(this.$xItemsSelected); |
| 1041 | + this.$xItemsSelected.show(); |
| 1042 | + } else { |
| 1043 | + this.$xItemsSelected.hide(); |
| 1044 | + } |
| 1045 | + }, |
| 1046 | + |
1022 | 1047 | _addSelectionDisplayItem: function ($changedItem) { |
1023 | 1048 | var solOptionItem = $changedItem.data('sol-item'), |
1024 | 1049 | $existingDisplayItem = solOptionItem.displaySelectionItem, |
1025 | 1050 | $displayItemText; |
1026 | 1051 |
|
1027 | | - if (!$existingDisplayItem) { |
| 1052 | + this.numSelected = 1 + this.numSelected; |
| 1053 | + |
| 1054 | + if (this.config.maxShow !== 0 && this.numSelected > this.config.maxShow) { |
| 1055 | + if (!this.bulkMode) { |
| 1056 | + this._setXItemsSelected(); |
| 1057 | + } |
| 1058 | + } else { |
1028 | 1059 | /* |
1029 | 1060 | * Modified for OpenGrok in 2016, 2019. |
1030 | 1061 | */ |
1031 | | - var selected = this.$showSelectionContainer.children('.sol-selected-display-item'); |
1032 | 1062 | var label = solOptionItem.label; |
1033 | 1063 | if ($changedItem.data('messages-available')) { |
1034 | 1064 | label += ' <span class="'; |
|
1065 | 1095 | }) |
1066 | 1096 | .prependTo($existingDisplayItem); |
1067 | 1097 | } |
1068 | | - /* |
1069 | | - * Modified for OpenGrok in 2016. |
1070 | | - */ |
1071 | | - if (this.config.maxShow != 0 && selected.length + 1 > this.config.maxShow) { |
1072 | | - var xitemstext = this.config.texts.itemsSelected.replace('{$a}', selected.length + 1 - this.config.maxShow); |
1073 | | - this.$xItemsSelected.html('<div class="sol-selected-display-item-text">' + xitemstext + '<div>'); |
1074 | | - this.$showSelectionContainer.append(this.$xItemsSelected); |
1075 | | - this.$xItemsSelected.show(); |
1076 | | - $existingDisplayItem.hide(); |
1077 | | - } |
1078 | | - |
| 1098 | + |
1079 | 1099 | solOptionItem.displaySelectionItem = $existingDisplayItem; |
1080 | 1100 | } |
1081 | 1101 | }, |
|
1084 | 1104 | var solOptionItem = $changedItem.data('sol-item'), |
1085 | 1105 | $myDisplayItem = solOptionItem.displaySelectionItem; |
1086 | 1106 |
|
1087 | | - if ($myDisplayItem) { |
1088 | | - /* |
1089 | | - * Modified for OpenGrok in 2016. |
1090 | | - */ |
1091 | | - var selected = this.$showSelectionContainer.children('.sol-selected-display-item'); |
1092 | | - if (this.config.maxShow != 0 && selected.length - 1 > this.config.maxShow) { |
1093 | | - var xitemstext = this.config.texts.itemsSelected.replace('{$a}', selected.length - 1 - this.config.maxShow); |
1094 | | - this.$xItemsSelected.html('<div class="sol-selected-display-item-text">' + xitemstext + '<div>'); |
1095 | | - this.$showSelectionContainer.append(this.$xItemsSelected); |
1096 | | - this.$xItemsSelected.show(); |
1097 | | - } else { |
1098 | | - this.$xItemsSelected.hide(); |
1099 | | - } |
| 1107 | + this.numSelected = this.numSelected - 1; |
1100 | 1108 |
|
1101 | | - if ($myDisplayItem.is(":visible")) { |
1102 | | - $myDisplayItem |
1103 | | - .siblings('.sol-selected-display-item') |
1104 | | - .not(":visible") |
1105 | | - .not(this.$xItemsSelected) |
1106 | | - .first() |
1107 | | - .show(); |
1108 | | - } |
1109 | | - |
| 1109 | + if ($myDisplayItem) { |
1110 | 1110 | $myDisplayItem.remove(); |
1111 | 1111 | solOptionItem.displaySelectionItem = undefined; |
1112 | 1112 | } |
| 1113 | + if (!this.bulkMode) { |
| 1114 | + this._setXItemsSelected(); |
| 1115 | + } |
1113 | 1116 | }, |
1114 | 1117 |
|
1115 | 1118 | _setNoResultsItemVisible: function (visible) { |
|
1130 | 1133 | } |
1131 | 1134 | }, |
1132 | 1135 |
|
| 1136 | + _buildValMap: function () { |
| 1137 | + if (this.$originalElement && this.$originalElement.prop('tagName').toLowerCase() === 'select') { |
| 1138 | + var self = this; |
| 1139 | + this.valMap = new Map(); |
| 1140 | + this.$originalElement.find('option').each(function (index, item) { |
| 1141 | + var $currentOriginalOption = $(item); |
| 1142 | + self.valMap.set($currentOriginalOption.val(), $currentOriginalOption); |
| 1143 | + }); |
| 1144 | + } |
| 1145 | + }, |
| 1146 | + |
1133 | 1147 | isOpen: function () { |
1134 | 1148 | return this.$container.hasClass('sol-active'); |
1135 | 1149 | }, |
|
1184 | 1198 | */ |
1185 | 1199 | selectAll: function (/* string or undefined */optgroup) { |
1186 | 1200 | if (this.config.multiple) { |
| 1201 | + this._buildValMap(); |
| 1202 | + this.bulkMode = true; |
| 1203 | + |
1187 | 1204 | var $changedInputs = !optgroup ? this.$selectionContainer |
1188 | 1205 | : this.$selectionContainer |
1189 | 1206 | .find(".sol-optiongroup-label") |
|
1200 | 1217 | if ($.isFunction(this.config.events.onChange)) { |
1201 | 1218 | this.config.events.onChange.call(this, this, $changedInputs); |
1202 | 1219 | } |
| 1220 | + |
| 1221 | + this.bulkMode = false; |
| 1222 | + this.valMap = null; |
| 1223 | + this._setXItemsSelected(); |
1203 | 1224 | } |
1204 | 1225 | }, |
1205 | 1226 | /* |
1206 | 1227 | * Modified for OpenGrok in 2016, 2019. |
1207 | 1228 | */ |
1208 | 1229 | invert: function () { |
1209 | 1230 | if (this.config.multiple) { |
| 1231 | + this._buildValMap(); |
| 1232 | + this.bulkMode = true; |
| 1233 | + |
1210 | 1234 | var $closedInputs = this.$selectionContainer |
1211 | 1235 | .find('input[type="checkbox"][name=project]:not([disabled], :checked)') |
1212 | 1236 | var $openedInputs = this.$selectionContainer |
|
1222 | 1246 | if ($.isFunction(this.config.events.onChange)) { |
1223 | 1247 | this.config.events.onChange.call(this, this, $openedInputs.add($closedInputs)); |
1224 | 1248 | } |
| 1249 | + |
| 1250 | + this.bulkMode = false; |
| 1251 | + this.valMap = null; |
| 1252 | + this._setXItemsSelected(); |
1225 | 1253 | } |
1226 | 1254 | }, |
1227 | 1255 | /* |
1228 | 1256 | * Modified for OpenGrok in 2016. |
1229 | 1257 | */ |
1230 | 1258 | deselectAll: function ( /* string or undefined */ optgroup) { |
1231 | 1259 | if (this.config.multiple) { |
| 1260 | + this._buildValMap(); |
| 1261 | + this.bulkMode = true; |
| 1262 | + |
1232 | 1263 | var $changedInputs = !optgroup ? this.$selectionContainer |
1233 | 1264 | : this.$selectionContainer |
1234 | 1265 | .find(".sol-optiongroup-label") |
|
1245 | 1276 | if ($.isFunction(this.config.events.onChange)) { |
1246 | 1277 | this.config.events.onChange.call(this, this, $changedInputs); |
1247 | 1278 | } |
| 1279 | + |
| 1280 | + this.bulkMode = false; |
| 1281 | + this.valMap = null; |
| 1282 | + this._setXItemsSelected(); |
1248 | 1283 | } |
1249 | 1284 | }, |
1250 | 1285 |
|
|
0 commit comments