tom-select-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tom-select-rails/version.rb +1 -1
  3. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js +168 -84
  4. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.complete.js.map +1 -1
  5. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js +132 -59
  6. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.js.map +1 -1
  7. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js +140 -65
  8. data/vendor/assets/javascripts/tom-select-rails/cjs/tom-select.popular.js.map +1 -1
  9. data/vendor/assets/javascripts/tom-select-rails/cjs/utils.js +1 -1
  10. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js +3 -3
  11. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/caret_position/plugin.js.map +1 -1
  12. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/change_listener/plugin.js +1 -1
  13. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js +9 -7
  14. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/checkbox_options/plugin.js.map +1 -1
  15. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js +3 -3
  16. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/clear_button/plugin.js.map +1 -1
  17. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/drag_drop/plugin.js +1 -1
  18. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js +3 -3
  19. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_header/plugin.js.map +1 -1
  20. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js +6 -4
  21. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/dropdown_input/plugin.js.map +1 -1
  22. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js +3 -7
  23. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/input_autogrow/plugin.js.map +1 -1
  24. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_active_items/plugin.js +1 -1
  25. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/no_backspace_delete/plugin.js +1 -1
  26. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js +4 -3
  27. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/optgroup_columns/plugin.js.map +1 -1
  28. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js +8 -8
  29. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/remove_button/plugin.js.map +1 -1
  30. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/restore_on_backspace/plugin.js +1 -1
  31. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js +22 -12
  32. data/vendor/assets/javascripts/tom-select-rails/esm/plugins/virtual_scroll/plugin.js.map +1 -1
  33. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js +168 -84
  34. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.complete.js.map +1 -1
  35. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js +132 -59
  36. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.js.map +1 -1
  37. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js +140 -65
  38. data/vendor/assets/javascripts/tom-select-rails/esm/tom-select.popular.js.map +1 -1
  39. data/vendor/assets/javascripts/tom-select-rails/esm/utils.js +1 -1
  40. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js +3 -3
  41. data/vendor/assets/javascripts/tom-select-rails/js/plugins/caret_position.js.map +1 -1
  42. data/vendor/assets/javascripts/tom-select-rails/js/plugins/change_listener.js +1 -1
  43. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js +9 -7
  44. data/vendor/assets/javascripts/tom-select-rails/js/plugins/checkbox_options.js.map +1 -1
  45. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js +3 -3
  46. data/vendor/assets/javascripts/tom-select-rails/js/plugins/clear_button.js.map +1 -1
  47. data/vendor/assets/javascripts/tom-select-rails/js/plugins/drag_drop.js +1 -1
  48. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js +3 -3
  49. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_header.js.map +1 -1
  50. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js +6 -4
  51. data/vendor/assets/javascripts/tom-select-rails/js/plugins/dropdown_input.js.map +1 -1
  52. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js +3 -7
  53. data/vendor/assets/javascripts/tom-select-rails/js/plugins/input_autogrow.js.map +1 -1
  54. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_active_items.js +1 -1
  55. data/vendor/assets/javascripts/tom-select-rails/js/plugins/no_backspace_delete.js +1 -1
  56. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js +4 -3
  57. data/vendor/assets/javascripts/tom-select-rails/js/plugins/optgroup_columns.js.map +1 -1
  58. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js +8 -8
  59. data/vendor/assets/javascripts/tom-select-rails/js/plugins/remove_button.js.map +1 -1
  60. data/vendor/assets/javascripts/tom-select-rails/js/plugins/restore_on_backspace.js +1 -1
  61. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js +22 -12
  62. data/vendor/assets/javascripts/tom-select-rails/js/plugins/virtual_scroll.js.map +1 -1
  63. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js +132 -59
  64. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.js.map +1 -1
  65. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js +142 -142
  66. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.base.min.js.map +1 -1
  67. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js +168 -84
  68. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.js.map +1 -1
  69. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js +157 -156
  70. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.complete.min.js.map +1 -1
  71. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js +140 -65
  72. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.js.map +1 -1
  73. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js +142 -143
  74. data/vendor/assets/javascripts/tom-select-rails/js/tom-select.popular.min.js.map +1 -1
  75. data/vendor/assets/javascripts/tom-select-rails/types/tom-select.d.ts +20 -3
  76. data/vendor/assets/javascripts/tom-select-rails/types/types/core.d.ts +2 -1
  77. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css +3 -7
  78. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.css.map +1 -1
  79. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css +1 -1
  80. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap4.min.css.map +1 -1
  81. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css +3 -7
  82. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.css.map +1 -1
  83. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css +1 -1
  84. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.bootstrap5.min.css.map +1 -1
  85. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css +7 -11
  86. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.css.map +1 -1
  87. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css +3 -7
  88. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.css.map +1 -1
  89. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css +1 -1
  90. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.default.min.css.map +1 -1
  91. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css +1 -1
  92. data/vendor/assets/stylesheets/tom-select-rails/css/tom-select.min.css.map +1 -1
  93. data/vendor/assets/stylesheets/tom-select-rails/scss/_dropdown.scss +0 -2
  94. data/vendor/assets/stylesheets/tom-select-rails/scss/tom-select.scss +4 -4
  95. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 231e3258e61b1031bb0bdc51591296466f00d73c50045af6797026dfc083b41c
