ui_bibz 3.0.13 → 4.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (294) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -3
  3. data/.github/workflows/linter.yml +13 -12
  4. data/.overcommit.yml +6 -0
  5. data/.rubocop.yml +6 -0
  6. data/.ruby-version +1 -1
  7. data/Gemfile +19 -12
  8. data/Gemfile.lock +178 -138
  9. data/app/assets/config/ui_bibz.js +12 -0
  10. data/app/assets/javascripts/forms/formula.js +82 -0
  11. data/app/assets/javascripts/forms/input-connected.js +132 -0
  12. data/app/assets/javascripts/forms/jquery.multi-select-extend.js +52 -0
  13. data/app/assets/javascripts/forms.js +160 -0
  14. data/app/assets/javascripts/interfaces.js +56 -0
  15. data/app/assets/javascripts/tables.js +49 -0
  16. data/app/assets/javascripts/ui_bibz_js.js +37 -0
  17. data/app/assets/stylesheets/navigations/_nav.sass +2 -0
  18. data/app/assets/stylesheets/navigations/_navbar.sass +12 -0
  19. data/app/assets/stylesheets/navigations/_progress_bar.sass +2 -0
  20. data/app/assets/stylesheets/navigations/_toolbar.sass +3 -0
  21. data/app/assets/stylesheets/sass/_boxes.sass +1 -0
  22. data/app/assets/stylesheets/sass/_containers.sass +2 -0
  23. data/app/assets/stylesheets/sass/_fixes.sass +2 -0
  24. data/app/assets/stylesheets/sass/_forms.sass +8 -0
  25. data/app/assets/stylesheets/sass/_navigations.sass +4 -0
  26. data/app/assets/stylesheets/sass/_notifications.sass +4 -0
  27. data/app/assets/stylesheets/sass/_tables.sass +2 -0
  28. data/app/assets/stylesheets/sass/_variables_mixins_functions.sass +3 -0
  29. data/app/assets/stylesheets/sass/boxes/_card.sass +4 -0
  30. data/app/assets/stylesheets/sass/containers/_panel.scss +330 -0
  31. data/app/assets/stylesheets/sass/forms/_bootstrap_select.sass +5 -0
  32. data/app/assets/stylesheets/sass/forms/_button.sass +3 -0
  33. data/app/assets/stylesheets/sass/forms/_date_picker.sass +3 -0
  34. data/app/assets/stylesheets/sass/forms/_form_check.sass +10 -0
  35. data/app/assets/stylesheets/sass/forms/_formula_field.sass +17 -0
  36. data/app/assets/stylesheets/sass/forms/_multiselect.sass +44 -0
  37. data/app/assets/stylesheets/sass/forms/_range.sass +44 -0
  38. data/app/assets/stylesheets/sass/forms/_slider.sass +136 -0
  39. data/app/assets/stylesheets/sass/forms/_surround_field.sass +25 -0
  40. data/app/assets/stylesheets/sass/notifications/_badge.sass +5 -0
  41. data/app/assets/stylesheets/sass/notifications/_glyph.sass +3 -0
  42. data/app/assets/stylesheets/sass/notifications/_star.sass +2 -0
  43. data/app/assets/stylesheets/sass/notifications/_toast.sass +3 -0
  44. data/app/assets/stylesheets/sass/tables/_table.sass +39 -0
  45. data/app/assets/stylesheets/sass/tables/_table_card.sass +39 -0
  46. data/app/assets/stylesheets/ui_bibz.sass +26 -0
  47. data/bin/test +3 -5
  48. data/config/importmap.rb +19 -0
  49. data/config/initializers/assets.rb +5 -0
  50. data/config/initializers/will_paginate.rb +1 -3
  51. data/lib/ui_bibz/builders/data_html_options_builder.rb +118 -0
  52. data/lib/ui_bibz/builders/html_classes_builder.rb +89 -0
  53. data/lib/ui_bibz/builders/html_options_builder.rb +22 -0
  54. data/lib/ui_bibz/factory_methods/component_initialize_factory_method.rb +33 -0
  55. data/lib/ui_bibz/helpers/ui/core/boxes_helper.rb +12 -12
  56. data/lib/ui_bibz/helpers/ui/core/forms_helper.rb +50 -50
  57. data/lib/ui_bibz/helpers/ui/core/icons_helper.rb +6 -6
  58. data/lib/ui_bibz/helpers/ui/core/layouts_helper.rb +2 -2
  59. data/lib/ui_bibz/helpers/ui/core/lists_helper.rb +2 -2
  60. data/lib/ui_bibz/helpers/ui/core/navigations_helper.rb +12 -12
  61. data/lib/ui_bibz/helpers/ui/core/notifications_helper.rb +4 -4
  62. data/lib/ui_bibz/helpers/ui/core/windows_helper.rb +10 -2
  63. data/lib/ui_bibz/helpers/ui/ux_helper.rb +2 -2
  64. data/lib/ui_bibz/helpers/utils_helper.rb +2 -2
  65. data/lib/ui_bibz/infos.rb +3 -3
  66. data/lib/ui_bibz/inputs/ui_bibz_form/ui_bibz_form_builder.rb +12 -12
  67. data/lib/ui_bibz/inputs/ui_bibz_inputs/collection_input.rb +1 -1
  68. data/lib/ui_bibz/rails/engine.rb +21 -4
  69. data/lib/ui_bibz/strategies/component_initialize_abstract_strategy.rb +27 -0
  70. data/lib/ui_bibz/strategies/component_initialize_block_strategy.rb +31 -0
  71. data/lib/ui_bibz/strategies/component_initialize_hash_strategy.rb +18 -0
  72. data/lib/ui_bibz/strategies/component_initialize_standard_strategy.rb +18 -0
  73. data/lib/ui_bibz/ui/concerns/card_itemable_concern.rb +4 -4
  74. data/lib/ui_bibz/ui/concerns/notification_concern.rb +1 -1
  75. data/lib/ui_bibz/ui/core/boxes/card.rb +1 -1
  76. data/lib/ui_bibz/ui/core/boxes/card_accordion.rb +4 -4
  77. data/lib/ui_bibz/ui/core/boxes/card_column.rb +1 -1
  78. data/lib/ui_bibz/ui/core/boxes/card_deck.rb +1 -1
  79. data/lib/ui_bibz/ui/core/boxes/card_grid.rb +0 -3
  80. data/lib/ui_bibz/ui/core/boxes/card_group.rb +1 -1
  81. data/lib/ui_bibz/ui/core/boxes/components/card_body.rb +9 -9
  82. data/lib/ui_bibz/ui/core/boxes/components/card_col.rb +2 -2
  83. data/lib/ui_bibz/ui/core/boxes/components/card_list_group.rb +1 -1
  84. data/lib/ui_bibz/ui/core/boxes/components/card_row.rb +1 -1
  85. data/lib/ui_bibz/ui/core/component.rb +13 -62
  86. data/lib/ui_bibz/ui/core/forms/buttons/button.rb +3 -1
  87. data/lib/ui_bibz/ui/core/forms/buttons/button_group.rb +11 -11
  88. data/lib/ui_bibz/ui/core/forms/choices/box_switch_field.rb +7 -7
  89. data/lib/ui_bibz/ui/core/forms/choices/checkbox_field.rb +2 -2
  90. data/lib/ui_bibz/ui/core/forms/choices/choice_group.rb +5 -6
  91. data/lib/ui_bibz/ui/core/forms/choices/components/choice.rb +1 -1
  92. data/lib/ui_bibz/ui/core/forms/dates/date_picker_field.rb +15 -15
  93. data/lib/ui_bibz/ui/core/forms/dropdowns/components/dropdown_link.rb +1 -1
  94. data/lib/ui_bibz/ui/core/forms/dropdowns/dropdown.rb +5 -5
  95. data/lib/ui_bibz/ui/core/forms/numbers/slider_field.rb +1 -1
  96. data/lib/ui_bibz/ui/core/forms/selects/dropdown_select_field.rb +10 -10
  97. data/lib/ui_bibz/ui/core/forms/selects/multi_column_field.rb +2 -2
  98. data/lib/ui_bibz/ui/core/forms/surrounds/surround_field.rb +32 -32
  99. data/lib/ui_bibz/ui/core/forms/textareas/markdown_editor_field.rb +7 -8
  100. data/lib/ui_bibz/ui/core/icons/components/glyph_text.rb +1 -1
  101. data/lib/ui_bibz/ui/core/icons/glyph.rb +4 -3
  102. data/lib/ui_bibz/ui/core/layouts/row.rb +2 -2
  103. data/lib/ui_bibz/ui/core/lists/components/list.rb +4 -4
  104. data/lib/ui_bibz/ui/core/lists/list_group.rb +1 -1
  105. data/lib/ui_bibz/ui/core/navigations/breadcrumb.rb +6 -4
  106. data/lib/ui_bibz/ui/core/navigations/components/nav_link_span.rb +1 -2
  107. data/lib/ui_bibz/ui/core/navigations/components/navbar_form.rb +6 -5
  108. data/lib/ui_bibz/ui/core/navigations/components/toolbar_form.rb +2 -2
  109. data/lib/ui_bibz/ui/core/navigations/nav.rb +10 -6
  110. data/lib/ui_bibz/ui/core/navigations/navbar.rb +21 -19
  111. data/lib/ui_bibz/ui/core/navigations/pagination.rb +3 -3
  112. data/lib/ui_bibz/ui/core/navigations/toolbar.rb +5 -5
  113. data/lib/ui_bibz/ui/core/notifications/alert.rb +4 -5
  114. data/lib/ui_bibz/ui/core/notifications/badge.rb +6 -2
  115. data/lib/ui_bibz/ui/core/notifications/components/toast_header.rb +1 -1
  116. data/lib/ui_bibz/ui/core/notifications/progress_bar.rb +3 -3
  117. data/lib/ui_bibz/ui/core/notifications/toast.rb +8 -9
  118. data/lib/ui_bibz/ui/core/windows/components/offcanvas_body.rb +47 -0
  119. data/lib/ui_bibz/ui/core/windows/components/offcanvas_header.rb +54 -0
  120. data/lib/ui_bibz/ui/core/windows/modal.rb +9 -9
  121. data/lib/ui_bibz/ui/core/windows/offcanvas.rb +84 -0
  122. data/lib/ui_bibz/ui/extensions/core/component/glyph_extension.rb +4 -20
  123. data/lib/ui_bibz/ui/extensions/core/component/klass_extension.rb +11 -19
  124. data/lib/ui_bibz/ui/extensions/core/forms/connect_extension.rb +1 -1
  125. data/lib/ui_bibz/ui/ux/containers/components/panel_column.rb +3 -3
  126. data/lib/ui_bibz/ui/ux/containers/components/panel_deck.rb +3 -3
  127. data/lib/ui_bibz/ui/ux/containers/components/panel_group.rb +3 -3
  128. data/lib/ui_bibz/ui/ux/containers/components/panel_header.rb +4 -4
  129. data/lib/ui_bibz/ui/ux/containers/panel.rb +13 -13
  130. data/lib/ui_bibz/ui/ux/tables/components/actions.rb +4 -4
  131. data/lib/ui_bibz/ui/ux/tables/components/column.rb +1 -1
  132. data/lib/ui_bibz/ui/ux/tables/components/columns.rb +2 -2
  133. data/lib/ui_bibz/ui/ux/tables/extensions/sortable.rb +1 -1
  134. data/lib/ui_bibz/ui/ux/tables/table.rb +5 -5
  135. data/lib/ui_bibz/ui/ux/tables/table_card.rb +6 -6
  136. data/lib/ui_bibz/ui/ux/tables/table_search_field.rb +1 -1
  137. data/lib/ui_bibz/utils/breakdown_class_name_generator.rb +3 -3
  138. data/lib/ui_bibz/utils/screwdriver.rb +1 -1
  139. data/lib/ui_bibz/view_objects/glyph_component_view_object.rb +38 -0
  140. data/lib/ui_bibz.rb +25 -0
  141. data/test/builders/data_html_classes_builder_test.rb +37 -0
  142. data/test/builders/html_classes_builder_test.rb +76 -0
  143. data/test/dummy/Rakefile +1 -1
  144. data/test/dummy/app/assets/stylesheets/application.css +1 -15
  145. data/test/dummy/app/channels/application_cable/channel.rb +6 -0
  146. data/test/dummy/app/channels/application_cable/connection.rb +6 -0
  147. data/test/dummy/app/jobs/application_job.rb +9 -0
  148. data/test/dummy/app/mailers/application_mailer.rb +6 -0
  149. data/test/dummy/app/views/layouts/application.html.erb +10 -12
  150. data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
  151. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  152. data/test/dummy/bin/rails +3 -3
  153. data/test/dummy/bin/rake +2 -2
  154. data/test/dummy/bin/setup +12 -12
  155. data/test/dummy/config/application.rb +13 -17
  156. data/test/dummy/config/boot.rb +3 -3
  157. data/test/dummy/config/database.yml +2 -2
  158. data/test/dummy/config/environment.rb +1 -1
  159. data/test/dummy/config/environments/development.rb +21 -16
  160. data/test/dummy/config/environments/production.rb +16 -41
  161. data/test/dummy/config/environments/test.rb +19 -8
  162. data/test/dummy/config/importmap.rb +11 -0
  163. data/test/dummy/config/initializers/content_security_policy.rb +21 -24
  164. data/test/dummy/config/initializers/filter_parameter_logging.rb +6 -2
  165. data/test/dummy/config/initializers/inflections.rb +4 -4
  166. data/test/dummy/config/initializers/permissions_policy.rb +12 -0
  167. data/test/dummy/config/locales/en.yml +13 -3
  168. data/test/dummy/config/puma.rb +7 -2
  169. data/test/dummy/config/storage.yml +5 -5
  170. data/test/dummy/config.ru +2 -1
  171. data/test/simple_form_test.rb +24 -24
  172. data/test/ui/core/boxes/card_test.rb +2 -1
  173. data/test/ui/core/component_test.rb +2 -2
  174. data/test/ui/core/forms/buttons/button_group_test.rb +1 -1
  175. data/test/ui/core/forms/buttons/button_link_test.rb +1 -1
  176. data/test/ui/core/forms/buttons/button_refresh_test.rb +1 -1
  177. data/test/ui/core/forms/buttons/button_test.rb +2 -2
  178. data/test/ui/core/forms/choices/box_switch_field_test.rb +10 -10
  179. data/test/ui/core/forms/choices/checkbox_field_test.rb +1 -1
  180. data/test/ui/core/forms/choices/choice_group_test.rb +1 -1
  181. data/test/ui/core/forms/dropdowns/dropdown_test.rb +1 -1
  182. data/test/ui/core/forms/numbers/formula_field_test.rb +1 -1
  183. data/test/ui/core/forms/selects/dropdown_select_field_test.rb +2 -2
  184. data/test/ui/core/forms/selects/select_field_test.rb +1 -1
  185. data/test/ui/core/forms/surrounds/surround_field_test.rb +4 -4
  186. data/test/ui/core/forms/texts/auto_complete_field_test.rb +2 -2
  187. data/test/ui/core/icons/glyph_test.rb +8 -4
  188. data/test/ui/core/icons/star_test.rb +12 -6
  189. data/test/ui/core/navigations/breadcrumb_test.rb +1 -1
  190. data/test/ui/core/navigations/link_test.rb +1 -1
  191. data/test/ui/core/navigations/nav_test.rb +11 -0
  192. data/test/ui/core/notifications/alert_test.rb +1 -1
  193. data/test/ui/core/notifications/badge_test.rb +3 -3
  194. data/test/ui/core/notifications/popover_test.rb +4 -4
  195. data/test/ui/core/notifications/spinner_test.rb +1 -1
  196. data/test/ui/core/notifications/toast_test.rb +1 -1
  197. data/test/ui/core/notifications/tooltip_test.rb +4 -4
  198. data/test/ui/core/windows/offcanvas_test.rb +27 -0
  199. data/test/ui/ux/containers/panel_test.rb +1 -1
  200. data/test/ui/ux/tables/table_test.rb +3 -3
  201. data/test/view_objects/glyph_component_view_object_test.rb +17 -0
  202. data/ui_bibz.gemspec +6 -20
  203. data/vendor/assets/fonts/fontawesome/fa-brands-400.ttf +0 -0
  204. data/vendor/assets/fonts/fontawesome/fa-brands-400.woff2 +0 -0
  205. data/vendor/assets/fonts/fontawesome/fa-regular-400.ttf +0 -0
  206. data/vendor/assets/fonts/fontawesome/fa-regular-400.woff2 +0 -0
  207. data/vendor/assets/fonts/fontawesome/fa-solid-900.ttf +0 -0
  208. data/vendor/assets/fonts/fontawesome/fa-solid-900.woff2 +0 -0
  209. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.ttf +0 -0
  210. data/vendor/assets/fonts/fontawesome/fa-v4compatibility.woff2 +0 -0
  211. data/vendor/assets/javascripts/bootstrap-markdown.js +1 -1555
  212. data/vendor/assets/javascripts/bootstrap-multiselect.min.js +40 -1176
  213. data/vendor/assets/javascripts/bootstrap-switch.min.js +9 -21
  214. data/vendor/assets/javascripts/bs-custom-file-input.min.js +0 -1
  215. data/vendor/assets/javascripts/fontawesome/all.js +5977 -0
  216. data/vendor/assets/javascripts/fontawesome/all.min.js +6 -0
  217. data/vendor/assets/javascripts/fontawesome/brands.js +749 -0
  218. data/vendor/assets/javascripts/fontawesome/brands.min.js +6 -0
  219. data/vendor/assets/javascripts/fontawesome/conflict-detection.js +1138 -0
  220. data/vendor/assets/javascripts/fontawesome/conflict-detection.min.js +6 -0
  221. data/vendor/assets/javascripts/fontawesome/fontawesome.js +3126 -0
  222. data/vendor/assets/javascripts/fontawesome/fontawesome.min.js +6 -0
  223. data/vendor/assets/javascripts/fontawesome/regular.js +445 -0
  224. data/vendor/assets/javascripts/fontawesome/regular.min.js +6 -0
  225. data/vendor/assets/javascripts/fontawesome/solid.js +1672 -0
  226. data/vendor/assets/javascripts/fontawesome/solid.min.js +6 -0
  227. data/vendor/assets/javascripts/fontawesome/v4-shims.js +225 -0
  228. data/vendor/assets/javascripts/fontawesome/v4-shims.min.js +6 -0
  229. data/vendor/assets/javascripts/fuzzysort.js +562 -0
  230. data/vendor/assets/javascripts/jquery-3.7.0.min.js +2 -0
  231. data/vendor/assets/javascripts/jquery.multi-select.min.js +725 -1
  232. data/vendor/assets/stylesheets/bootstrap-multiselect.sass +115 -0
  233. data/vendor/assets/stylesheets/bootstrap-switch.scss +211 -0
  234. data/vendor/assets/stylesheets/fontawesome/_animated.scss +142 -9
  235. data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +13 -13
  236. data/vendor/assets/stylesheets/fontawesome/_core.scss +28 -6
  237. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +2 -1
  238. data/vendor/assets/stylesheets/fontawesome/_functions.scss +57 -0
  239. data/vendor/assets/stylesheets/fontawesome/_icons.scss +7 -1438
  240. data/vendor/assets/stylesheets/fontawesome/_list.scss +4 -4
  241. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +53 -34
  242. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +25 -18
  243. data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +12 -3
  244. data/vendor/assets/stylesheets/fontawesome/_shims.scss +640 -664
  245. data/vendor/assets/stylesheets/fontawesome/_sizing.scss +16 -0
  246. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +5 -4
  247. data/vendor/assets/stylesheets/fontawesome/_variables.scss +4896 -1393
  248. data/vendor/assets/stylesheets/fontawesome/brands.scss +17 -10
  249. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +7 -2
  250. data/vendor/assets/stylesheets/fontawesome/regular.scss +13 -10
  251. data/vendor/assets/stylesheets/fontawesome/solid.scss +13 -11
  252. data/vendor/assets/stylesheets/fontawesome/v4-shims.scss +6 -1
  253. data/vendor/assets/stylesheets/multi-select.css +92 -0
  254. metadata +120 -348
  255. data/.gitlab-ci.yml +0 -17
  256. data/.travis.yml +0 -24
  257. data/lib/ui_bibz/ui/extensions/core/component/popover_extension.rb +0 -70
  258. data/structure.md +0 -68
  259. data/test/dummy/README.rdoc +0 -28
  260. data/test/dummy/app/assets/javascripts/application.js +0 -13
  261. data/test/dummy/app/javascripts/packs/index.js +0 -3
  262. data/test/dummy/config/initializers/application_controller_renderer.rb +0 -9
  263. data/test/dummy/config/initializers/assets.rb +0 -14
  264. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
  265. data/test/dummy/config/initializers/cookies_serializer.rb +0 -7
  266. data/test/dummy/config/initializers/mime_types.rb +0 -5
  267. data/test/dummy/config/initializers/session_store.rb +0 -5
  268. data/test/dummy/config/initializers/ui_bibz.rb +0 -5
  269. data/test/dummy/config/initializers/wrap_parameters.rb +0 -16
  270. data/test/dummy/config/secrets.yml +0 -22
  271. data/test/dummy/config/spring.rb +0 -8
  272. data/test/dummy/test/models/user_test.rb +0 -9
  273. data/vendor/assets/fonts/fa-brands-400.eot +0 -0
  274. data/vendor/assets/fonts/fa-brands-400.svg +0 -3570
  275. data/vendor/assets/fonts/fa-brands-400.ttf +0 -0
  276. data/vendor/assets/fonts/fa-brands-400.woff +0 -0
  277. data/vendor/assets/fonts/fa-brands-400.woff2 +0 -0
  278. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  279. data/vendor/assets/fonts/fa-regular-400.svg +0 -803
  280. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  281. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  282. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  283. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  284. data/vendor/assets/fonts/fa-solid-900.svg +0 -4938
  285. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  286. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  287. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  288. data/vendor/assets/javascripts/all.js +0 -4441
  289. data/vendor/assets/javascripts/all.min.js +0 -5
  290. data/vendor/assets/stylesheets/all.min.css +0 -5
  291. data/vendor/assets/stylesheets/fontawesome/_larger.scss +0 -23
  292. data/vendor/assets/stylesheets/svg-with-js.css +0 -5
  293. /data/{test/dummy/app/mailers/.keep → app/assets/stylesheets/sass/forms/_dropdown.sass} +0 -0
  294. /data/{test/dummy/app/views/users/index.html.erb → app/assets/stylesheets/sass/forms/_input_refresh_button.sass} +0 -0