4
- data.tar.gz: 81d4cd624faab6229846e51fef1438729a1c9fad6e344f7cabbac7219177c7e4
3
+ metadata.gz: 1b3cc20dc49ea2de80dfdfe939c1b4b32aabf86d74fbd188907b0de731129a87
4
+ data.tar.gz: 7c7e09dfa447bec81857c137f3ba82084a94fc20c44e62bdae1cc5ad8ac44068
5
5
  SHA512:
6
- metadata.gz: 07016fd5c972592fe25603b904e139daa660def15f3ce15599edc39f48dd63570b611f8a15e6862531850169420792b5fcca9fa2b119e5428c9f47d9552e3d99
7
- data.tar.gz: eb42bd93be577d053bbfb018af2ed5d8eb7a09af39cc90ca03fbc8a3dc606fee251aa6ba14df0efa59a064764ec954924682da8984ac59eae0039e8a2efc467f
6
+ metadata.gz: c62aeb791ae593fa5428acd0a0b76587abd77c505b2c34110acbb3be9228b15ce61395e2e214e5da5a136f6d0d401a74c1b479787fc1c91a5b347ff30cc20741
7
+ data.tar.gz: 789659f7b13407003b2b99bf993b37017030278c87da2389455547d14d56c55b126a27f2ecc1177980e7d3a6f12ba77da2f9044ad0d9f707121edfa97fcf9f29
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TomSelect
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tom Select v2.0.3
2
+ * Tom Select v2.1.0
3
3
  * Licensed under the Apache License, Version 2.0 (the "License");
4
4
  */
5
5
 
@@ -189,24 +189,20 @@ function MicroPlugin(Interface) {
189
189
  };
190
190
  }
191
191
 
192
+ // @ts-ignore TS2691 "An import path cannot end with a '.ts' extension"
192
193
  // https://github.com/andrewrk/node-diacritics/blob/master/index.js
193
194
  var latin_pat;
194
195
  const accent_pat = '[\u0300-\u036F\u{b7}\u{2be}]'; // \u{2bc}
195
196
 
196
- const accent_reg = new RegExp(accent_pat, 'g');
197
+ const accent_reg = new RegExp(accent_pat, 'gu');
197
198
  var diacritic_patterns;
198
199
  const latin_convert = {
199
200
  'æ': 'ae',
200
201
  'ⱥ': 'a',
201
202
  'ø': 'o'
202
203
  };
203
- const convert_pat = new RegExp(Object.keys(latin_convert).join('|'), 'g');
204
- /**
205
- * code points generated from toCodePoints();
206
- * removed 65339 to 65345
207
- */
208
-
209
- const code_points = [[67, 67], [160, 160], [192, 438], [452, 652], [961, 961], [1019, 1019], [1083, 1083], [1281, 1289], [1984, 1984], [5095, 5095], [7429, 7441], [7545, 7549], [7680, 7935], [8580, 8580], [9398, 9449], [11360, 11391], [42792, 42793], [42802, 42851], [42873, 42897], [42912, 42922], [64256, 64260], [65313, 65338], [65345, 65370]];
204
+ const convert_pat = new RegExp(Object.keys(latin_convert).join('|'), 'gu');
205
+ const code_points = [[0, 65535]];
210
206
  /**
211
207
  * Remove accents
212
208
  * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703
@@ -225,7 +221,6 @@ const asciifold = str => {
225
221
  *
226
222
  */
227
223
 
228
-
229
224
  const arrayToPattern = (chars, glue = '|') => {
230
225
  if (chars.length == 1) {
231
226
  return chars[0];
@@ -242,6 +237,10 @@ const arrayToPattern = (chars, glue = '|') => {
242
237
 
243
238
  return '(?:' + chars.join(glue) + ')';
244
239
  };
240
+ const escapeToPattern = chars => {
241
+ const escaped = chars.map(diacritic => escape_regex(diacritic));
242
+ return arrayToPattern(escaped);
243
+ };
245
244
  /**
246
245
  * Get all possible combinations of substrings that add up to the given string
247
246
  * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string
@@ -266,7 +265,7 @@ const allSubstrings = input => {
266
265
  *
267
266
  */
268
267
 
269
- const generateDiacritics = () => {
268
+ const generateDiacritics = code_points => {
270
269
  var diacritics = {};
271
270
  code_points.forEach(code_range => {
272
271
  for (let i = code_range[0]; i <= code_range[1]; i++) {
@@ -275,13 +274,22 @@ const generateDiacritics = () => {
275
274
 
276
275
  if (latin == diacritic.toLowerCase()) {
277
276
  continue;
277
+ } // skip when latin is a string longer than 3 characters long
278
+ // bc the resulting regex patterns will be long
279
+ // eg:
280
+ // latin صلى الله عليه وسلم length 18 code point 65018
281
+ // latin جل جلاله length 8 code point 65019
282
+
283
+
284
+ if (latin.length > 3) {
285
+ continue;
278
286
  }
279
287
 
280
288
  if (!(latin in diacritics)) {
281
289
  diacritics[latin] = [latin];
282
290
  }
283
291
 
284
- var patt = new RegExp(arrayToPattern(diacritics[latin]), 'iu');
292
+ var patt = new RegExp(escapeToPattern(diacritics[latin]), 'iu');
285
293
 
286
294
  if (diacritic.match(patt)) {
287
295
  continue;
@@ -289,13 +297,23 @@ const generateDiacritics = () => {
289
297
 
290
298
  diacritics[latin].push(diacritic);
291
299
  }
292
- });
293
- var latin_chars = Object.keys(diacritics); // latin character pattern
300
+ }); // filter out if there's only one character in the list
301
+
302
+ let latin_chars = Object.keys(diacritics);
303
+
304
+ for (let i = 0; i < latin_chars.length; i++) {
305
+ const latin = latin_chars[i];
306
+
307
+ if (diacritics[latin].length < 2) {
308
+ delete diacritics[latin];
309
+ }
310
+ } // latin character pattern
294
311
  // match longer substrings first
295
312
 
296
- latin_chars = latin_chars.sort((a, b) => b.length - a.length);
297
- latin_pat = new RegExp('(' + arrayToPattern(latin_chars) + accent_pat + '*)', 'g'); // build diacritic patterns
298
- // ae needs:
313
+
314
+ latin_chars = Object.keys(diacritics).sort((a, b) => b.length - a.length);
315
+ latin_pat = new RegExp('(' + escapeToPattern(latin_chars) + accent_pat + '*)', 'gu'); // build diacritic patterns
316
+ // ae needs:
299
317
  // (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))
300
318
 
301
319
  var diacritic_patterns = {};
@@ -304,7 +322,7 @@ const generateDiacritics = () => {
304
322
  var pattern = substrings.map(sub_pat => {
305
323
  sub_pat = sub_pat.map(l => {
306
324
  if (diacritics.hasOwnProperty(l)) {
307
- return arrayToPattern(diacritics[l]);
325
+ return escapeToPattern(diacritics[l]);
308
326
  }
309
327
 
310
328
  return l;
@@ -323,27 +341,20 @@ const generateDiacritics = () => {
323
341
 
324
342
  const diacriticRegexPoints = regex => {
325
343
  if (diacritic_patterns === undefined) {
326
- diacritic_patterns = generateDiacritics();
344
+ diacritic_patterns = generateDiacritics(code_points);
327
345
  }
328
346
 
329
347
  const decomposed = regex.normalize('NFKD').toLowerCase();
330
348
  return decomposed.split(latin_pat).map(part => {
331
- if (part == '') {
332
- return '';
333
- } // "ffl" or "ffl"
334
-
335
-
349
+ // "ffl" or "ffl"
336
350
  const no_accent = asciifold(part);
337
351
 
352
+ if (no_accent == '') {
353
+ return '';
354
+ }
355
+
338
356
  if (diacritic_patterns.hasOwnProperty(no_accent)) {
339
357
  return diacritic_patterns[no_accent];
340
- } // 'أهلا' (\u{623}\u{647}\u{644}\u{627}) or 'أهلا' (\u{627}\u{654}\u{647}\u{644}\u{627})
341
-
342
-
343
- const composed_part = part.normalize('NFC');
344
-
345
- if (composed_part != part) {
346
- return arrayToPattern([part, composed_part]);
347
358
  }
348
359
 
349
360
  return part;
@@ -509,10 +520,10 @@ class Sifter {
509
520
  }
510
521
 
511
522
  if (word.length > 0) {
512
- regex = escape_regex(word);
513
-
514
523
  if (this.settings.diacritics) {
515
- regex = diacriticRegexPoints(regex);
524
+ regex = diacriticRegexPoints(word);
525
+ } else {
526
+ regex = escape_regex(word);
516
527
  }
517
528
 
518
529
  if (respect_word_boundaries) regex = "\\b" + regex;
@@ -1528,6 +1539,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1528
1539
  this.isInputHidden = false;
1529
1540
  this.isSetup = false;
1530
1541
  this.ignoreFocus = false;
1542
+ this.ignoreHover = false;
1531
1543
  this.hasOptions = false;
1532
1544
  this.currentResults = void 0;
1533
1545
  this.lastValue = '';
@@ -1726,7 +1738,13 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1726
1738
  settings.load = loadDebounce(settings.load, settings.loadThrottle);
1727
1739
  }
1728
1740
 
1729
- self.control_input.type = input.type; // clicking on an option should select it
1741
+ self.control_input.type = input.type;
1742
+ addEvent(dropdown, 'mouseenter', e => {
1743
+ var target_match = parentMatch(e.target, '[data-selectable]', dropdown);
1744
+ if (target_match) self.onOptionHover(e, target_match);
1745
+ }, {
1746
+ capture: true
1747
+ }); // clicking on an option should select it
1730
1748
 
1731
1749
  addEvent(dropdown, 'click', evt => {
1732
1750
  const option = parentMatch(evt.target, '[data-selectable]');
@@ -1760,7 +1778,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1760
1778
  addEvent(focus_node, 'resize', () => self.positionDropdown(), passive_event);
1761
1779
  addEvent(focus_node, 'blur', e => self.onBlur(e));
1762
1780
  addEvent(focus_node, 'focus', e => self.onFocus(e));
1763
- addEvent(focus_node, 'paste', e => self.onPaste(e));
1781
+ addEvent(control_input, 'paste', e => self.onPaste(e));
1764
1782
 
1765
1783
  const doc_mousedown = evt => {
1766
1784
  // blur if target is outside of this instance
@@ -1787,18 +1805,24 @@ class TomSelect extends MicroPlugin(MicroEvent) {
1787
1805
  }
1788
1806
  };
1789
1807
 
1790
- var win_scroll = () => {
1808
+ const win_scroll = () => {
1791
1809
  if (self.isOpen) {
1792
1810
  self.positionDropdown();
1793
1811
  }
1794
1812
  };
1795
1813
 
1814
+ const win_hover = () => {
1815
+ self.ignoreHover = false;
1816
+ };
1817
+
1796
1818
  addEvent(document, 'mousedown', doc_mousedown);
1797
1819
  addEvent(window, 'scroll', win_scroll, passive_event);
1798
1820
  addEvent(window, 'resize', win_scroll, passive_event);
1821
+ addEvent(window, 'mousemove', win_hover, passive_event);
1799
1822
 
1800
1823
  this._destroy = () => {
1801
1824
  document.removeEventListener('mousedown', doc_mousedown);
1825
+ window.removeEventListener('mousemove', win_hover);
1802
1826
  window.removeEventListener('scroll', win_scroll);
1803
1827
  window.removeEventListener('resize', win_scroll);
1804
1828
  if (label) label.removeEventListener('click', label_click);
@@ -2004,21 +2028,29 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2004
2028
  // input and create Items for each separate value
2005
2029
 
2006
2030
 
2007
- if (self.settings.splitOn) {
2008
- // Wait for pasted text to be recognized in value
2009
- setTimeout(() => {
2010
- var pastedText = self.inputValue();
2031
+ if (!self.settings.splitOn) {
2032
+ return;
2033
+ } // Wait for pasted text to be recognized in value
2011
2034
 
2012
- if (!pastedText.match(self.settings.splitOn)) {
2013
- return;
2014
- }
2015
2035
 
2016
- var splitInput = pastedText.trim().split(self.settings.splitOn);
2017
- iterate(splitInput, piece => {
2036
+ setTimeout(() => {
2037
+ var pastedText = self.inputValue();
2038
+
2039
+ if (!pastedText.match(self.settings.splitOn)) {
2040
+ return;
2041
+ }
2042
+
2043
+ var splitInput = pastedText.trim().split(self.settings.splitOn);
2044
+ iterate(splitInput, piece => {
2045
+ piece = hash_key(piece);
2046
+
2047
+ if (this.options[piece]) {
2048
+ self.addItem(piece);
2049
+ } else {
2018
2050
  self.createItem(piece);
2019
- });
2020
- }, 0);
2021
- }
2051
+ }
2052
+ });
2053
+ }, 0);
2022
2054
  }
2023
2055
  /**
2024
2056
  * Triggered on <input> keypress.
@@ -2050,6 +2082,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2050
2082
 
2051
2083
  onKeyDown(e) {
2052
2084
  var self = this;
2085
+ self.ignoreHover = true;
2053
2086
 
2054
2087
  if (self.isLocked) {
2055
2088
  if (e.keyCode !== KEY_TAB) {
@@ -2110,6 +2143,8 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2110
2143
  self.onOptionSelect(e, self.activeOption);
2111
2144
  preventDefault(e); // if the option_create=null, the dropdown might be closed
2112
2145
  } else if (self.settings.create && self.createItem()) {
2146
+ preventDefault(e); // don't submit form when searching for a value
2147
+ } else if (document.activeElement == self.control_input && self.isOpen) {
2113
2148
  preventDefault(e);
2114
2149
  }
2115
2150
 
@@ -2180,6 +2215,17 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2180
2215
  self.trigger('type', value);
2181
2216
  }
2182
2217
  }
2218
+ /**
2219
+ * Triggered when the user rolls over
2220
+ * an option in the autocomplete dropdown menu.
2221
+ *
2222
+ */
2223
+
2224
+
2225
+ onOptionHover(evt, option) {
2226
+ if (this.ignoreHover) return;
2227
+ this.setActiveOption(option, false);
2228
+ }
2183
2229
  /**
2184
2230
  * Triggered on <input> focus.
2185
2231
  *
@@ -2534,7 +2580,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2534
2580
  */
2535
2581
 
2536
2582
 
2537
- setActiveOption(option) {
2583
+ setActiveOption(option, scroll = true) {
2538
2584
  if (option === this.activeOption) {
2539
2585
  return;
2540
2586
  }
@@ -2549,7 +2595,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
2549
2595
  'aria-selected': 'true'
2550
2596
  });
2551
2597
  addClasses(option, 'active');
2552
- this.scrollToOption(option);
2598
+ if (scroll) this.scrollToOption(option);
2553
2599
  }
2554
2600
  /**
2555
2601
  * Sets the dropdown_content scrollTop to display the option
@@ -3182,13 +3228,14 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3182
3228
  */
3183
3229
 
3184
3230
 
3185
- clearOptions() {
3231
+ clearOptions(filter) {
3232
+ const boundFilter = (filter || this.clearFilter).bind(this);
3186
3233
  this.loadedSearches = {};
3187
3234
  this.userOptions = {};
3188
3235
  this.clearCache();
3189
- var selected = {};
3236
+ const selected = {};
3190
3237
  iterate(this.options, (option, key) => {
3191
- if (this.items.indexOf(key) >= 0) {
3238
+ if (boundFilter(option, key)) {
3192
3239
  selected[key] = this.options[key];
3193
3240
  }
3194
3241
  });
@@ -3196,6 +3243,20 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3196
3243
  this.lastQuery = null;
3197
3244
  this.trigger('option_clear');
3198
3245
  }
3246
+ /**
3247
+ * Used by clearOptions() to decide whether or not an option should be removed
3248
+ * Return true to keep an option, false to remove
3249
+ *
3250
+ */
3251
+
3252
+
3253
+ clearFilter(option, value) {
3254
+ if (this.items.indexOf(value) >= 0) {
3255
+ return true;
3256
+ }
3257
+
3258
+ return false;
3259
+ }
3199
3260
  /**
3200
3261
  * Returns the dom element of the option
3201
3262
  * matching the given value.
@@ -3515,11 +3576,11 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3515
3576
  refreshValidityState() {
3516
3577
  var self = this;
3517
3578
 
3518
- if (!self.input.checkValidity) {
3579
+ if (!self.input.validity) {
3519
3580
  return;
3520
3581
  }
3521
3582
 
3522
- self.isValid = self.input.checkValidity();
3583
+ self.isValid = self.input.validity.valid;
3523
3584
  self.isInvalid = !self.isValid;
3524
3585
  }
3525
3586
  /**
@@ -3746,9 +3807,7 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3746
3807
  }
3747
3808
  }
3748
3809
 
3749
- const values = rm_items.map(item => item.dataset.value); // allow the callback to abort
3750
-
3751
- if (!values.length || typeof self.settings.onDelete === 'function' && self.settings.onDelete.call(self, values, e) === false) {
3810
+ if (!self.shouldDelete(rm_items, e)) {
3752
3811
  return false;
3753
3812
  }
3754
3813
 
@@ -3767,6 +3826,20 @@ class TomSelect extends MicroPlugin(MicroEvent) {
3767
3826
  self.refreshOptions(false);
3768
3827
  return true;
3769
3828
  }
3829
+ /**
3830
+ * Return true if the items should be deleted
3831
+ */
3832
+
3833
+
3834
+ shouldDelete(items, evt) {
3835
+ const values = items.map(item => item.dataset.value); // allow the callback to abort
3836
+
3837
+ if (!values.length || typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false) {
3838
+ return false;
3839
+ }
3840
+
3841
+ return true;
3842
+ }
3770
3843
  /**
3771
3844
  * Selects the previous / next item (depending on the `direction` argument).
3772
3845
  *
@@ -4124,10 +4197,12 @@ function checkbox_options () {
4124
4197
  setTimeout(() => {
4125
4198
  var checkbox = option.querySelector('input');
4126
4199
 
4127
- if (option.classList.contains('selected')) {
4128
- checkbox.checked = true;
4129
- } else {
4130
- checkbox.checked = false;
4200
+ if (checkbox instanceof HTMLInputElement) {
4201
+ if (option.classList.contains('selected')) {
4202
+ checkbox.checked = true;
4203
+ } else {
4204
+ checkbox.checked = false;
4205
+ }
4131
4206
  }
4132
4207
  }, 1);
4133
4208
  }; // add checkbox to option template
@@ -4454,7 +4529,9 @@ function dropdown_input () {
4454
4529
 
4455
4530
  self.hook('before', 'close', () => {
4456
4531
  if (!self.isOpen) return;
4457
- self.focus_node.focus();
4532
+ self.focus_node.focus({
4533
+ preventScroll: true
4534
+ });
4458
4535
  });
4459
4536
  });
4460
4537
  }
@@ -4492,12 +4569,8 @@ function input_autogrow () {
4492
4569
 
4493
4570
 
4494
4571
  var resize = () => {
4495
- if (self.items.length > 0) {
4496
- test_input.textContent = control.value;
4497
- control.style.width = test_input.clientWidth + 'px';
4498
- } else {
4499
- control.style.width = '';
4500
- }
4572
+ test_input.textContent = control.value;
4573
+ control.style.width = test_input.clientWidth + 'px';
4501
4574
  };
4502
4575
 
4503
4576
  resize();
@@ -4576,6 +4649,7 @@ function optgroup_columns () {
4576
4649
  return orig_keydown.call(self, evt);
4577
4650
  }
4578
4651
 
4652
+ self.ignoreHover = true;
4579
4653
  optgroup = parentMatch(self.activeOption, '[data-group]');
4580
4654
  index = nodeIndex(self.activeOption, '[data-selectable]');
4581
4655
 
@@ -4635,9 +4709,9 @@ function remove_button (userOptions) {
4635
4709
  var orig_render_item = self.settings.render.item;
4636
4710
 
4637
4711
  self.settings.render.item = (data, escape) => {
4638
- var rendered = getDom(orig_render_item.call(self, data, escape));
4712
+ var item = getDom(orig_render_item.call(self, data, escape));
4639
4713
  var close_button = getDom(html);
4640
- rendered.appendChild(close_button);
4714
+ item.appendChild(close_button);
4641
4715
  addEvent(close_button, 'mousedown', evt => {
4642
4716
  preventDefault(evt, true);
4643
4717
  });
@@ -4645,12 +4719,12 @@ function remove_button (userOptions) {
4645
4719
  // propagating will trigger the dropdown to show for single mode
4646
4720
  preventDefault(evt, true);
4647
4721
  if (self.isLocked) return;
4648
- var value = rendered.dataset.value;
4649
- self.removeItem(value);
4722
+ if (!self.shouldDelete([item], evt)) return;
4723
+ self.removeItem(item);
4650
4724
  self.refreshOptions(false);
4651
4725
  self.inputState();
4652
4726
  });
4653
- return rendered;
4727
+ return item;
4654
4728
  };
4655
4729
  });
4656
4730
  }
@@ -4714,10 +4788,11 @@ function virtual_scroll () {
4714
4788
  var dropdown_content;
4715
4789
  var loading_more = false;
4716
4790
  var load_more_opt;
4791
+ var default_values = [];
4717
4792
 
4718
4793
  if (!self.settings.shouldLoadMore) {
4719
4794
  // return true if additional results should be loaded
4720
- self.settings.shouldLoadMore = function () {
4795
+ self.settings.shouldLoadMore = () => {
4721
4796
  const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);
4722
4797
 
4723
4798
  if (scroll_percent > 0.9) {
@@ -4749,7 +4824,7 @@ function virtual_scroll () {
4749
4824
  field: '$score'
4750
4825
  }]; // can we load more results for given query?
4751
4826
 
4752
- function canLoadMore(query) {
4827
+ const canLoadMore = query => {
4753
4828
  if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {
4754
4829
  return false;
4755
4830
  }
@@ -4759,15 +4834,23 @@ function virtual_scroll () {
4759
4834
  }
4760
4835
 
4761
4836
  return false;
4762
- } // set the next url that will be
4837
+ };
4838
+
4839
+ const clearFilter = (option, value) => {
4840
+ if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {
4841
+ return true;
4842
+ }
4843
+
4844
+ return false;
4845
+ }; // set the next url that will be
4763
4846
 
4764
4847
 
4765
- self.setNextUrl = function (value, next_url) {
4848
+ self.setNextUrl = (value, next_url) => {
4766
4849
  pagination[value] = next_url;
4767
4850
  }; // getUrl() to be used in settings.load()
4768
4851
 
4769
4852
 
4770
- self.getUrl = function (query) {
4853
+ self.getUrl = query => {
4771
4854
  if (query in pagination) {
4772
4855
  const next_url = pagination[query];
4773
4856
  pagination[query] = false;
@@ -4801,7 +4884,7 @@ function virtual_scroll () {
4801
4884
 
4802
4885
  self.hook('instead', 'loadCallback', (options, optgroups) => {
4803
4886
  if (!loading_more) {
4804
- self.clearOptions();
4887
+ self.clearOptions(clearFilter);
4805
4888
  } else if (load_more_opt && options.length > 0) {
4806
4889
  load_more_opt.dataset.value = options[0][self.settings.valueField];
4807
4890
  }
@@ -4839,18 +4922,19 @@ function virtual_scroll () {
4839
4922
  }); // add scroll listener and default templates
4840
4923
 
4841
4924
  self.on('initialize', () => {
4925
+ default_values = Object.keys(self.options);
4842
4926
  dropdown_content = self.dropdown_content; // default templates
4843
4927
 
4844
4928
  self.settings.render = Object.assign({}, {
4845
- loading_more: function () {
4929
+ loading_more: () => {
4846
4930
  return `<div class="loading-more-results">Loading more results ... </div>`;
4847
4931
  },
4848
- no_more_results: function () {
4932
+ no_more_results: () => {
4849
4933
  return `<div class="no-more-results">No more results</div>`;
4850
4934
  }
4851
4935
  }, self.settings.render); // watch dropdown content scroll position
4852
4936
 
4853
- dropdown_content.addEventListener('scroll', function () {
4937
+ dropdown_content.addEventListener('scroll', () => {
4854
4938
  if (!self.settings.shouldLoadMore.call(self)) {
4855
4939
  return;
4856
4940
  } // !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true