@@ -1,1180 +1,44 @@
1
1
  /**
2
- * Bootstrap Multiselect v0.9.8 (https://github.com/davidstutz/bootstrap-multiselect)
2
+ * Bootstrap Multiselect (http://davidstutz.de/bootstrap-multiselect/)
3
3
  *
4
- * Copyright 2012 - 2014 David Stutz
4
+ * Apache License, Version 2.0:
5
+ * Copyright (c) 2012 - 2021 David Stutz
5
6
  *
6
- * Dual licensed under the BSD-3-Clause and the Apache License, Version 2.0.
7
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
+ * use this file except in compliance with the License. You may obtain a
9
+ * copy of the License at http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ * License for the specific language governing permissions and limitations
15
+ * under the License.
16
+ *
17
+ * BSD 3-Clause License:
18
+ * Copyright (c) 2012 - 2021 David Stutz
19
+ * All rights reserved.
20
+ *
21
+ * Redistribution and use in source and binary forms, with or without
22
+ * modification, are permitted provided that the following conditions are met:
23
+ * - Redistributions of source code must retain the above copyright notice,
24
+ * this list of conditions and the following disclaimer.
25
+ * - Redistributions in binary form must reproduce the above copyright notice,
26
+ * this list of conditions and the following disclaimer in the documentation
27
+ * and/or other materials provided with the distribution.
28
+ * - Neither the name of David Stutz nor the names of its contributors may be
29
+ * used to endorse or promote products derived from this software without
30
+ * specific prior written permission.
31
+ *
32
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
34
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
36
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
38
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
39
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
40
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
41
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
42
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7
43
  */
8
- !function($) {
9
-
10
- "use strict";// jshint ;_;
11
-
12
- if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) {
13
- ko.bindingHandlers.multiselect = {
14
-
15
- init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
16
-
17
- var listOfSelectedItems = allBindingsAccessor().selectedOptions;
18
- var config = ko.utils.unwrapObservable(valueAccessor());
19
-
20
- $(element).multiselect(config);
21
-
22
- if (isObservableArray(listOfSelectedItems)) {
23
-
24
- // Set the initial selection state on the multiselect list.
25
- $(element).multiselect('select', ko.utils.unwrapObservable(listOfSelectedItems));
26
-
27
- // Subscribe to the selectedOptions: ko.observableArray
28
- listOfSelectedItems.subscribe(function (changes) {
29
- var addedArray = [], deletedArray = [];
30
- forEach(changes, function (change) {
31
- switch (change.status) {
32
- case 'added':
33
- addedArray.push(change.value);
34
- break;
35
- case 'deleted':
36
- deletedArray.push(change.value);
37
- break;
38
- }
39
- });
40
-
41
- if (addedArray.length > 0) {
42
- $(element).multiselect('select', addedArray);
43
- }
44
-
45
- if (deletedArray.length > 0) {
46
- $(element).multiselect('deselect', deletedArray);
47
- }
48
- }, null, "arrayChange");
49
- }
50
- },
51
-
52
- update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
53
-
54
- var listOfItems = allBindingsAccessor().options,
55
- ms = $(element).data('multiselect'),
56
- config = ko.utils.unwrapObservable(valueAccessor());
57
-
58
- if (isObservableArray(listOfItems)) {
59
- // Subscribe to the options: ko.observableArray incase it changes later
60
- listOfItems.subscribe(function (theArray) {
61
- $(element).multiselect('rebuild');
62
- });
63
- }
64
-
65
- if (!ms) {
66
- $(element).multiselect(config);
67
- }
68
- else {
69
- ms.updateOriginalOptions();
70
- }
71
- }
72
- };
73
- }
74
-
75
- function isObservableArray(obj) {
76
- return ko.isObservable(obj) && !(obj.destroyAll === undefined);
77
- }
78
-
79
- function forEach(array, callback) {
80
- for (var index = 0; index < array.length; ++index) {
81
- callback(array[index]);
82
- }
83
- }
84
-
85
- /**
86
- * Constructor to create a new multiselect using the given select.
87
- *
88
- * @param {jQuery} select
89
- * @param {Object} options
90
- * @returns {Multiselect}
91
- */
92
- function Multiselect(select, options) {
93
-
94
- this.options = this.mergeOptions(options);
95
- this.$select = $(select);
96
-
97
- // Initialization.
98
- // We have to clone to create a new reference.
99
- this.originalOptions = this.$select.clone()[0].options;
100
- this.query = '';
101
- this.searchTimeout = null;
102
-
103
- this.options.multiple = this.$select.attr('multiple') === "multiple";
104
- this.options.onChange = $.proxy(this.options.onChange, this);
105
- this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this);
106
- this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this);
107
- this.options.onDropdownShown = $.proxy(this.options.onDropdownShown, this);
108
- this.options.onDropdownHidden = $.proxy(this.options.onDropdownHidden, this);
109
-
110
- // Build select all if enabled.
111
- this.buildContainer();
112
- this.buildButton();
113
- this.buildDropdown();
114
- this.buildSelectAll();
115
- this.buildDropdownOptions();
116
- this.buildFilter();
117
-
118
- this.updateButtonText();
119
- this.updateSelectAll();
120
-
121
- if (this.options.disableIfEmpty) {
122
- this.disableIfEmpty();
123
- }
124
-
125
- this.$select.hide().after(this.$container);
126
- };
127
-
128
- Multiselect.prototype = {
129
-
130
- defaults: {
131
- /**
132
- * Default text function will either print 'None selected' in case no
133
- * option is selected or a list of the selected options up to a length
134
- * of 3 selected options.
135
- *
136
- * @param {jQuery} options
137
- * @param {jQuery} select
138
- * @returns {String}
139
- */
140
- buttonText: function(options, select) {
141
- if (options.length === 0) {
142
- return this.nonSelectedText + ' <b class="caret"></b>';
143
- }
144
- else {
145
- if (options.length > this.numberDisplayed) {
146
- return options.length + ' ' + this.nSelectedText + ' <b class="caret"></b>';
147
- }
148
- else {
149
- var selected = '';
150
- options.each(function() {
151
- var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).html();
152
-
153
- selected += label + ', ';
154
- });
155
- return selected.substr(0, selected.length - 2) + ' <b class="caret"></b>';
156
- }
157
- }
158
- },
159
- /**
160
- * Updates the title of the button similar to the buttonText function.
161
- *
162
- * @param {jQuery} options
163
- * @param {jQuery} select
164
- * @returns {@exp;selected@call;substr}
165
- */
166
- buttonTitle: function(options, select) {
167
- if (options.length === 0) {
168
- return this.nonSelectedText;
169
- }
170
- else {
171
- var selected = '';
172
- options.each(function () {
173
- selected += $(this).text() + ', ';
174
- });
175
- return selected.substr(0, selected.length - 2);
176
- }
177
- },
178
- /**
179
- * Create a label.
180
- *
181
- * @param {jQuery} element
182
- * @returns {String}
183
- */
184
- label: function(element){
185
- return $(element).attr('label') || $(element).html();
186
- },
187
- /**
188
- * Triggered on change of the multiselect.
189
- *
190
- * Not triggered when selecting/deselecting options manually.
191
- *
192
- * @param {jQuery} option
193
- * @param {Boolean} checked
194
- */
195
- onChange : function(option, checked) {
196
-
197
- },
198
- /**
199
- * Triggered when the dropdown is shown.
200
- *
201
- * @param {jQuery} event
202
- */
203
- onDropdownShow: function(event) {
204
-
205
- },
206
- /**
207
- * Triggered when the dropdown is hidden.
208
- *
209
- * @param {jQuery} event
210
- */
211
- onDropdownHide: function(event) {
212
-
213
- },
214
- /**
215
- * Triggered after the dropdown is shown.
216
- *
217
- * @param {jQuery} event
218
- */
219
- onDropdownShown: function(event) {
220
-
221
- },
222
- /**
223
- * Triggered after the dropdown is hidden.
224
- *
225
- * @param {jQuery} event
226
- */
227
- onDropdownHidden: function(event) {
228
-
229
- },
230
- buttonClass: 'btn btn-default',
231
- dropRight: false,
232
- selectedClass: 'active',
233
- buttonWidth: 'auto',
234
- buttonContainer: '<div class="btn-group" />',
235
- // Maximum height of the dropdown menu.
236
- // If maximum height is exceeded a scrollbar will be displayed.
237
- maxHeight: false,
238
- checkboxName: false,
239
- includeSelectAllOption: false,
240
- includeSelectAllIfMoreThan: 0,
241
- selectAllText: ' Select all',
242
- selectAllValue: 'multiselect-all',
243
- enableFiltering: false,
244
- enableCaseInsensitiveFiltering: false,
245
- filterPlaceholder: 'Search',
246
- // possible options: 'text', 'value', 'both'
247
- filterBehavior: 'text',
248
- preventInputChangeEvent: false,
249
- nonSelectedText: 'None selected',
250
- nSelectedText: 'selected',
251
- numberDisplayed: 3,
252
- disableIfEmpty: false,
253
- templates: {
254
- button: '<button type="button" class="multiselect dropdown-toggle" data-toggle="dropdown"></button>',
255
- ul: '<ul class="multiselect-container dropdown-menu"></ul>',
256
- filter: '<li class="multiselect-item filter"><div class=""><input class="form-control multiselect-search" type="text"></div></li>',
257
- li: '<li><a href="javascript:void(0);"><label></label></a></li>',
258
- divider: '<li class="multiselect-item divider"></li>',
259
- liGroup: '<li class="multiselect-item group"><label class="multiselect-group"></label></li>'
260
- }
261
- },
262
-
263
- constructor: Multiselect,
264
-
265
- /**
266
- * Builds the container of the multiselect.
267
- */
268
- buildContainer: function() {
269
- this.$container = $(this.options.buttonContainer);
270
- this.$container.on('show.bs.dropdown', this.options.onDropdownShow);
271
- this.$container.on('hide.bs.dropdown', this.options.onDropdownHide);
272
- this.$container.on('shown.bs.dropdown', this.options.onDropdownShown);
273
- this.$container.on('hidden.bs.dropdown', this.options.onDropdownHidden);
274
- },
275
-
276
- /**
277
- * Builds the button of the multiselect.
278
- */
279
- buildButton: function() {
280
- this.$button = $(this.options.templates.button).addClass(this.options.buttonClass);
281
-
282
- // Adopt active state.
283
- if (this.$select.prop('disabled')) {
284
- this.disable();
285
- }
286
- else {
287
- this.enable();
288
- }
289
-
290
- // Manually add button width if set.
291
- if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') {
292
- this.$button.css({
293
- 'width' : this.options.buttonWidth
294
- });
295
- this.$container.css({
296
- 'width': this.options.buttonWidth
297
- });
298
- }
299
-
300
- // Keep the tab index from the select.
301
- var tabindex = this.$select.attr('tabindex');
302
- if (tabindex) {
303
- this.$button.attr('tabindex', tabindex);
304
- }
305
-
306
- this.$container.prepend(this.$button);
307
- },
308
-
309
- /**
310
- * Builds the ul representing the dropdown menu.
311
- */
312
- buildDropdown: function() {
313
-
314
- // Build ul.
315
- this.$ul = $(this.options.templates.ul);
316
-
317
- if (this.options.dropRight) {
318
- this.$ul.addClass('pull-right');
319
- }
320
-
321
- // Set max height of dropdown menu to activate auto scrollbar.
322
- if (this.options.maxHeight) {
323
- // TODO: Add a class for this option to move the css declarations.
324
- this.$ul.css({
325
- 'max-height': this.options.maxHeight + 'px',
326
- 'overflow-y': 'auto',
327
- 'overflow-x': 'hidden'
328
- });
329
- }
330
-
331
- this.$container.append(this.$ul);
332
- },
333
-
334
- /**
335
- * Build the dropdown options and binds all nessecary events.
336
- *
337
- * Uses createDivider and createOptionValue to create the necessary options.
338
- */
339
- buildDropdownOptions: function() {
340
-
341
- this.$select.children().each($.proxy(function(index, element) {
342
-
343
- // Support optgroups and options without a group simultaneously.
344
- var tag = $(element).prop('tagName')
345
- .toLowerCase();
346
-
347
- if ($(element).prop('value') === this.options.selectAllValue) {
348
- return;
349
- }
350
-
351
- if (tag === 'optgroup') {
352
- this.createOptgroup(element);
353
- }
354
- else if (tag === 'option') {
355
-
356
- if ($(element).data('role') === 'divider') {
357
- this.createDivider();
358
- }
359
- else {
360
- this.createOptionValue(element);
361
- }
362
-
363
- }
364
-
365
- // Other illegal tags will be ignored.
366
- }, this));
367
-
368
- // Bind the change event on the dropdown elements.
369
- $('li input', this.$ul).on('change', $.proxy(function(event) {
370
- var $target = $(event.target);
371
-
372
- var checked = $target.prop('checked') || false;
373
- var isSelectAllOption = $target.val() === this.options.selectAllValue;
374
-
375
- // Apply or unapply the configured selected class.
376
- if (this.options.selectedClass) {
377
- if (checked) {
378
- $target.parents('li')
379
- .addClass(this.options.selectedClass);
380
- }
381
- else {
382
- $target.parents('li')
383
- .removeClass(this.options.selectedClass);
384
- }
385
- }
386
-
387
- // Get the corresponding option.
388
- var value = $target.val();
389
- var $option = this.getOptionByValue(value);
390
-
391
- var $optionsNotThis = $('option', this.$select).not($option);
392
- var $checkboxesNotThis = $('input', this.$container).not($target);
393
-
394
- if (isSelectAllOption) {
395
- if (checked) {
396
- this.selectAll();
397
- }
398
- else {
399
- this.deselectAll();
400
- }
401
- }
402
-
403
- if(!isSelectAllOption){
404
- if (checked) {
405
- $option.prop('selected', true);
406
-
407
- if (this.options.multiple) {
408
- // Simply select additional option.
409
- $option.prop('selected', true);
410
- }
411
- else {
412
- // Unselect all other options and corresponding checkboxes.
413
- if (this.options.selectedClass) {
414
- $($checkboxesNotThis).parents('li').removeClass(this.options.selectedClass);
415
- }
416
-
417
- $($checkboxesNotThis).prop('checked', false);
418
- $optionsNotThis.prop('selected', false);
419
-
420
- // It's a single selection, so close.
421
- this.$button.click();
422
- }
423
-
424
- if (this.options.selectedClass === "active") {
425
- $optionsNotThis.parents("a").css("outline", "");
426
- }
427
- }
428
- else {
429
- // Unselect option.
430
- $option.prop('selected', false);
431
- }
432
- }
433
-
434
- this.$select.change();
435
-
436
- this.updateButtonText();
437
- this.updateSelectAll();
438
-
439
- this.options.onChange($option, checked);
440
-
441
- if(this.options.preventInputChangeEvent) {
442
- return false;
443
- }
444
- }, this));
445
-
446
- $('li a', this.$ul).on('touchstart click', function(event) {
447
- event.stopPropagation();
448
-
449
- var $target = $(event.target);
450
-
451
- if (event.shiftKey) {
452
- var checked = $target.prop('checked') || false;
453
-
454
- if (checked) {
455
- var prev = $target.parents('li:last')
456
- .siblings('li[class="active"]:first');
457
-
458
- var currentIdx = $target.parents('li')
459
- .index();
460
- var prevIdx = prev.index();
461
-
462
- if (currentIdx > prevIdx) {
463
- $target.parents("li:last").prevUntil(prev).each(
464
- function() {
465
- $(this).find("input:first").prop("checked", true)
466
- .trigger("change");
467
- }
468
- );
469
- }
470
- else {
471
- $target.parents("li:last").nextUntil(prev).each(
472
- function() {
473
- $(this).find("input:first").prop("checked", true)
474
- .trigger("change");
475
- }
476
- );
477
- }
478
- }
479
- }
480
-
481
- $target.blur();
482
- });
483
-
484
- // Keyboard support.
485
- this.$container.off('keydown.multiselect').on('keydown.multiselect', $.proxy(function(event) {
486
- if ($('input[type="text"]', this.$container).is(':focus')) {
487
- return;
488
- }
489
- if ((event.keyCode === 9 || event.keyCode === 27)
490
- && this.$container.hasClass('open')) {
491
-
492
- // Close on tab or escape.
493
- this.$button.click();
494
- }
495
- else {
496
- var $items = $(this.$container).find("li:not(.divider):not(.disabled) a").filter(":visible");
497
-
498
- if (!$items.length) {
499
- return;
500
- }
501
-
502
- var index = $items.index($items.filter(':focus'));
503
-
504
- // Navigation up.
505
- if (event.keyCode === 38 && index > 0) {
506
- index--;
507
- }
508
- // Navigate down.
509
- else if (event.keyCode === 40 && index < $items.length - 1) {
510
- index++;
511
- }
512
- else if (!~index) {
513
- index = 0;
514
- }
515
-
516
- var $current = $items.eq(index);
517
- $current.focus();
518
-
519
- if (event.keyCode === 32 || event.keyCode === 13) {
520
- var $checkbox = $current.find('input');
521
-
522
- $checkbox.prop("checked", !$checkbox.prop("checked"));
523
- $checkbox.change();
524
- }
525
-
526
- event.stopPropagation();
527
- event.preventDefault();
528
- }
529
- }, this));
530
- },
531
-
532
- /**
533
- * Create an option using the given select option.
534
- *
535
- * @param {jQuery} element
536
- */
537
- createOptionValue: function(element) {
538
- if ($(element).is(':selected')) {
539
- $(element).prop('selected', true);
540
- }
541
-
542
- // Support the label attribute on options.
543
- var label = this.options.label(element);
544
- var value = $(element).val();
545
- var inputType = this.options.multiple ? "checkbox" : "radio";
546
-
547
- var $li = $(this.options.templates.li);
548
- $('label', $li).addClass(inputType);
549
-
550
- if (this.options.checkboxName) {
551
- $('label', $li).append('<input type="' + inputType + '" name="' + this.options.checkboxName + '" />');
552
- }
553
- else {
554
- $('label', $li).append('<input type="' + inputType + '" />');
555
- }
556
-
557
- var selected = $(element).prop('selected') || false;
558
- var $checkbox = $('input', $li);
559
- $checkbox.val(value);
560
-
561
- if (value === this.options.selectAllValue) {
562
- $li.addClass("multiselect-item multiselect-all");
563
- $checkbox.parent().parent()
564
- .addClass('multiselect-all');
565
- }
566
-
567
- $('label', $li).append(" " + label);
568
-
569
- this.$ul.append($li);
570
-
571
- if ($(element).is(':disabled')) {
572
- $checkbox.attr('disabled', 'disabled')
573
- .prop('disabled', true)
574
- .parents('a')
575
- .attr("tabindex", "-1")
576
- .parents('li')
577
- .addClass('disabled');
578
- }
579
-
580
- $checkbox.prop('checked', selected);
581
-
582
- if (selected && this.options.selectedClass) {
583
- $checkbox.parents('li')
584
- .addClass(this.options.selectedClass);
585
- }
586
- },
587
-
588
- /**
589
- * Creates a divider using the given select option.
590
- *
591
- * @param {jQuery} element
592
- */
593
- createDivider: function(element) {
594
- var $divider = $(this.options.templates.divider);
595
- this.$ul.append($divider);
596
- },
597
-
598
- /**
599
- * Creates an optgroup.
600
- *
601
- * @param {jQuery} group
602
- */
603
- createOptgroup: function(group) {
604
- var groupName = $(group).prop('label');
605
-
606
- // Add a header for the group.
607
- var $li = $(this.options.templates.liGroup);
608
- $('label', $li).text(groupName);
609
-
610
- this.$ul.append($li);
611
-
612
- if ($(group).is(':disabled')) {
613
- $li.addClass('disabled');
614
- }
615
-
616
- // Add the options of the group.
617
- $('option', group).each($.proxy(function(index, element) {
618
- this.createOptionValue(element);
619
- }, this));
620
- },
621
-
622
- /**
623
- * Build the selct all.
624
- *
625
- * Checks if a select all has already been created.
626
- */
627
- buildSelectAll: function() {
628
- var alreadyHasSelectAll = this.hasSelectAll();
629
-
630
- if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple
631
- && $('option', this.$select).length > this.options.includeSelectAllIfMoreThan) {
632
-
633
- // Check whether to add a divider after the select all.
634
- if (this.options.includeSelectAllDivider) {
635
- this.$ul.prepend($(this.options.templates.divider));
636
- }
637
-
638
- var $li = $(this.options.templates.li);
639
- $('label', $li).addClass("checkbox");
640
-
641
- if (this.options.checkboxName) {
642
- $('label', $li).append('<input type="checkbox" name="' + this.options.checkboxName + '" />');
643
- }
644
- else {
645
- $('label', $li).append('<input type="checkbox" />');
646
- }
647
-
648
- var $checkbox = $('input', $li);
649
- $checkbox.val(this.options.selectAllValue);
650
-
651
- $li.addClass("multiselect-item multiselect-all");
652
- $checkbox.parent().parent()
653
- .addClass('multiselect-all');
654
-
655
- $('label', $li).append(" " + this.options.selectAllText);
656
-
657
- this.$ul.prepend($li);
658
-
659
- $checkbox.prop('checked', false);
660
- }
661
- },
662
-
663
- /**
664
- * Builds the filter.
665
- */
666
- buildFilter: function() {
667
-
668
- // Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength.
669
- if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) {
670
- var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering);
671
-
672
- if (this.$select.find('option').length >= enableFilterLength) {
673
-
674
- this.$filter = $(this.options.templates.filter);
675
- $('input', this.$filter).attr('placeholder', this.options.filterPlaceholder);
676
- this.$ul.prepend(this.$filter);
677
-
678
- this.$filter.val(this.query).on('click', function(event) {
679
- event.stopPropagation();
680
- }).on('input keydown', $.proxy(function(event) {
681
- // This is useful to catch "keydown" events after the browser has updated the control.
682
- clearTimeout(this.searchTimeout);
683
-
684
- this.searchTimeout = this.asyncFunction($.proxy(function() {
685
-
686
- if (this.query !== event.target.value) {
687
- this.query = event.target.value;
688
-
689
- $.each($('li', this.$ul), $.proxy(function(index, element) {
690
- var value = $('input', element).val();
691
- var text = $('label', element).text();
692
-
693
- var filterCandidate = '';
694
- if ((this.options.filterBehavior === 'text')) {
695
- filterCandidate = text;
696
- }
697
- else if ((this.options.filterBehavior === 'value')) {
698
- filterCandidate = value;
699
- }
700
- else if (this.options.filterBehavior === 'both') {
701
- filterCandidate = text + '\n' + value;
702
- }
703
-
704
- if (value !== this.options.selectAllValue && text) {
705
- // By default lets assume that element is not
706
- // interesting for this search.
707
- var showElement = false;
708
-
709
- if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) {
710
- showElement = true;
711
- }
712
- else if (filterCandidate.indexOf(this.query) > -1) {
713
- showElement = true;
714
- }
715
-
716
- if (showElement) {
717
- $(element).show().removeClass("filter-hidden");
718
- }
719
- else {
720
- $(element).hide().addClass("filter-hidden");
721
- }
722
- }
723
- }, this));
724
- }
725
-
726
- this.updateSelectAll();
727
- }, this), 300, this);
728
- }, this));
729
- }
730
- }
731
- },
732
-
733
- /**
734
- * Unbinds the whole plugin.
735
- */
736
- destroy: function() {
737
- this.$container.remove();
738
- this.$select.show();
739
- this.$select.data('multiselect', null);
740
- },
741
-
742
- /**
743
- * Refreshs the multiselect based on the selected options of the select.
744
- */
745
- refresh: function() {
746
- $('option', this.$select).each($.proxy(function(index, element) {
747
- var $input = $('li input', this.$ul).filter(function() {
748
- return $(this).val() === $(element).val();
749
- });
750
-
751
- if ($(element).is(':selected')) {
752
- $input.prop('checked', true);
753
-
754
- if (this.options.selectedClass) {
755
- $input.parents('li')
756
- .addClass(this.options.selectedClass);
757
- }
758
- }
759
- else {
760
- $input.prop('checked', false);
761
-
762
- if (this.options.selectedClass) {
763
- $input.parents('li')
764
- .removeClass(this.options.selectedClass);
765
- }
766
- }
767
-
768
- if ($(element).is(":disabled")) {
769
- $input.attr('disabled', 'disabled')
770
- .prop('disabled', true)
771
- .parents('li')
772
- .addClass('disabled');
773
- }
774
- else {
775
- $input.prop('disabled', false)
776
- .parents('li')
777
- .removeClass('disabled');
778
- }
779
- }, this));
780
-
781
- this.updateButtonText();
782
- this.updateSelectAll();
783
- },
784
-
785
- /**
786
- * Select all options of the given values.
787
- *
788
- * If triggerOnChange is set to true, the on change event is triggered if
789
- * and only if one value is passed.
790
- *
791
- * @param {Array} selectValues
792
- * @param {Boolean} triggerOnChange
793
- */
794
- select: function(selectValues, triggerOnChange) {
795
- if(!$.isArray(selectValues)) {
796
- selectValues = [selectValues];
797
- }
798
-
799
- for (var i = 0; i < selectValues.length; i++) {
800
- var value = selectValues[i];
801
-
802
- var $option = this.getOptionByValue(value);
803
- var $checkbox = this.getInputByValue(value);
804
-
805
- if($option === undefined || $checkbox === undefined) {
806
- continue;
807
- }
808
-
809
- if (!this.options.multiple) {
810
- this.deselectAll(false);
811
- }
812
-
813
- if (this.options.selectedClass) {
814
- $checkbox.parents('li')
815
- .addClass(this.options.selectedClass);
816
- }
817
-
818
- $checkbox.prop('checked', true);
819
- $option.prop('selected', true);
820
- }
821
-
822
- this.updateButtonText();
823
-
824
- if (triggerOnChange && selectValues.length === 1) {
825
- this.options.onChange($option, true);
826
- }
827
- },
828
-
829
- /**
830
- * Clears all selected items.
831
- */
832
- clearSelection: function () {
833
- this.deselectAll(false);
834
- this.updateButtonText();
835
- this.updateSelectAll();
836
- },
837
-
838
- /**
839
- * Deselects all options of the given values.
840
- *
841
- * If triggerOnChange is set to true, the on change event is triggered, if
842
- * and only if one value is passed.
843
- *
844
- * @param {Array} deselectValues
845
- * @param {Boolean} triggerOnChange
846
- */
847
- deselect: function(deselectValues, triggerOnChange) {
848
- if(!$.isArray(deselectValues)) {
849
- deselectValues = [deselectValues];
850
- }
851
-
852
- for (var i = 0; i < deselectValues.length; i++) {
853
-
854
- var value = deselectValues[i];
855
-
856
- var $option = this.getOptionByValue(value);
857
- var $checkbox = this.getInputByValue(value);
858
-
859
- if($option === undefined || $checkbox === undefined) {
860
- continue;
861
- }
862
-
863
- if (this.options.selectedClass) {
864
- $checkbox.parents('li')
865
- .removeClass(this.options.selectedClass);
866
- }
867
-
868
- $checkbox.prop('checked', false);
869
- $option.prop('selected', false);
870
- }
871
-
872
- this.updateButtonText();
873
-
874
- if (triggerOnChange && deselectValues.length === 1) {
875
- this.options.onChange($option, false);
876
- }
877
- },
878
-
879
- /**
880
- * Selects all enabled & visible options.
881
- */
882
- selectAll: function () {
883
- var allCheckboxes = $("li input[type='checkbox']:enabled", this.$ul);
884
- var visibleCheckboxes = allCheckboxes.filter(":visible");
885
- var allCheckboxesCount = allCheckboxes.length;
886
- var visibleCheckboxesCount = visibleCheckboxes.length;
887
-
888
- visibleCheckboxes.prop('checked', true);
889
- $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").addClass(this.options.selectedClass);
890
-
891
- if (allCheckboxesCount === visibleCheckboxesCount) {
892
- $("option:enabled", this.$select).prop('selected', true);
893
- }
894
- else {
895
- var values = visibleCheckboxes.map(function() {
896
- return $(this).val();
897
- }).get();
898
-
899
- $("option:enabled", this.$select).filter(function(index) {
900
- return $.inArray($(this).val(), values) !== -1;
901
- }).prop('selected', true);
902
- }
903
- },
904
-
905
- /**
906
- * Deselects all options.
907
- *
908
- * If justVisible is true or not specified, only visible options are deselected.
909
- *
910
- * @param {Boolean} justVisible
911
- */
912
- deselectAll: function (justVisible) {
913
- var justVisible = typeof justVisible === 'undefined' ? true : justVisible;
914
-
915
- if(justVisible) {
916
- var visibleCheckboxes = $("li input[type='checkbox']:enabled", this.$ul).filter(":visible");
917
- visibleCheckboxes.prop('checked', false);
918
-
919
- var values = visibleCheckboxes.map(function() {
920
- return $(this).val();
921
- }).get();
922
-
923
- $("option:enabled", this.$select).filter(function(index) {
924
- return $.inArray($(this).val(), values) !== -1;
925
- }).prop('selected', false);
926
-
927
- if (this.options.selectedClass) {
928
- $("li:not(.divider):not(.disabled)", this.$ul).filter(":visible").removeClass(this.options.selectedClass);
929
- }
930
- }
931
- else {
932
- $("li input[type='checkbox']:enabled", this.$ul).prop('checked', false);
933
- $("option:enabled", this.$select).prop('selected', false);
934
-
935
- if (this.options.selectedClass) {
936
- $("li:not(.divider):not(.disabled)", this.$ul).removeClass(this.options.selectedClass);
937
- }
938
- }
939
- },
940
-
941
- /**
942
- * Rebuild the plugin.
943
- *
944
- * Rebuilds the dropdown, the filter and the select all option.
945
- */
946
- rebuild: function() {
947
- this.$ul.html('');
948
-
949
- // Important to distinguish between radios and checkboxes.
950
- this.options.multiple = this.$select.attr('multiple') === "multiple";
951
-
952
- this.buildSelectAll();
953
- this.buildDropdownOptions();
954
- this.buildFilter();
955
-
956
- this.updateButtonText();
957
- this.updateSelectAll();
958
-
959
- if (this.options.disableIfEmpty) {
960
- this.disableIfEmpty();
961
- }
962
-
963
- if (this.options.dropRight) {
964
- this.$ul.addClass('pull-right');
965
- }
966
- },
967
-
968
- /**
969
- * The provided data will be used to build the dropdown.
970
- *
971
- * @param {Array} dataprovider
972
- */
973
- dataprovider: function(dataprovider) {
974
- var optionDOM = "";
975
- var groupCounter = 0;
976
-
977
- $.each(dataprovider, function (index, option) {
978
- if ($.isArray(option.children)) {
979
- groupCounter++;
980
- optionDOM += '<optgroup label="' + (option.title || 'Group ' + groupCounter) + '">';
981
-
982
- forEach(option.children, function(subOption) {
983
- optionDOM += '<option value="' + subOption.value + '">' + (subOption.label || subOption.value) + '</option>';
984
- });
985
-
986
- optionDOM += '</optgroup>';
987
- }
988
- else {
989
- optionDOM += '<option value="' + option.value + '">' + (option.label || option.value) + '</option>';
990
- }
991
- });
992
-
993
- this.$select.html(optionDOM);
994
- this.rebuild();
995
- },
996
-
997
- /**
998
- * Enable the multiselect.
999
- */
1000
- enable: function() {
1001
- this.$select.prop('disabled', false);
1002
- this.$button.prop('disabled', false)
1003
- .removeClass('disabled');
1004
- },
1005
-
1006
- /**
1007
- * Disable the multiselect.
1008
- */
1009
- disable: function() {
1010
- this.$select.prop('disabled', true);
1011
- this.$button.prop('disabled', true)
1012
- .addClass('disabled');
1013
- },
1014
-
1015
- /**
1016
- * Disable the multiselect if there are no options in the select.
1017
- */
1018
- disableIfEmpty: function () {
1019
- if ($('option', this.$select).length <= 0) {
1020
- this.disable();
1021
- }
1022
- else {
1023
- this.enable();
1024
- }
1025
- },
1026
-
1027
- /**
1028
- * Set the options.
1029
- *
1030
- * @param {Array} options
1031
- */
1032
- setOptions: function(options) {
1033
- this.options = this.mergeOptions(options);
1034
- },
1035
-
1036
- /**
1037
- * Merges the given options with the default options.
1038
- *
1039
- * @param {Array} options
1040
- * @returns {Array}
1041
- */
1042
- mergeOptions: function(options) {
1043
- return $.extend(true, {}, this.defaults, options);
1044
- },
1045
-
1046
- /**
1047
- * Checks whether a select all checkbox is present.
1048
- *
1049
- * @returns {Boolean}
1050
- */
1051
- hasSelectAll: function() {
1052
- return $('li.' + this.options.selectAllValue, this.$ul).length > 0;
1053
- },
1054
-
1055
- /**
1056
- * Updates the select all checkbox based on the currently displayed and selected checkboxes.
1057
- */
1058
- updateSelectAll: function() {
1059
- if (this.hasSelectAll()) {
1060
- var allBoxes = $("li:not(.multiselect-item):not(.filter-hidden) input:enabled", this.$ul);
1061
- var allBoxesLength = allBoxes.length;
1062
- var checkedBoxesLength = allBoxes.filter(":checked").length;
1063
- var selectAllLi = $("li." + this.options.selectAllValue, this.$ul);
1064
- var selectAllInput = selectAllLi.find("input");
1065
-
1066
- if (checkedBoxesLength > 0 && checkedBoxesLength === allBoxesLength) {
1067
- selectAllInput.prop("checked", true);
1068
- selectAllLi.addClass(this.options.selectedClass);
1069
- }
1070
- else {
1071
- selectAllInput.prop("checked", false);
1072
- selectAllLi.removeClass(this.options.selectedClass);
1073
- }
1074
- }
1075
- },
1076
-
1077
- /**
1078
- * Update the button text and its title based on the currently selected options.
1079
- */
1080
- updateButtonText: function() {
1081
- var options = this.getSelected();
1082
-
1083
- // First update the displayed button text.
1084
- $('button.multiselect', this.$container).html(this.options.buttonText(options, this.$select));
1085
-
1086
- // Now update the title attribute of the button.
1087
- $('button.multiselect', this.$container).attr('title', this.options.buttonTitle(options, this.$select));
1088
- },
1089
-
1090
- /**
1091
- * Get all selected options.
1092
- *
1093
- * @returns {jQUery}
1094
- */
1095
- getSelected: function() {
1096
- return $('option', this.$select).filter(":selected");
1097
- },
1098
-
1099
- /**
1100
- * Gets a select option by its value.
1101
- *
1102
- * @param {String} value
1103
- * @returns {jQuery}
1104
- */
1105
- getOptionByValue: function (value) {
1106
-
1107
- var options = $('option', this.$select);
1108
- var valueToCompare = value.toString();
1109
-
1110
- for (var i = 0; i < options.length; i = i + 1) {
1111
- var option = options[i];
1112
- if (option.value === valueToCompare) {
1113
- return $(option);
1114
- }
1115
- }
1116
- },
1117
-
1118
- /**
1119
- * Get the input (radio/checkbox) by its value.
1120
- *
1121
- * @param {String} value
1122
- * @returns {jQuery}
1123
- */
1124
- getInputByValue: function (value) {
1125
-
1126
- var checkboxes = $('li input', this.$ul);
1127
- var valueToCompare = value.toString();
1128
-
1129
- for (var i = 0; i < checkboxes.length; i = i + 1) {
1130
- var checkbox = checkboxes[i];
1131
- if (checkbox.value === valueToCompare) {
1132
- return $(checkbox);
1133
- }
1134
- }
1135
- },
1136
-
1137
- /**
1138
- * Used for knockout integration.
1139
- */
1140
- updateOriginalOptions: function() {
1141
- this.originalOptions = this.$select.clone()[0].options;
1142
- },
1143
-
1144
- asyncFunction: function(callback, timeout, self) {
1145
- var args = Array.prototype.slice.call(arguments, 3);
1146
- return setTimeout(function() {
1147
- callback.apply(self || window, args);
1148
- }, timeout);
1149
- }
1150
- };
1151
-
1152
- $.fn.multiselect = function(option, parameter, extraOptions) {
1153
- return this.each(function() {
1154
- var data = $(this).data('multiselect');
1155
- var options = typeof option === 'object' && option;
1156
-
1157
- // Initialize the multiselect.
1158
- if (!data) {
1159
- data = new Multiselect(this, options);
1160
- $(this).data('multiselect', data);
1161
- }
1162
-
1163
- // Call multiselect method.
1164
- if (typeof option === 'string') {
1165
- data[option](parameter, extraOptions);
1166
-
1167
- if (option === 'destroy') {
1168
- $(this).data('multiselect', false);
1169
- }
1170
- }
1171
- });
1172
- };
1173
-
1174
- $.fn.multiselect.Constructor = Multiselect;
1175
-
1176
- $(function() {
1177
- $("select[data-role=multiselect]").multiselect();
1178
- });
1179
-
1180
- }(window.jQuery);
44
+ var FuzzySet=void function(t,e){void 0===t&&void 0!==window&&(t=window),"function"==typeof define&&define.amd?define(["jquery"],function(t){return e(t)}):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(t.jQuery)}(this,function(t){!function(t){"use strict";function e(e,i){this.$select=t(e),this.options=this.mergeOptions(t.extend({},i,this.$select.data())),this.$select.attr("data-placeholder")&&(this.options.nonSelectedText=this.$select.data("placeholder")),this.originalOptions=this.$select.clone()[0].options,this.query="",this.searchTimeout=null,this.lastToggledInput=null,this.options.multiple="multiple"===this.$select.attr("multiple"),this.options.onChange=t.proxy(this.options.onChange,this),this.options.onSelectAll=t.proxy(this.options.onSelectAll,this),this.options.onDeselectAll=t.proxy(this.options.onDeselectAll,this),this.options.onDropdownShow=t.proxy(this.options.onDropdownShow,this),this.options.onDropdownHide=t.proxy(this.options.onDropdownHide,this),this.options.onDropdownShown=t.proxy(this.options.onDropdownShown,this),this.options.onDropdownHidden=t.proxy(this.options.onDropdownHidden,this),this.options.onInitialized=t.proxy(this.options.onInitialized,this),this.options.onFiltering=t.proxy(this.options.onFiltering,this),this.buildContainer(),this.buildButton(),this.buildDropdown(),this.buildReset(),this.buildSelectAll(),this.buildDropdownOptions(),this.buildFilter(),this.buildButtons(),this.updateButtonText(),this.updateSelectAll(!0),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups(),this.options.wasDisabled=this.$select.prop("disabled"),this.options.disableIfEmpty&&t("option",this.$select).length<=0&&!this.options.wasDisabled&&this.disable(!0),this.$select.wrap('<span class="multiselect-native-select" />').after(this.$container),this.$select.prop("tabindex","-1"),"never"!==this.options.widthSynchronizationMode&&this.synchronizeButtonAndPopupWidth(),this.options.onInitialized(this.$select,this.$container)}"undefined"!=typeof ko&&ko.bindingHandlers&&!ko.bindingHandlers.multiselect&&(ko.bindingHandlers.multiselect={after:["options","value","selectedOptions","enable","disable"],init:function(e,i,s,o,l){var n=t(e),p=ko.toJS(i());if(n.multiselect(p),s.has("options")){var a=s.get("options");ko.isObservable(a)&&ko.computed({read:function(){a(),setTimeout(function(){var t=n.data("multiselect");t&&t.updateOriginalOptions(),n.multiselect("rebuild")},1)},disposeWhenNodeIsRemoved:e})}if(s.has("value")){var r=s.get("value");ko.isObservable(r)&&ko.computed({read:function(){r(),setTimeout(function(){n.multiselect("refresh")},1)},disposeWhenNodeIsRemoved:e}).extend({rateLimit:100,notifyWhenChangesStop:!0})}if(s.has("selectedOptions")){var c=s.get("selectedOptions");ko.isObservable(c)&&ko.computed({read:function(){c(),setTimeout(function(){n.multiselect("refresh")},1)},disposeWhenNodeIsRemoved:e}).extend({rateLimit:100,notifyWhenChangesStop:!0})}var h=function(t){setTimeout(function(){t?n.multiselect("enable"):n.multiselect("disable")})};if(s.has("enable")){var u=s.get("enable");ko.isObservable(u)?ko.computed({read:function(){h(u())},disposeWhenNodeIsRemoved:e}).extend({rateLimit:100,notifyWhenChangesStop:!0}):h(u)}if(s.has("disable")){var d=s.get("disable");ko.isObservable(d)?ko.computed({read:function(){h(!d())},disposeWhenNodeIsRemoved:e}).extend({rateLimit:100,notifyWhenChangesStop:!0}):h(!d)}ko.utils.domNodeDisposal.addDisposeCallback(e,function(){n.multiselect("destroy")})},update:function(e,i,s,o,l){var n=t(e),p=ko.toJS(i());n.multiselect("setOptions",p),n.multiselect("rebuild")}}),e.prototype={defaults:{buttonText:function(e,i){if(this.disabledText.length>0&&i.prop("disabled"))return this.disabledText;if(0===e.length)return this.nonSelectedText;if(this.allSelectedText&&e.length===t("option",t(i)).length&&1!==t("option",t(i)).length&&this.multiple)return this.selectAllNumber?this.allSelectedText+" ("+e.length+")":this.allSelectedText;if(0!=this.numberDisplayed&&e.length>this.numberDisplayed)return e.length+" "+this.nSelectedText;var s="",o=this.delimiterText;return e.each(function(){var e=void 0!==t(this).attr("label")?t(this).attr("label"):t(this).text();s+=e+o}),s.substr(0,s.length-this.delimiterText.length)},buttonTitle:function(e,i){if(0===e.length)return this.nonSelectedText;var s="",o=this.delimiterText;return e.each(function(){var e=void 0!==t(this).attr("label")?t(this).attr("label"):t(this).text();s+=e+o}),s.substr(0,s.length-this.delimiterText.length)},checkboxName:function(t){return!1},optionLabel:function(e){return t(e).attr("label")||t(e).text()},optionClass:function(e){return t(e).attr("class")||""},onChange:function(t,e){},onDropdownShow:function(t){},onDropdownHide:function(t){},onDropdownShown:function(t){},onDropdownHidden:function(t){},onSelectAll:function(){},onDeselectAll:function(){},onInitialized:function(t,e){},onFiltering:function(t){},enableHTML:!1,buttonClass:"form-select",inheritClass:!1,buttonWidth:"auto",buttonContainer:'<div class="btn-group" />',dropRight:!1,dropUp:!1,selectedClass:"active",maxHeight:!1,includeSelectAllOption:!1,includeSelectAllIfMoreThan:0,selectAllText:" Select all",selectAllValue:"multiselect-all",selectAllName:!1,selectAllNumber:!0,selectAllJustVisible:!0,enableFiltering:!1,enableCaseInsensitiveFiltering:!0,enableFullValueFiltering:!1,enableClickableOptGroups:!1,enableCollapsibleOptGroups:!1,collapseOptGroupsByDefault:!1,filterPlaceholder:"Search",filterBehavior:"text",fuzzySearch:!1,includeFilterClearBtn:!0,preventInputChangeEvent:!1,nonSelectedText:"None selected",nSelectedText:"selected",allSelectedText:"All selected",resetButtonText:"Reset",numberDisplayed:3,disableIfEmpty:!1,disabledText:"",delimiterText:", ",includeResetOption:!1,includeResetDivider:!1,resetText:"Reset",indentGroupOptions:!0,widthSynchronizationMode:"never",buttonTextAlignment:"center",enableResetButton:!1,templates:{button:'<button type="button" class="multiselect dropdown-toggle form-select" data-bs-toggle="dropdown"><span class="multiselect-selected-text"></span></button>',popupContainer:'<div class="multiselect-container dropdown-menu"></div>',filter:'<div class="multiselect-filter d-flex align-items-center"><i class="fas fa-sm fa-search text-muted"></i><input type="search" class="multiselect-search form-control" /></div>',buttonGroup:'<div class="multiselect-buttons btn-group" style="display:flex;"></div>',buttonGroupReset:'<button type="button" class="multiselect-reset btn btn-secondary btn-block"></button>',option:'<button type="button" class="multiselect-option dropdown-item"></button>',divider:'<div class="dropdown-divider"></div>',optionGroup:'<button type="button" class="multiselect-group dropdown-item"></button>',resetButton:'<div class="multiselect-reset text-center p-2"><button type="button" class="btn btn-sm btn-block btn-outline-secondary"></button></div>'}},constructor:e,buildContainer:function(){this.$container=t(this.options.buttonContainer),"never"!==this.options.widthSynchronizationMode?this.$container.on("show.bs.dropdown",t.proxy(function(){this.synchronizeButtonAndPopupWidth(),this.options.onDropdownShow()},this)):this.$container.on("show.bs.dropdown",this.options.onDropdownShow),this.$container.on("hide.bs.dropdown",this.options.onDropdownHide),this.$container.on("shown.bs.dropdown",this.options.onDropdownShown),this.$container.on("hidden.bs.dropdown",this.options.onDropdownHidden)},buildButton:function(){if(this.$button=t(this.options.templates.button).addClass(this.options.buttonClass),this.$select.attr("class")&&this.options.inheritClass&&this.$button.addClass(this.$select.attr("class")),this.$select.prop("disabled")?this.disable():this.enable(),this.options.buttonWidth&&"auto"!==this.options.buttonWidth&&(this.$button.css({width:"100%"}),this.$container.css({width:this.options.buttonWidth})),this.options.buttonTextAlignment)switch(this.options.buttonTextAlignment){case"left":this.$button.addClass("text-left");break;case"center":this.$button.addClass("text-center");break;case"right":this.$button.addClass("text-right")}var e=this.$select.attr("tabindex");e&&this.$button.attr("tabindex",e),this.$container.prepend(this.$button)},buildDropdown:function(){this.$popupContainer=t(this.options.templates.popupContainer),this.options.dropRight?this.$container.addClass("dropright"):this.options.dropUp&&this.$container.addClass("dropup"),this.options.maxHeight&&this.$popupContainer.css({"max-height":this.options.maxHeight+"px","overflow-y":"auto","overflow-x":"hidden"}),"never"!==this.options.widthSynchronizationMode&&this.$popupContainer.css("overflow-x","hidden"),this.$popupContainer.on("touchstart click",function(t){t.stopPropagation()}),this.$container.append(this.$popupContainer)},synchronizeButtonAndPopupWidth:function(){if(this.$popupContainer&&"never"!==this.options.widthSynchronizationMode){var t=this.$button.outerWidth();switch(this.options.widthSynchronizationMode){case"always":this.$popupContainer.css("min-width",t),this.$popupContainer.css("max-width",t);break;case"ifPopupIsSmaller":this.$popupContainer.css("min-width",t);break;case"ifPopupIsWider":this.$popupContainer.css("max-width",t)}}},buildDropdownOptions:function(){this.$select.children().each(t.proxy(function(e,i){var s=t(i),o=s.prop("tagName").toLowerCase();s.prop("value")!==this.options.selectAllValue&&("optgroup"===o?this.createOptgroup(i):"option"===o&&("divider"===s.data("role")?this.createDivider():this.createOptionValue(i,!1)))},this)),t(this.$popupContainer).off("change",'> *:not(.multiselect-group) input[type="checkbox"], > *:not(.multiselect-group) input[type="radio"]'),t(this.$popupContainer).on("change",'> *:not(.multiselect-group) input[type="checkbox"], > *:not(.multiselect-group) input[type="radio"]',t.proxy(function(e){var i=t(e.target),s=i.prop("checked")||!1,o=i.val()===this.options.selectAllValue;this.options.selectedClass&&(s?i.closest(".multiselect-option").addClass(this.options.selectedClass):i.closest(".multiselect-option").removeClass(this.options.selectedClass));var l=i.val(),n=this.getOptionByValue(l),p=t("option",this.$select).not(n),a=t("input",this.$container).not(i);if(o?s?this.selectAll(this.options.selectAllJustVisible,!0):this.deselectAll(this.options.selectAllJustVisible,!0):(s?(n.prop("selected",!0),this.options.multiple?n.prop("selected",!0):(this.options.selectedClass&&t(a).closest(".dropdown-item").removeClass(this.options.selectedClass),t(a).prop("checked",!1),p.prop("selected",!1),this.$button.click()),"active"===this.options.selectedClass&&p.closest(".dropdown-item").css("outline","")):n.prop("selected",!1),this.options.onChange(n,s),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()),this.$select.change(),this.updateButtonText(),this.options.preventInputChangeEvent)return!1},this)),t(".multiselect-option",this.$popupContainer).off("mousedown"),t(".multiselect-option",this.$popupContainer).on("mousedown",function(t){if(t.shiftKey)return!1}),t(this.$popupContainer).off("touchstart click",".multiselect-option, .multiselect-all, .multiselect-group"),t(this.$popupContainer).on("touchstart click",".multiselect-option, .multiselect-all, .multiselect-group",t.proxy(function(e){e.stopPropagation();var i=t(e.target);if(e.shiftKey&&this.options.multiple){i.is("input")||(e.preventDefault(),(i=i.closest(".multiselect-option").find("input")).prop("checked",!i.prop("checked")));var s=i.prop("checked")||!1;if(null!==this.lastToggledInput&&this.lastToggledInput!==i){var o=this.$popupContainer.find(".multiselect-option:visible").index(i.closest(".multiselect-option")),l=this.$popupContainer.find(".multiselect-option:visible").index(this.lastToggledInput.closest(".multiselect-option"));if(o>l){var n=l;l=o,o=n}++l;var p=this.$popupContainer.find(".multiselect-option:not(.multiselect-filter-hidden)").slice(o,l).find("input");p.prop("checked",s),this.options.selectedClass&&p.closest(".multiselect-option").toggleClass(this.options.selectedClass,s);for(var a=0,r=p.length;a<r;a++){var c=t(p[a]);this.getOptionByValue(c.val()).prop("selected",s)}}i.trigger("change")}else if(!i.is("input")){var c=i.closest(".multiselect-option, .multiselect-all").find(".form-check-input");if(c.length>0)(this.options.multiple||!c.prop("checked"))&&(c.prop("checked",!c.prop("checked")),c.change());else if(this.options.enableClickableOptGroups&&this.options.multiple&&!i.hasClass("caret-container")){var h=i;h.hasClass("multiselect-group")||(h=i.closest(".multiselect-group")),(c=h.find(".form-check-input")).length>0&&(c.prop("checked",!c.prop("checked")),c.change())}e.preventDefault()}i.closest(".multiselect-option").find("input[type='checkbox'], input[type='radio']").length>0?this.lastToggledInput=i:this.lastToggledInput=null,i.blur()},this)),this.$container.off("keydown.multiselect").on("keydown.multiselect",t.proxy(function(e){var i=t(this.$container).find(".multiselect-option:not(.disabled), .multiselect-group:not(.disabled), .multiselect-all").filter(":visible"),s=i.index(i.filter(":focus")),o=t(".multiselect-search",this.$container);if(9===e.keyCode&&this.$container.hasClass("show"))this.$button.click();else if(13==e.keyCode){var l=i.eq(s);setTimeout(function(){l.focus()},1)}else if(38==e.keyCode)0!=s||o.is(":focus")||setTimeout(function(){o.focus()},1);else if(40==e.keyCode){if(o.is(":focus")){var n=i.eq(0);setTimeout(function(){o.blur(),n.focus()},1)}else -1==s&&setTimeout(function(){o.focus()},1)}},this)),this.options.enableClickableOptGroups&&this.options.multiple&&(t(".multiselect-group input",this.$popupContainer).off("change"),t(".multiselect-group input",this.$popupContainer).on("change",t.proxy(function(e){e.stopPropagation();var i=t(e.target).prop("checked")||!1,s=t(e.target).closest(".dropdown-item"),o=s.nextUntil(".multiselect-group").not(".multiselect-filter-hidden").not(".disabled").find("input"),l=[];this.options.selectedClass&&(i?s.addClass(this.options.selectedClass):s.removeClass(this.options.selectedClass)),t.each(o,t.proxy(function(e,s){var o=t(s),n=o.val(),p=this.getOptionByValue(n);i?(o.prop("checked",!0),o.closest(".dropdown-item").addClass(this.options.selectedClass),p.prop("selected",!0)):(o.prop("checked",!1),o.closest(".dropdown-item").removeClass(this.options.selectedClass),p.prop("selected",!1)),l.push(this.getOptionByValue(n))},this)),this.options.onChange(l,i),this.$select.change(),this.updateButtonText(),this.updateSelectAll()},this))),this.options.enableCollapsibleOptGroups&&this.options.multiple&&(t(".multiselect-group .caret-container",this.$popupContainer).off("click"),t(".multiselect-group .caret-container",this.$popupContainer).on("click",t.proxy(function(e){var i=t(e.target).closest(".multiselect-group").nextUntil(".multiselect-group").not(".multiselect-filter-hidden"),s=!0;i.each(function(){s=s&&!t(this).hasClass("multiselect-collapsible-hidden")}),s?i.hide().addClass("multiselect-collapsible-hidden"):i.show().removeClass("multiselect-collapsible-hidden")},this)))},createCheckbox:function(e,i,s,o,l,n){var p=t("<span />");if(p.addClass("form-check"),this.options.enableHTML&&t(i).length>0){var a=t('<label class="form-check-label" />');a.html(i),p.append(a)}else{var a=t('<label class="form-check-label"/>');a.text(i),p.append(a)}var r=t('<input class="form-check-input"/>').attr("type",n);return r.val(o),p.prepend(r),s&&r.attr("name",s),e.prepend(p),e.attr("title",l||i),r},createOptionValue:function(e,i){var s=t(e);s.is(":selected")&&s.prop("selected",!0);var o=this.options.optionLabel(e),l=this.options.optionClass(e),n=s.val(),p=this.options.multiple?"checkbox":"radio",a=s.attr("title"),r=t(this.options.templates.option);r.addClass(l),i&&this.options.indentGroupOptions&&r.addClass("multiselect-group-option-indented"),this.options.collapseOptGroupsByDefault&&"optgroup"===t(e).parent().prop("tagName").toLowerCase()&&(r.addClass("multiselect-collapsible-hidden"),r.hide());var c=this.options.checkboxName(s),h=this.createCheckbox(r,o,c,n,a,p),u=s.prop("selected")||!1;n===this.options.selectAllValue&&(r.addClass("multiselect-all"),r.removeClass("multiselect-option"),h.parent().parent().addClass("multiselect-all")),this.$popupContainer.append(r),s.is(":disabled")&&h.attr("disabled","disabled").prop("disabled",!0).closest(".dropdown-item").addClass("disabled"),h.prop("checked",u),u&&this.options.selectedClass&&h.closest(".dropdown-item").addClass(this.options.selectedClass)},createDivider:function(e){var i=t(this.options.templates.divider);this.$popupContainer.append(i)},createOptgroup:function(e){var i=t(e),s=i.attr("label"),o=i.attr("value"),l=i.attr("title"),n=t("<span class='multiselect-group dropdown-item-text'></span>");this.options.enableClickableOptGroups&&this.options.multiple?(n=t(this.options.templates.optionGroup),this.createCheckbox(n,s,null,o,l,"checkbox")):this.options.enableHTML?n.html(" "+s):n.text(" "+s);var p=this.options.optionClass(e);n.addClass(p),this.options.enableCollapsibleOptGroups&&this.options.multiple&&(n.find(".form-check").addClass("d-inline-block"),n.append('<span class="caret-container dropdown-toggle pl-1"></span>')),i.is(":disabled")&&n.addClass("disabled"),this.$popupContainer.append(n),t("option",e).each(t.proxy(function(t,e){this.createOptionValue(e,!0)},this))},buildReset:function(){if(this.options.includeResetOption){if(this.options.includeResetDivider){var e=t(this.options.templates.divider);e.addClass("mt-0"),this.$popupContainer.prepend(e)}var i=t(this.options.templates.resetButton);this.options.enableHTML?t("button",i).html(this.options.resetText):t("button",i).text(this.options.resetText),t("button",i).click(t.proxy(function(){this.clearSelection()},this)),this.$popupContainer.prepend(i)}},buildSelectAll:function(){if("number"==typeof this.options.selectAllValue&&(this.options.selectAllValue=this.options.selectAllValue.toString()),!this.hasSelectAll()&&this.options.includeSelectAllOption&&this.options.multiple&&t("option",this.$select).length>this.options.includeSelectAllIfMoreThan){this.options.includeSelectAllDivider&&this.$popupContainer.prepend(t(this.options.templates.divider));var e=t(this.options.templates.li||this.options.templates.option),i=this.createCheckbox(e,this.options.selectAllText,this.options.selectAllName,this.options.selectAllValue,this.options.selectAllText,"checkbox");e.addClass("multiselect-all"),e.removeClass("multiselect-option"),e.find(".form-check-label").addClass("font-weight-bold"),this.$popupContainer.prepend(e),i.prop("checked",!1)}},buildFilter:function(){if(this.options.enableFiltering||this.options.enableCaseInsensitiveFiltering){var e=Math.max(this.options.enableFiltering,this.options.enableCaseInsensitiveFiltering);this.$select.find("option").length>=e&&(this.$filter=t(this.options.templates.filter),t("input",this.$filter).attr("placeholder",this.options.filterPlaceholder),this.options.includeFilterClearBtn?(this.isFirefox()&&0===this.$filter.find(".multiselect-clear-filter").length&&this.$filter.append("<i class='fas fa-times text-muted multiselect-clear-filter multiselect-moz-clear-filter'></i>"),this.$filter.find(".multiselect-clear-filter").on("click",t.proxy(function(e){clearTimeout(this.searchTimeout),this.query="",this.$filter.find(".multiselect-search").val(""),t(".dropdown-item",this.$popupContainer).show().removeClass("multiselect-filter-hidden"),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()},this))):(this.$filter.find(".multiselect-search").attr("type","text"),this.$filter.find(".multiselect-clear-filter").remove()),this.$popupContainer.prepend(this.$filter),this.$filter.val(this.query).on("click",function(t){t.stopPropagation()}).on("input keydown",t.proxy(function(e){13===e.which&&e.preventDefault(),this.isFirefox()&&this.options.includeFilterClearBtn&&(e.target.value?this.$filter.find(".multiselect-moz-clear-filter").show():this.$filter.find(".multiselect-moz-clear-filter").hide()),clearTimeout(this.searchTimeout),this.searchTimeout=this.asyncFunction(t.proxy(function(){if(this.query!==e.target.value){var i,s;this.query=e.target.value,t.each(t(".multiselect-option, .multiselect-group",this.$popupContainer),t.proxy(function(e,o){var l=t("input",o).length>0?t("input",o).val():"",n=t(o).attr("title");t(o).find("span label").html(n);var p="";if("text"===this.options.filterBehavior?p=n:"value"===this.options.filterBehavior?p=l:"both"===this.options.filterBehavior&&(p=n+"\n"+l),l!==this.options.selectAllValue&&n){var a=!1;if(this.options.enableCaseInsensitiveFiltering&&(p=p.toLowerCase(),this.query=this.query.toLowerCase()),this.options.enableFullValueFiltering&&"both"!==this.options.filterBehavior){var r=p.trim().substring(0,this.query.length);this.query.indexOf(r)>-1&&(a=!0)}else if(!this.options.fuzzySearch&&p.indexOf(this.query)>-1)a=!0;else if(this.options.fuzzySearch){let c=t(o).find("span label");if(""==this.query)c.html(p),t(o).css("order",""),a=!0;else{let h=fuzzysort.single(this.query,p,{thresthold:1e3});null!=h&&(t(o).css("order",-h.score),c.html(fuzzysort.highlight(h)),a=!0)}}a||(t(o).css("display","none"),t(o).addClass("multiselect-filter-hidden")),a&&(t(o).css("display","block"),t(o).removeClass("multiselect-filter-hidden")),t(o).hasClass("multiselect-group")?(i=o,s=a):(a&&t(i).show().removeClass("multiselect-filter-hidden"),!a&&s&&t(o).show().removeClass("multiselect-filter-hidden"))}},this))}this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups(),this.updatePopupPosition(),this.options.onFiltering(e.target)},this),300,this)},this)))}},buildButtons:function(){if(this.options.enableResetButton){var e=t(this.options.templates.buttonGroup);this.$buttonGroupReset=t(this.options.templates.buttonGroupReset).text(this.options.resetButtonText),e.append(this.$buttonGroupReset),this.$popupContainer.prepend(e),this.defaultSelection={},t("option",this.$select).each(t.proxy(function(e,i){var s=t(i);this.defaultSelection[s.val()]=s.prop("selected")},this)),this.$buttonGroupReset.on("click",t.proxy(function(e){t("option",this.$select).each(t.proxy(function(e,i){var s=t(i);s.prop("selected",this.defaultSelection[s.val()])},this)),this.refresh(),this.options.enableFiltering&&(this.$filter.trigger("keydown"),t("input",this.$filter).val(""))},this))}},updatePopupPosition:function(){var t=this.$popupContainer.css("transform"),e=t.substring(0,t.indexOf("(")),i=t.substring(t.indexOf("(")+1,t.length-1).split(","),s=5;"matrix3d"===e&&(s=13);var o=i[s];(o=void 0===o?0:o.trim())<0&&(o=-1*this.$popupContainer.css("height").replace("px",""),i[s]=o,t=e+"("+i.join(",")+")",this.$popupContainer.css("transform",t))},destroy:function(){this.$container.remove(),this.$select.unwrap(),this.$select.show(),this.$select.prop("disabled",this.options.wasDisabled),this.$select.data("multiselect",null)},refresh:function(){var e={};t(".multiselect-option input",this.$popupContainer).each(function(){e[t(this).val()]=t(this)}),t("option",this.$select).each(t.proxy(function(i,s){var o=t(s),l=e[t(s).val()];o.is(":selected")?(l.prop("checked",!0),this.options.selectedClass&&l.closest(".multiselect-option").addClass(this.options.selectedClass)):(l.prop("checked",!1),this.options.selectedClass&&l.closest(".multiselect-option").removeClass(this.options.selectedClass)),o.is(":disabled")?l.attr("disabled","disabled").prop("disabled",!0).closest(".multiselect-option").addClass("disabled"):l.prop("disabled",!1).closest(".multiselect-option").removeClass("disabled")},this)),this.updateButtonText(),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()},select:function(e,i){t.isArray(e)||(e=[e]);for(var s=0;s<e.length;s++){var o=e[s];if(null!=o){var l=this.getOptionByValue(o),n=this.getInputByValue(o);if(void 0!==l&&void 0!==n){if(this.options.selectedClass&&n.closest(".dropdown-item").addClass(this.options.selectedClass),n.prop("checked",!0),l.prop("selected",!0),!this.options.multiple){var p=t("input",this.$container).not(n);t(p).prop("checked",!1),t(p).closest(".multiselect-option").removeClass("active"),t("option",this.$select).not(l).prop("selected",!1)}i&&this.options.onChange(l,!0)}}}this.updateButtonText(),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()},clearSelection:function(){this.deselectAll(!1),this.updateButtonText(),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()},deselect:function(e,i){if(this.options.multiple){t.isArray(e)||(e=[e]);for(var s=0;s<e.length;s++){var o=e[s];if(null!=o){var l=this.getOptionByValue(o),n=this.getInputByValue(o);void 0!==l&&void 0!==n&&(this.options.selectedClass&&n.closest(".dropdown-item").removeClass(this.options.selectedClass),n.prop("checked",!1),l.prop("selected",!1),i&&this.options.onChange(l,!1))}}this.updateButtonText(),this.updateSelectAll(),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups()}},selectAll:function(e,i){if(this.options.multiple){var s=[],e=void 0===e||e;if(e){var o=t(".multiselect-option:not(.disabled):not(.multiselect-filter-hidden)",this.$popupContainer);t("input:enabled",o).prop("checked",!0),o.addClass(this.options.selectedClass),t("input:enabled",o).each(t.proxy(function(e,i){var o=t(i).val(),l=this.getOptionByValue(o);t(l).prop("selected")||s.push(l),t(l).prop("selected",!0)},this))}else{var l=t(".multiselect-option:not(.disabled)",this.$popupContainer);t("input:enabled",l).prop("checked",!0),l.addClass(this.options.selectedClass),t("input:enabled",l).each(t.proxy(function(e,i){var o=t(i).val(),l=this.getOptionByValue(o);t(l).prop("selected")||s.push(l),t(l).prop("selected",!0)},this))}t('.multiselect-option input[value="'+this.options.selectAllValue+'"]',this.$popupContainer).prop("checked",!0),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups(),this.updateButtonText(),this.updateSelectAll(),i&&this.options.onSelectAll(s)}},deselectAll:function(e,i){if(this.options.multiple){var s=[],e=void 0===e||e;if(e){var o=t(".multiselect-option:not(.disabled):not(.multiselect-filter-hidden)",this.$popupContainer);t('input[type="checkbox"]:enabled',o).prop("checked",!1),o.removeClass(this.options.selectedClass),t('input[type="checkbox"]:enabled',o).each(t.proxy(function(e,i){var o=t(i).val(),l=this.getOptionByValue(o);t(l).prop("selected")&&s.push(l),t(l).prop("selected",!1)},this))}else{var l=t(".multiselect-option:not(.disabled):not(.multiselect-group)",this.$popupContainer);t('input[type="checkbox"]:enabled',l).prop("checked",!1),l.removeClass(this.options.selectedClass),t('input[type="checkbox"]:enabled',l).each(t.proxy(function(e,i){var o=t(i).val(),l=this.getOptionByValue(o);t(l).prop("selected")&&s.push(l),t(l).prop("selected",!1)},this))}t('.multiselect-all input[value="'+this.options.selectAllValue+'"]',this.$popupContainer).prop("checked",!1),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups(),this.updateButtonText(),this.updateSelectAll(),i&&this.options.onDeselectAll(s)}},rebuild:function(){this.$popupContainer.html(""),this.options.multiple="multiple"===this.$select.attr("multiple"),this.buildSelectAll(),this.buildDropdownOptions(),this.buildFilter(),this.buildButtons(),this.updateButtonText(),this.updateSelectAll(!0),this.options.enableClickableOptGroups&&this.options.multiple&&this.updateOptGroups(),this.options.disableIfEmpty&&(t("option",this.$select).length<=0?this.$select.prop("disabled")||this.disable(!0):this.$select.data("disabled-by-option")&&this.enable()),this.options.dropRight?this.$container.addClass("dropright"):this.options.dropUp&&this.$container.addClass("dropup"),"never"!==this.options.widthSynchronizationMode&&this.synchronizeButtonAndPopupWidth()},dataprovider:function(e){var i=0,s=this.$select.empty();t.each(e,function(e,o){var l;if(t.isArray(o.children))i++,l=t("<optgroup/>").attr({label:o.label||"Group "+i,disabled:!!o.disabled,value:o.value}),function t(e,i){for(var s=0;s<e.length;++s)i(e[s],s)}(o.children,function(e){var i={value:e.value,label:e.label||e.value,title:e.title,selected:!!e.selected,disabled:!!e.disabled};for(var s in e.attributes)i["data-"+s]=e.attributes[s];l.append(t("<option/>").attr(i))});else{var n={value:o.value,label:o.label||o.value,title:o.title,class:o.class,selected:!!o.selected,disabled:!!o.disabled};for(var p in o.attributes)n["data-"+p]=o.attributes[p];(l=t("<option/>").attr(n)).text(o.label||o.value)}s.append(l)}),this.rebuild()},enable:function(){this.$select.prop("disabled",!1),this.$button.prop("disabled",!1).removeClass("disabled"),this.updateButtonText()},disable:function(t){this.$select.prop("disabled",!0),this.$button.prop("disabled",!0).addClass("disabled"),t?this.$select.data("disabled-by-option",!0):this.$select.data("disabled-by-option",null),this.updateButtonText()},setOptions:function(t){this.options=this.mergeOptions(t)},mergeOptions:function(e){return t.extend(!0,{},this.defaults,this.options,e)},hasSelectAll:function(){return t(".multiselect-all",this.$popupContainer).length>0},updateOptGroups:function(){var e=t(".multiselect-group",this.$popupContainer),i=this.options.selectedClass;e.each(function(){var e=t(this).nextUntil(".multiselect-group").not(".multiselect-filter-hidden").not(".disabled"),s=!0;e.each(function(){t("input",this).prop("checked")||(s=!1)}),i&&(s?t(this).addClass(i):t(this).removeClass(i)),t("input",this).prop("checked",s)})},updateSelectAll:function(e){if(this.hasSelectAll()){var i=t(".multiselect-option:not(.multiselect-filter-hidden):not(.multiselect-group):not(.disabled) input:enabled",this.$popupContainer),s=i.length,o=i.filter(":checked").length,l=t(".multiselect-all",this.$popupContainer),n=l.find("input");o>0&&o===s?(n.prop("checked",!0),l.addClass(this.options.selectedClass)):(n.prop("checked",!1),l.removeClass(this.options.selectedClass))}},updateButtonText:function(){var e=this.getSelected();this.options.enableHTML?t(".multiselect .multiselect-selected-text",this.$container).html(this.options.buttonText(e,this.$select)):t(".multiselect .multiselect-selected-text",this.$container).text(this.options.buttonText(e,this.$select)),t(".multiselect",this.$container).attr("title",this.options.buttonTitle(e,this.$select)),this.$button.trigger("change")},getSelected:function(){return t("option",this.$select).filter(":selected")},getOptionByValue:function(e){for(var i=t("option",this.$select),s=e.toString(),o=0;o<i.length;o+=1){var l=i[o];if(l.value===s)return t(l)}},getInputByValue:function(e){for(var i=t(".multiselect-option input:not(.multiselect-search)",this.$popupContainer),s=e.toString(),o=0;o<i.length;o+=1){var l=i[o];if(l.value===s)return t(l)}},updateOriginalOptions:function(){this.originalOptions=this.$select.clone()[0].options},asyncFunction:function(t,e,i){var s=Array.prototype.slice.call(arguments,3);return setTimeout(function(){t.apply(i||window,s)},e)},setAllSelectedText:function(t){this.options.allSelectedText=t,this.updateButtonText()},isFirefox:function(){return!!navigator&&!!navigator.userAgent&&navigator.userAgent.toLocaleLowerCase().indexOf("firefox")>-1}},t.fn.multiselect=function(i,s,o){return this.each(function(){var l=t(this).data("multiselect");l||(l=new e(this,"object"==typeof i&&i),t(this).data("multiselect",l)),"string"==typeof i&&(l[i](s,o),"destroy"===i&&t(this).data("multiselect",!1))})},t.fn.multiselect.Constructor=e,t(function(){t("select[data-role=multiselect]").multiselect()})}(t)});