@drecchia/tom-select 2.5.2-virtual-scroll.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +104 -0
- package/dist/css/tom-select.bootstrap4.css +573 -0
- package/dist/css/tom-select.bootstrap5.css +612 -0
- package/dist/css/tom-select.css +405 -0
- package/dist/css/tom-select.default.css +497 -0
- package/dist/css/tom-select.default.css.map +1 -0
- package/dist/esm/plugins/caret_position/plugin.js +163 -0
- package/dist/esm/plugins/caret_position/plugin.js.map +1 -0
- package/dist/esm/plugins/change_listener/plugin.js +51 -0
- package/dist/esm/plugins/change_listener/plugin.js.map +1 -0
- package/dist/esm/plugins/checkbox_options/plugin.js +179 -0
- package/dist/esm/plugins/checkbox_options/plugin.js.map +1 -0
- package/dist/esm/plugins/clear_button/plugin.js +76 -0
- package/dist/esm/plugins/clear_button/plugin.js.map +1 -0
- package/dist/esm/plugins/drag_drop/plugin.js +220 -0
- package/dist/esm/plugins/drag_drop/plugin.js.map +1 -0
- package/dist/esm/plugins/dropdown_header/plugin.js +102 -0
- package/dist/esm/plugins/dropdown_header/plugin.js.map +1 -0
- package/dist/esm/plugins/dropdown_input/plugin.js +224 -0
- package/dist/esm/plugins/dropdown_input/plugin.js.map +1 -0
- package/dist/esm/plugins/input_autogrow/plugin.js +74 -0
- package/dist/esm/plugins/input_autogrow/plugin.js.map +1 -0
- package/dist/esm/plugins/local_virtual_scroll/plugin.js +305 -0
- package/dist/esm/plugins/local_virtual_scroll/plugin.js.map +1 -0
- package/dist/esm/plugins/no_active_items/plugin.js +26 -0
- package/dist/esm/plugins/no_active_items/plugin.js.map +1 -0
- package/dist/esm/plugins/no_backspace_delete/plugin.js +32 -0
- package/dist/esm/plugins/no_backspace_delete/plugin.js.map +1 -0
- package/dist/esm/plugins/optgroup_columns/plugin.js +86 -0
- package/dist/esm/plugins/optgroup_columns/plugin.js.map +1 -0
- package/dist/esm/plugins/remove_button/plugin.js +134 -0
- package/dist/esm/plugins/remove_button/plugin.js.map +1 -0
- package/dist/esm/plugins/restore_on_backspace/plugin.js +42 -0
- package/dist/esm/plugins/restore_on_backspace/plugin.js.map +1 -0
- package/dist/esm/plugins/virtual_scroll/plugin.js +272 -0
- package/dist/esm/plugins/virtual_scroll/plugin.js.map +1 -0
- package/dist/js/plugins/caret_position.js +171 -0
- package/dist/js/plugins/caret_position.js.map +1 -0
- package/dist/js/plugins/change_listener.js +59 -0
- package/dist/js/plugins/change_listener.js.map +1 -0
- package/dist/js/plugins/checkbox_options.js +187 -0
- package/dist/js/plugins/checkbox_options.js.map +1 -0
- package/dist/js/plugins/clear_button.js +84 -0
- package/dist/js/plugins/clear_button.js.map +1 -0
- package/dist/js/plugins/drag_drop.js +228 -0
- package/dist/js/plugins/drag_drop.js.map +1 -0
- package/dist/js/plugins/dropdown_header.js +110 -0
- package/dist/js/plugins/dropdown_header.js.map +1 -0
- package/dist/js/plugins/dropdown_input.js +232 -0
- package/dist/js/plugins/dropdown_input.js.map +1 -0
- package/dist/js/plugins/input_autogrow.js +82 -0
- package/dist/js/plugins/input_autogrow.js.map +1 -0
- package/dist/js/plugins/local_virtual_scroll.js +313 -0
- package/dist/js/plugins/local_virtual_scroll.js.map +1 -0
- package/dist/js/plugins/no_active_items.js +34 -0
- package/dist/js/plugins/no_active_items.js.map +1 -0
- package/dist/js/plugins/no_backspace_delete.js +40 -0
- package/dist/js/plugins/no_backspace_delete.js.map +1 -0
- package/dist/js/plugins/optgroup_columns.js +94 -0
- package/dist/js/plugins/optgroup_columns.js.map +1 -0
- package/dist/js/plugins/remove_button.js +142 -0
- package/dist/js/plugins/remove_button.js.map +1 -0
- package/dist/js/plugins/restore_on_backspace.js +50 -0
- package/dist/js/plugins/restore_on_backspace.js.map +1 -0
- package/dist/js/plugins/virtual_scroll.js +280 -0
- package/dist/js/plugins/virtual_scroll.js.map +1 -0
- package/dist/js/tom-select.base.js +4167 -0
- package/dist/js/tom-select.base.js.map +1 -0
- package/dist/js/tom-select.base.min.js +373 -0
- package/dist/js/tom-select.base.min.js.map +1 -0
- package/dist/js/tom-select.complete.js +5364 -0
- package/dist/js/tom-select.complete.js.map +1 -0
- package/dist/js/tom-select.complete.min.js +489 -0
- package/dist/js/tom-select.complete.min.js.map +1 -0
- package/dist/js/tom-select.popular.js +4436 -0
- package/dist/js/tom-select.popular.js.map +1 -0
- package/dist/js/tom-select.popular.min.js +396 -0
- package/dist/js/tom-select.popular.min.js.map +1 -0
- package/dist/types/constants.d.ts +12 -0
- package/dist/types/contrib/highlight.d.ts +13 -0
- package/dist/types/contrib/microevent.d.ts +20 -0
- package/dist/types/contrib/microplugin.d.ts +71 -0
- package/dist/types/defaults.d.ts +53 -0
- package/dist/types/getSettings.d.ts +3 -0
- package/dist/types/plugins/caret_position/plugin.d.ts +16 -0
- package/dist/types/plugins/change_listener/plugin.d.ts +16 -0
- package/dist/types/plugins/checkbox_options/plugin.d.ts +17 -0
- package/dist/types/plugins/checkbox_options/types.d.ts +14 -0
- package/dist/types/plugins/clear_button/plugin.d.ts +17 -0
- package/dist/types/plugins/clear_button/types.d.ts +7 -0
- package/dist/types/plugins/drag_drop/plugin.d.ts +16 -0
- package/dist/types/plugins/dropdown_header/plugin.d.ts +17 -0
- package/dist/types/plugins/dropdown_header/types.d.ts +8 -0
- package/dist/types/plugins/dropdown_input/plugin.d.ts +16 -0
- package/dist/types/plugins/input_autogrow/plugin.d.ts +15 -0
- package/dist/types/plugins/local_virtual_scroll/plugin.d.ts +19 -0
- package/dist/types/plugins/local_virtual_scroll/types.d.ts +14 -0
- package/dist/types/plugins/no_active_items/plugin.d.ts +15 -0
- package/dist/types/plugins/no_backspace_delete/plugin.d.ts +15 -0
- package/dist/types/plugins/optgroup_columns/plugin.d.ts +16 -0
- package/dist/types/plugins/remove_button/plugin.d.ts +17 -0
- package/dist/types/plugins/remove_button/types.d.ts +6 -0
- package/dist/types/plugins/restore_on_backspace/plugin.d.ts +21 -0
- package/dist/types/plugins/virtual_scroll/plugin.d.ts +16 -0
- package/dist/types/tom-select.complete.d.ts +2 -0
- package/dist/types/tom-select.d.ts +594 -0
- package/dist/types/tom-select.popular.d.ts +2 -0
- package/dist/types/types/core.d.ts +50 -0
- package/dist/types/types/index.d.ts +2 -0
- package/dist/types/types/settings.d.ts +81 -0
- package/dist/types/utils.d.ts +95 -0
- package/dist/types/vanilla.d.ts +76 -0
- package/package.json +156 -0
- package/src/constants.ts +13 -0
- package/src/contrib/highlight.ts +81 -0
- package/src/contrib/microevent.ts +73 -0
- package/src/contrib/microplugin.ts +137 -0
- package/src/defaults.ts +95 -0
- package/src/getSettings.ts +176 -0
- package/src/plugins/caret_position/plugin.ts +73 -0
- package/src/plugins/change_listener/plugin.ts +23 -0
- package/src/plugins/checkbox_options/plugin.scss +11 -0
- package/src/plugins/checkbox_options/plugin.ts +130 -0
- package/src/plugins/checkbox_options/types.ts +15 -0
- package/src/plugins/clear_button/plugin.scss +33 -0
- package/src/plugins/clear_button/plugin.ts +54 -0
- package/src/plugins/clear_button/types.ts +8 -0
- package/src/plugins/drag_drop/plugin.scss +10 -0
- package/src/plugins/drag_drop/plugin.ts +143 -0
- package/src/plugins/dropdown_header/plugin.scss +24 -0
- package/src/plugins/dropdown_header/plugin.ts +57 -0
- package/src/plugins/dropdown_header/types.ts +9 -0
- package/src/plugins/dropdown_input/plugin.scss +43 -0
- package/src/plugins/dropdown_input/plugin.ts +97 -0
- package/src/plugins/input_autogrow/plugin.scss +15 -0
- package/src/plugins/input_autogrow/plugin.ts +56 -0
- package/src/plugins/local_virtual_scroll/plugin.ts +309 -0
- package/src/plugins/local_virtual_scroll/types.ts +9 -0
- package/src/plugins/no_active_items/plugin.ts +20 -0
- package/src/plugins/no_backspace_delete/plugin.ts +30 -0
- package/src/plugins/optgroup_columns/plugin.scss +25 -0
- package/src/plugins/optgroup_columns/plugin.ts +59 -0
- package/src/plugins/remove_button/plugin.scss +70 -0
- package/src/plugins/remove_button/plugin.ts +78 -0
- package/src/plugins/remove_button/types.ts +7 -0
- package/src/plugins/restore_on_backspace/plugin.ts +44 -0
- package/src/plugins/virtual_scroll/plugin.ts +219 -0
- package/src/scss/-tom-select.bootstrap4.scss +4 -0
- package/src/scss/-tom-select.bootstrap5.scss +4 -0
- package/src/scss/_dropdown.scss +99 -0
- package/src/scss/_items.scss +114 -0
- package/src/scss/tom-select.bootstrap4.scss +218 -0
- package/src/scss/tom-select.bootstrap5.scss +270 -0
- package/src/scss/tom-select.default.scss +89 -0
- package/src/scss/tom-select.scss +179 -0
- package/src/tom-select.complete.ts +35 -0
- package/src/tom-select.popular.ts +15 -0
- package/src/tom-select.ts +2807 -0
- package/src/types/core.ts +68 -0
- package/src/types/index.ts +3 -0
- package/src/types/settings.ts +98 -0
- package/src/utils.ts +230 -0
- package/src/vanilla.ts +210 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tom Select v2.5.2
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.remove_button = factory());
|
|
10
|
+
})(this, (function () { 'use strict';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts a scalar to its best string representation
|
|
14
|
+
* for hash keys and HTML attribute values.
|
|
15
|
+
*
|
|
16
|
+
* Transformations:
|
|
17
|
+
* 'str' -> 'str'
|
|
18
|
+
* null -> ''
|
|
19
|
+
* undefined -> ''
|
|
20
|
+
* true -> '1'
|
|
21
|
+
* false -> '0'
|
|
22
|
+
* 0 -> '0'
|
|
23
|
+
* 1 -> '1'
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Escapes a string for use within HTML.
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
const escape_html = str => {
|
|
32
|
+
return (str + '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Prevent default
|
|
37
|
+
*
|
|
38
|
+
*/
|
|
39
|
+
const preventDefault = (evt, stop = false) => {
|
|
40
|
+
if (evt) {
|
|
41
|
+
evt.preventDefault();
|
|
42
|
+
if (stop) {
|
|
43
|
+
evt.stopPropagation();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Add event helper
|
|
50
|
+
*
|
|
51
|
+
*/
|
|
52
|
+
const addEvent = (target, type, callback, options) => {
|
|
53
|
+
target.addEventListener(type, callback, options);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Return a dom element from either a dom query string, jQuery object, a dom element or html string
|
|
58
|
+
* https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
|
|
59
|
+
*
|
|
60
|
+
* param query should be {}
|
|
61
|
+
*/
|
|
62
|
+
const getDom = query => {
|
|
63
|
+
if (query.jquery) {
|
|
64
|
+
return query[0];
|
|
65
|
+
}
|
|
66
|
+
if (query instanceof HTMLElement) {
|
|
67
|
+
return query;
|
|
68
|
+
}
|
|
69
|
+
if (isHtmlString(query)) {
|
|
70
|
+
var tpl = document.createElement('template');
|
|
71
|
+
tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
|
|
72
|
+
return tpl.content.firstChild;
|
|
73
|
+
}
|
|
74
|
+
return document.querySelector(query);
|
|
75
|
+
};
|
|
76
|
+
const isHtmlString = arg => {
|
|
77
|
+
if (typeof arg === 'string' && arg.indexOf('<') > -1) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Plugin: "remove_button" (Tom Select)
|
|
85
|
+
* Copyright (c) contributors
|
|
86
|
+
*
|
|
87
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
88
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
89
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
90
|
+
*
|
|
91
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
92
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
93
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
94
|
+
* governing permissions and limitations under the License.
|
|
95
|
+
*
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
function plugin (userOptions) {
|
|
99
|
+
const options = Object.assign({
|
|
100
|
+
label: '×',
|
|
101
|
+
title: 'Remove',
|
|
102
|
+
className: 'remove',
|
|
103
|
+
append: true
|
|
104
|
+
}, userOptions);
|
|
105
|
+
|
|
106
|
+
//options.className = 'remove-single';
|
|
107
|
+
var self = this;
|
|
108
|
+
|
|
109
|
+
// override the render method to add remove button to each item
|
|
110
|
+
if (!options.append) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
|
|
114
|
+
self.hook('after', 'setupTemplates', () => {
|
|
115
|
+
var orig_render_item = self.settings.render.item;
|
|
116
|
+
self.settings.render.item = (data, escape) => {
|
|
117
|
+
var item = getDom(orig_render_item.call(self, data, escape));
|
|
118
|
+
var close_button = getDom(html);
|
|
119
|
+
item.appendChild(close_button);
|
|
120
|
+
addEvent(close_button, 'mousedown', evt => {
|
|
121
|
+
preventDefault(evt, true);
|
|
122
|
+
});
|
|
123
|
+
addEvent(close_button, 'click', evt => {
|
|
124
|
+
if (self.isLocked) return;
|
|
125
|
+
|
|
126
|
+
// propagating will trigger the dropdown to show for single mode
|
|
127
|
+
preventDefault(evt, true);
|
|
128
|
+
if (self.isLocked) return;
|
|
129
|
+
if (!self.shouldDelete([item], evt)) return;
|
|
130
|
+
self.removeItem(item);
|
|
131
|
+
self.refreshOptions(false);
|
|
132
|
+
self.inputState();
|
|
133
|
+
});
|
|
134
|
+
return item;
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return plugin;
|
|
140
|
+
|
|
141
|
+
}));
|
|
142
|
+
//# sourceMappingURL=remove_button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove_button.js","sources":["../../../src/utils.ts","../../../src/vanilla.ts","../../../src/plugins/remove_button/plugin.ts"],"sourcesContent":["\nimport type TomSelect from './tom-select.ts';\nimport { TomLoadCallback } from './types/index.ts';\n\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\nexport const hash_key = (value:undefined|null|boolean|string|number):string|null => {\n\tif (typeof value === 'undefined' || value === null) return null;\n\treturn get_hash(value);\n};\n\nexport const get_hash = (value:boolean|string|number):string => {\n\tif (typeof value === 'boolean') return value ? '1' : '0';\n\treturn value + '';\n};\n\n/**\n * Escapes a string for use within HTML.\n *\n */\nexport const escape_html = (str:string):string => {\n\treturn (str + '')\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\"/g, '"');\n};\n\n\n/**\n * use setTimeout if timeout > 0 \n */\nexport const timeout = (fn:()=>void,timeout:number): number | null => {\n\tif( timeout > 0 ){\n\t\treturn window.setTimeout(fn,timeout);\n\t}\n\n\tfn.call(null);\n\treturn null;\n}\n\n/**\n * Debounce the user provided load function\n *\n */\nexport const loadDebounce = (fn:(value:string,callback:TomLoadCallback) => void,delay:number) => {\n\tvar timeout: null|ReturnType<typeof setTimeout>;\n\treturn function(this:TomSelect, value:string,callback:TomLoadCallback) {\n\t\tvar self = this;\n\n\t\tif( timeout ){\n\t\t\tself.loading = Math.max(self.loading - 1, 0);\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t\ttimeout = setTimeout(function() {\n\t\t\ttimeout = null;\n\t\t\tself.loadedSearches[value] = true;\n\t\t\tfn.call(self, value, callback);\n\n\t\t}, delay);\n\t};\n};\n\n\n/**\n * Debounce all fired events types listed in `types`\n * while executing the provided `fn`.\n *\n */\nexport const debounce_events = ( self:TomSelect, types:string[], fn:() => void ) => {\n\tvar type:string;\n\tvar trigger = self.trigger;\n\tvar event_args:{ [key: string]: any } = {};\n\n\t// override trigger method\n\tself.trigger = function(){\n\t\tvar type = arguments[0];\n\t\tif (types.indexOf(type) !== -1) {\n\t\t\tevent_args[type] = arguments;\n\t\t} else {\n\t\t\treturn trigger.apply(self, arguments);\n\t\t}\n\t};\n\n\t// invoke provided function\n\tfn.apply(self, []);\n\tself.trigger = trigger;\n\n\t// trigger queued events\n\tfor( type of types ){\n\t\tif( type in event_args ){\n\t\t\ttrigger.apply(self, event_args[type]);\n\t\t}\n\t}\n};\n\n\n/**\n * Determines the current selection within a text input control.\n * Returns an object containing:\n * - start\n * - length\n *\n * Note: \"selectionStart, selectionEnd ... apply only to inputs of types text, search, URL, tel and password\"\n * \t- https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n */\nexport const getSelection = (input:HTMLInputElement):{ start: number; length: number } => {\n\treturn {\n\t\tstart\t: input.selectionStart || 0,\n\t\tlength\t: (input.selectionEnd||0) - (input.selectionStart||0),\n\t};\n};\n\n\n/**\n * Prevent default\n *\n */\nexport const preventDefault = (evt?:Event, stop:boolean=false):void => {\n\tif( evt ){\n\t\tevt.preventDefault();\n\t\tif( stop ){\n\t\t\tevt.stopPropagation();\n\t\t}\n\t}\n}\n\n\n/**\n * Add event helper\n *\n */\nexport const addEvent = (target:EventTarget, type:string, callback:EventListenerOrEventListenerObject, options?:object):void => {\n\ttarget.addEventListener(type,callback,options);\n};\n\n\n/**\n * Return true if the requested key is down\n * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )\n * The current evt may not always set ( eg calling advanceSelection() )\n *\n */\nexport const isKeyDown = ( key_name:keyof (KeyboardEvent|MouseEvent), evt?:KeyboardEvent|MouseEvent ) => {\n\n\tif( !evt ){\n\t\treturn false;\n\t}\n\n\tif( !evt[key_name] ){\n\t\treturn false;\n\t}\n\n\tvar count = (evt.altKey?1:0) + (evt.ctrlKey?1:0) + (evt.shiftKey?1:0) + (evt.metaKey?1:0);\n\n\tif( count === 1 ){\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Get the id of an element\n * If the id attribute is not set, set the attribute with the given id\n *\n */\nexport const getId = (el:Element,id:string) => {\n\tconst existing_id = el.getAttribute('id');\n\tif( existing_id ){\n\t\treturn existing_id;\n\t}\n\n\tel.setAttribute('id',id);\n\treturn id;\n};\n\n\n/**\n * Returns a string with backslashes added before characters that need to be escaped.\n */\nexport const addSlashes = (str:string):string => {\n\treturn str.replace(/[\\\\\"']/g, '\\\\$&');\n};\n\n/**\n *\n */\nexport const append = ( parent:Element|DocumentFragment, node: string|Node|null|undefined ):void =>{\n\tif( node ) parent.append(node);\n};\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nexport const iterate = (object:[]|{[key:string]:any}, callback:(value:any,key:any)=>any) => {\n\n\tif ( Array.isArray(object)) {\n\t\tobject.forEach(callback);\n\n\t}else{\n\n\t\tfor (var key in object) {\n\t\t\tif (object.hasOwnProperty(key)) {\n\t\t\t\tcallback(object[key], key);\n\t\t\t}\n\t\t}\n\t}\n};\n","\nimport { iterate } from './utils.ts';\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nexport const getDom = ( query:any ):HTMLElement => {\n\n\tif( query.jquery ){\n\t\treturn query[0];\n\t}\n\n\tif( query instanceof HTMLElement ){\n\t\treturn query;\n\t}\n\n\tif( isHtmlString(query) ){\n\t\tvar tpl = document.createElement('template');\n\t\ttpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n\t\treturn tpl.content.firstChild as HTMLElement;\n\t}\n\n\treturn document.querySelector(query);\n};\n\nexport const isHtmlString = (arg:any): boolean => {\n\tif( typeof arg === 'string' && arg.indexOf('<') > -1 ){\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport const escapeQuery = (query:string):string => {\n\treturn query.replace(/['\"\\\\]/g, '\\\\$&');\n}\n\n/**\n * Dispatch an event\n *\n */\nexport const triggerEvent = ( dom_el:HTMLElement, event_name:string ):void => {\n\tvar event = document.createEvent('HTMLEvents');\n\tevent.initEvent(event_name, true, false);\n\tdom_el.dispatchEvent(event)\n};\n\n/**\n * Apply CSS rules to a dom element\n *\n */\nexport const applyCSS = ( dom_el:HTMLElement, css:{ [key: string]: string|number }):void => {\n\tObject.assign(dom_el.style, css);\n}\n\n\n/**\n * Add css classes\n *\n */\nexport const addClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {\n\n\tvar norm_classes \t= classesArray(classes);\n\telmts\t\t\t\t= castAsArray(elmts);\n\n\telmts.map( el => {\n\t\tnorm_classes.map( cls => {\n\t\t\tel.classList.add( cls );\n\t\t});\n\t});\n}\n\n/**\n * Remove css classes\n *\n */\n export const removeClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {\n\n \tvar norm_classes \t= classesArray(classes);\n\telmts\t\t\t\t= castAsArray(elmts);\n\n\telmts.map( el => {\n\t\tnorm_classes.map(cls => {\n\t \t\tel.classList.remove( cls );\n\t\t});\n \t});\n }\n\n\n/**\n * Return arguments\n *\n */\nexport const classesArray = (args:string[]|string[][]):string[] => {\n\tvar classes:string[] = [];\n\titerate( args, (_classes) =>{\n\t\tif( typeof _classes === 'string' ){\n\t\t\t_classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n\t\t}\n\t\tif( Array.isArray(_classes) ){\n\t\t\tclasses = classes.concat(_classes);\n\t\t}\n\t});\n\n\treturn classes.filter(Boolean);\n}\n\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nexport const castAsArray = (arg:any):Array<any> => {\n\tif( !Array.isArray(arg) ){\n \t\targ = [arg];\n \t}\n\treturn arg;\n}\n\n\n/**\n * Get the closest node to the evt.target matching the selector\n * Stops at wrapper\n *\n */\nexport const parentMatch = ( target:null|HTMLElement, selector:string, wrapper?:HTMLElement ):HTMLElement|void => {\n\n\tif( wrapper && !wrapper.contains(target) ){\n\t\treturn;\n\t}\n\n\twhile( target && target.matches ){\n\n\t\tif( target.matches(selector) ){\n\t\t\treturn target;\n\t\t}\n\n\t\ttarget = target.parentNode as HTMLElement;\n\t}\n}\n\n\n/**\n * Get the first or last item from an array\n *\n * > 0 - right (last)\n * <= 0 - left (first)\n *\n */\nexport const getTail = ( list:Array<any>|NodeList, direction:number=0 ):any => {\n\n\tif( direction > 0 ){\n\t\treturn list[list.length-1];\n\t}\n\n\treturn list[0];\n}\n\n/**\n * Return true if an object is empty\n *\n */\nexport const isEmptyObject = (obj:object):boolean => {\n\treturn (Object.keys(obj).length === 0);\n}\n\n\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nexport const nodeIndex = ( el:null|Element, amongst?:string ):number => {\n\tif (!el) return -1;\n\n\tamongst = amongst || el.nodeName;\n\n\tvar i = 0;\n\twhile( el = el.previousElementSibling ){\n\n\t\tif( el.matches(amongst) ){\n\t\t\ti++;\n\t\t}\n\t}\n\treturn i;\n}\n\n\n/**\n * Set attributes of an element\n *\n */\nexport const setAttr = (el:Element,attrs:{ [key: string]: null|string|number }) => {\n\titerate( attrs,(val,attr) => {\n\t\tif( val == null ){\n\t\t\tel.removeAttribute(attr as string);\n\t\t}else{\n\t\t\tel.setAttribute(attr as string, ''+val);\n\t\t}\n\t});\n}\n\n\n/**\n * Replace a node\n */\nexport const replaceNode = ( existing:Node, replacement:Node ) => {\n\tif( existing.parentNode ) existing.parentNode.replaceChild(replacement, existing);\n}\n","/**\n * Plugin: \"remove_button\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nimport type TomSelect from '../../tom-select.ts';\nimport { getDom } from '../../vanilla.ts';\nimport { escape_html, preventDefault, addEvent } from '../../utils.ts';\nimport { TomOption, TomItem } from '../../types/index.ts';\nimport { RBOptions } from './types.ts';\n\nexport default function(this:TomSelect, userOptions:RBOptions) {\n\n\tconst options = Object.assign({\n\t\t\tlabel : '×',\n\t\t\ttitle : 'Remove',\n\t\t\tclassName : 'remove',\n\t\t\tappend : true\n\t\t}, userOptions);\n\n\n\t//options.className = 'remove-single';\n\tvar self\t\t\t= this;\n\n\t// override the render method to add remove button to each item\n\tif( !options.append ){\n\t\treturn;\n\t}\n\n\tvar html = '<a href=\"javascript:void(0)\" class=\"' + options.className + '\" tabindex=\"-1\" title=\"' + escape_html(options.title) + '\">' + options.label + '</a>';\n\n\tself.hook('after','setupTemplates',() => {\n\n\t\tvar orig_render_item = self.settings.render.item;\n\n\t\tself.settings.render.item = (data:TomOption, escape:typeof escape_html) => {\n\n\t\t\tvar item = getDom(orig_render_item.call(self, data, escape)) as TomItem;\n\n\t\t\tvar close_button = getDom(html);\n\t\t\titem.appendChild(close_button);\n\n\t\t\taddEvent(close_button,'mousedown',(evt) => {\n\t\t\t\tpreventDefault(evt,true);\n\t\t\t});\n\n\t\t\taddEvent(close_button,'click',(evt) => {\n\n\t\t\t\tif( self.isLocked ) return;\n\n\t\t\t\t// propagating will trigger the dropdown to show for single mode\n\t\t\t\tpreventDefault(evt,true);\n\n\t\t\t\tif( self.isLocked ) return;\n\t\t\t\tif( !self.shouldDelete([item],evt as MouseEvent) ) return;\n\n\t\t\t\tself.removeItem(item);\n\t\t\t\tself.refreshOptions(false);\n\t\t\t\tself.inputState();\n\t\t\t});\n\n\t\t\treturn item;\n\t\t};\n\n\t});\n\n\n};\n"],"names":["escape_html","str","replace","preventDefault","evt","stop","stopPropagation","addEvent","target","type","callback","options","addEventListener","getDom","query","jquery","HTMLElement","isHtmlString","tpl","document","createElement","innerHTML","trim","content","firstChild","querySelector","arg","indexOf","userOptions","Object","assign","label","title","className","append","self","html","hook","orig_render_item","settings","render","item","data","escape","call","close_button","appendChild","isLocked","shouldDelete","removeItem","refreshOptions","inputState"],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tom Select v2.5.2
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.restore_on_backspace = factory());
|
|
10
|
+
})(this, (function () { 'use strict';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Plugin: "restore_on_backspace" (Tom Select)
|
|
14
|
+
* Copyright (c) contributors
|
|
15
|
+
*
|
|
16
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
17
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
18
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
19
|
+
*
|
|
20
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
21
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
22
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
23
|
+
* governing permissions and limitations under the License.
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
function plugin (userOptions) {
|
|
28
|
+
const self = this;
|
|
29
|
+
const options = Object.assign({
|
|
30
|
+
text: option => {
|
|
31
|
+
return option[self.settings.labelField];
|
|
32
|
+
}
|
|
33
|
+
}, userOptions);
|
|
34
|
+
self.on('item_remove', function (value) {
|
|
35
|
+
if (!self.isFocused) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (self.control_input.value.trim() === '') {
|
|
39
|
+
var option = self.options[value];
|
|
40
|
+
if (option) {
|
|
41
|
+
self.setTextboxValue(options.text.call(self, option));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return plugin;
|
|
48
|
+
|
|
49
|
+
}));
|
|
50
|
+
//# sourceMappingURL=restore_on_backspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore_on_backspace.js","sources":["../../../src/plugins/restore_on_backspace/plugin.ts"],"sourcesContent":["/**\n * Plugin: \"restore_on_backspace\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\nimport type TomSelect from '../../tom-select.ts';\nimport { TomOption } from '../../types/index.ts';\n\ntype TPluginOptions = {\n\ttext?:(option:TomOption)=>string,\n};\n\nexport default function(this:TomSelect, userOptions:TPluginOptions) {\n\tconst self = this;\n\n\tconst options = Object.assign({\n\t\ttext: (option:TomOption) => {\n\t\t\treturn option[self.settings.labelField];\n\t\t}\n\t},userOptions);\n\n\tself.on('item_remove',function(value:string){\n\t\tif( !self.isFocused ){\n\t\t\treturn;\n\t\t}\n\n\t\tif( self.control_input.value.trim() === '' ){\n\t\t\tvar option = self.options[value];\n\t\t\tif( option ){\n\t\t\t\tself.setTextboxValue(options.text.call(self, option));\n\t\t\t}\n\t\t}\n\t});\n\n};\n"],"names":["userOptions","self","options","Object","assign","text","option","settings","labelField","on","value","isFocused","control_input","trim","setTextboxValue","call"],"mappings":";;;;;;;;;;;CAAA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;CAQe,eAAA,EAAyBA,WAA0B,EAAE;GACnE,MAAMC,IAAI,GAAG,IAAI;CAEjB,EAAA,MAAMC,OAAO,GAAGC,MAAM,CAACC,MAAM,CAAC;KAC7BC,IAAI,EAAGC,MAAgB,IAAK;CAC3B,MAAA,OAAOA,MAAM,CAACL,IAAI,CAACM,QAAQ,CAACC,UAAU,CAAC;CACxC,IAAA;IACA,EAACR,WAAW,CAAC;CAEdC,EAAAA,IAAI,CAACQ,EAAE,CAAC,aAAa,EAAC,UAASC,KAAY,EAAC;CAC3C,IAAA,IAAI,CAACT,IAAI,CAACU,SAAS,EAAE;CACpB,MAAA;CACD,IAAA;KAEA,IAAIV,IAAI,CAACW,aAAa,CAACF,KAAK,CAACG,IAAI,EAAE,KAAK,EAAE,EAAE;CAC3C,MAAA,IAAIP,MAAM,GAAGL,IAAI,CAACC,OAAO,CAACQ,KAAK,CAAC;CAChC,MAAA,IAAIJ,MAAM,EAAE;CACXL,QAAAA,IAAI,CAACa,eAAe,CAACZ,OAAO,CAACG,IAAI,CAACU,IAAI,CAACd,IAAI,EAAEK,MAAM,CAAC,CAAC;CACtD,MAAA;CACD,IAAA;CACD,EAAA,CAAC,CAAC;CAEH;;;;;;;;"}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tom Select v2.5.2
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function (global, factory) {
|
|
7
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
8
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
9
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.virtual_scroll = factory());
|
|
10
|
+
})(this, (function () { 'use strict';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts a scalar to its best string representation
|
|
14
|
+
* for hash keys and HTML attribute values.
|
|
15
|
+
*
|
|
16
|
+
* Transformations:
|
|
17
|
+
* 'str' -> 'str'
|
|
18
|
+
* null -> ''
|
|
19
|
+
* undefined -> ''
|
|
20
|
+
* true -> '1'
|
|
21
|
+
* false -> '0'
|
|
22
|
+
* 0 -> '0'
|
|
23
|
+
* 1 -> '1'
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Iterates over arrays and hashes.
|
|
29
|
+
*
|
|
30
|
+
* ```
|
|
31
|
+
* iterate(this.items, function(item, id) {
|
|
32
|
+
* // invoked for each item
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
const iterate = (object, callback) => {
|
|
38
|
+
if (Array.isArray(object)) {
|
|
39
|
+
object.forEach(callback);
|
|
40
|
+
} else {
|
|
41
|
+
for (var key in object) {
|
|
42
|
+
if (object.hasOwnProperty(key)) {
|
|
43
|
+
callback(object[key], key);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Add css classes
|
|
51
|
+
*
|
|
52
|
+
*/
|
|
53
|
+
const addClasses = (elmts, ...classes) => {
|
|
54
|
+
var norm_classes = classesArray(classes);
|
|
55
|
+
elmts = castAsArray(elmts);
|
|
56
|
+
elmts.map(el => {
|
|
57
|
+
norm_classes.map(cls => {
|
|
58
|
+
el.classList.add(cls);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Return arguments
|
|
65
|
+
*
|
|
66
|
+
*/
|
|
67
|
+
const classesArray = args => {
|
|
68
|
+
var classes = [];
|
|
69
|
+
iterate(args, _classes => {
|
|
70
|
+
if (typeof _classes === 'string') {
|
|
71
|
+
_classes = _classes.trim().split(/[\t\n\f\r\s]/);
|
|
72
|
+
}
|
|
73
|
+
if (Array.isArray(_classes)) {
|
|
74
|
+
classes = classes.concat(_classes);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return classes.filter(Boolean);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Create an array from arg if it's not already an array
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
const castAsArray = arg => {
|
|
85
|
+
if (!Array.isArray(arg)) {
|
|
86
|
+
arg = [arg];
|
|
87
|
+
}
|
|
88
|
+
return arg;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Plugin: "restore_on_backspace" (Tom Select)
|
|
93
|
+
* Copyright (c) contributors
|
|
94
|
+
*
|
|
95
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
96
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
97
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
98
|
+
*
|
|
99
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
100
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
101
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
102
|
+
* governing permissions and limitations under the License.
|
|
103
|
+
*
|
|
104
|
+
*/
|
|
105
|
+
|
|
106
|
+
function plugin () {
|
|
107
|
+
const self = this;
|
|
108
|
+
const orig_canLoad = self.canLoad;
|
|
109
|
+
const orig_clearActiveOption = self.clearActiveOption;
|
|
110
|
+
const orig_loadCallback = self.loadCallback;
|
|
111
|
+
var pagination = {};
|
|
112
|
+
var dropdown_content;
|
|
113
|
+
var loading_more = false;
|
|
114
|
+
var load_more_opt;
|
|
115
|
+
var default_values = [];
|
|
116
|
+
if (!self.settings.shouldLoadMore) {
|
|
117
|
+
// return true if additional results should be loaded
|
|
118
|
+
self.settings.shouldLoadMore = () => {
|
|
119
|
+
const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);
|
|
120
|
+
if (scroll_percent > 0.9) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (self.activeOption) {
|
|
124
|
+
var selectable = self.selectable();
|
|
125
|
+
var index = Array.from(selectable).indexOf(self.activeOption);
|
|
126
|
+
if (index >= selectable.length - 2) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return false;
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (!self.settings.firstUrl) {
|
|
134
|
+
throw 'virtual_scroll plugin requires a firstUrl() method';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// in order for virtual scrolling to work,
|
|
138
|
+
// options need to be ordered the same way they're returned from the remote data source
|
|
139
|
+
self.settings.sortField = [{
|
|
140
|
+
field: '$order'
|
|
141
|
+
}, {
|
|
142
|
+
field: '$score'
|
|
143
|
+
}];
|
|
144
|
+
|
|
145
|
+
// can we load more results for given query?
|
|
146
|
+
const canLoadMore = query => {
|
|
147
|
+
if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (query in pagination && pagination[query]) {
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
};
|
|
155
|
+
const clearFilter = (option, value) => {
|
|
156
|
+
if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
// set the next url that will be
|
|
163
|
+
self.setNextUrl = (value, next_url) => {
|
|
164
|
+
pagination[value] = next_url;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// getUrl() to be used in settings.load()
|
|
168
|
+
self.getUrl = query => {
|
|
169
|
+
if (query in pagination) {
|
|
170
|
+
const next_url = pagination[query];
|
|
171
|
+
pagination[query] = false;
|
|
172
|
+
return next_url;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// if the user goes back to a previous query
|
|
176
|
+
// we need to load the first page again
|
|
177
|
+
self.clearPagination();
|
|
178
|
+
return self.settings.firstUrl.call(self, query);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// clear pagination
|
|
182
|
+
self.clearPagination = () => {
|
|
183
|
+
pagination = {};
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// don't clear the active option (and cause unwanted dropdown scroll)
|
|
187
|
+
// while loading more results
|
|
188
|
+
self.hook('instead', 'clearActiveOption', () => {
|
|
189
|
+
if (loading_more) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
return orig_clearActiveOption.call(self);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// override the canLoad method
|
|
196
|
+
self.hook('instead', 'canLoad', query => {
|
|
197
|
+
// first time the query has been seen
|
|
198
|
+
if (!(query in pagination)) {
|
|
199
|
+
return orig_canLoad.call(self, query);
|
|
200
|
+
}
|
|
201
|
+
return canLoadMore(query);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// wrap the load
|
|
205
|
+
self.hook('instead', 'loadCallback', (options, optgroups) => {
|
|
206
|
+
if (!loading_more) {
|
|
207
|
+
self.clearOptions(clearFilter);
|
|
208
|
+
} else if (load_more_opt) {
|
|
209
|
+
const first_option = options[0];
|
|
210
|
+
if (first_option !== undefined) {
|
|
211
|
+
load_more_opt.dataset.value = first_option[self.settings.valueField];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
orig_loadCallback.call(self, options, optgroups);
|
|
215
|
+
loading_more = false;
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// add templates to dropdown
|
|
219
|
+
// loading_more if we have another url in the queue
|
|
220
|
+
// no_more_results if we don't have another url in the queue
|
|
221
|
+
self.hook('after', 'refreshOptions', () => {
|
|
222
|
+
const query = self.lastValue;
|
|
223
|
+
var option;
|
|
224
|
+
if (canLoadMore(query)) {
|
|
225
|
+
option = self.render('loading_more', {
|
|
226
|
+
query: query
|
|
227
|
+
});
|
|
228
|
+
if (option) {
|
|
229
|
+
option.setAttribute('data-selectable', ''); // so that navigating dropdown with [down] keypresses can navigate to this node
|
|
230
|
+
load_more_opt = option;
|
|
231
|
+
}
|
|
232
|
+
} else if (query in pagination && !dropdown_content.querySelector('.no-results')) {
|
|
233
|
+
option = self.render('no_more_results', {
|
|
234
|
+
query: query
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (option) {
|
|
238
|
+
addClasses(option, self.settings.optionClass);
|
|
239
|
+
dropdown_content.append(option);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
// add scroll listener and default templates
|
|
244
|
+
self.on('initialize', () => {
|
|
245
|
+
default_values = Object.keys(self.options);
|
|
246
|
+
dropdown_content = self.dropdown_content;
|
|
247
|
+
|
|
248
|
+
// default templates
|
|
249
|
+
self.settings.render = Object.assign({}, {
|
|
250
|
+
loading_more: () => {
|
|
251
|
+
return `<div class="loading-more-results">Loading more results ... </div>`;
|
|
252
|
+
},
|
|
253
|
+
no_more_results: () => {
|
|
254
|
+
return `<div class="no-more-results">No more results</div>`;
|
|
255
|
+
}
|
|
256
|
+
}, self.settings.render);
|
|
257
|
+
|
|
258
|
+
// watch dropdown content scroll position
|
|
259
|
+
dropdown_content.addEventListener('scroll', () => {
|
|
260
|
+
if (!self.settings.shouldLoadMore.call(self)) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true
|
|
265
|
+
if (!canLoadMore(self.lastValue)) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// don't call load() too much
|
|
270
|
+
if (loading_more) return;
|
|
271
|
+
loading_more = true;
|
|
272
|
+
self.load.call(self, self.lastValue);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return plugin;
|
|
278
|
+
|
|
279
|
+
}));
|
|
280
|
+
//# sourceMappingURL=virtual_scroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtual_scroll.js","sources":["../../../src/utils.ts","../../../src/vanilla.ts","../../../src/plugins/virtual_scroll/plugin.ts"],"sourcesContent":["\nimport type TomSelect from './tom-select.ts';\nimport { TomLoadCallback } from './types/index.ts';\n\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\nexport const hash_key = (value:undefined|null|boolean|string|number):string|null => {\n\tif (typeof value === 'undefined' || value === null) return null;\n\treturn get_hash(value);\n};\n\nexport const get_hash = (value:boolean|string|number):string => {\n\tif (typeof value === 'boolean') return value ? '1' : '0';\n\treturn value + '';\n};\n\n/**\n * Escapes a string for use within HTML.\n *\n */\nexport const escape_html = (str:string):string => {\n\treturn (str + '')\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\"/g, '"');\n};\n\n\n/**\n * use setTimeout if timeout > 0 \n */\nexport const timeout = (fn:()=>void,timeout:number): number | null => {\n\tif( timeout > 0 ){\n\t\treturn window.setTimeout(fn,timeout);\n\t}\n\n\tfn.call(null);\n\treturn null;\n}\n\n/**\n * Debounce the user provided load function\n *\n */\nexport const loadDebounce = (fn:(value:string,callback:TomLoadCallback) => void,delay:number) => {\n\tvar timeout: null|ReturnType<typeof setTimeout>;\n\treturn function(this:TomSelect, value:string,callback:TomLoadCallback) {\n\t\tvar self = this;\n\n\t\tif( timeout ){\n\t\t\tself.loading = Math.max(self.loading - 1, 0);\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t\ttimeout = setTimeout(function() {\n\t\t\ttimeout = null;\n\t\t\tself.loadedSearches[value] = true;\n\t\t\tfn.call(self, value, callback);\n\n\t\t}, delay);\n\t};\n};\n\n\n/**\n * Debounce all fired events types listed in `types`\n * while executing the provided `fn`.\n *\n */\nexport const debounce_events = ( self:TomSelect, types:string[], fn:() => void ) => {\n\tvar type:string;\n\tvar trigger = self.trigger;\n\tvar event_args:{ [key: string]: any } = {};\n\n\t// override trigger method\n\tself.trigger = function(){\n\t\tvar type = arguments[0];\n\t\tif (types.indexOf(type) !== -1) {\n\t\t\tevent_args[type] = arguments;\n\t\t} else {\n\t\t\treturn trigger.apply(self, arguments);\n\t\t}\n\t};\n\n\t// invoke provided function\n\tfn.apply(self, []);\n\tself.trigger = trigger;\n\n\t// trigger queued events\n\tfor( type of types ){\n\t\tif( type in event_args ){\n\t\t\ttrigger.apply(self, event_args[type]);\n\t\t}\n\t}\n};\n\n\n/**\n * Determines the current selection within a text input control.\n * Returns an object containing:\n * - start\n * - length\n *\n * Note: \"selectionStart, selectionEnd ... apply only to inputs of types text, search, URL, tel and password\"\n * \t- https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n */\nexport const getSelection = (input:HTMLInputElement):{ start: number; length: number } => {\n\treturn {\n\t\tstart\t: input.selectionStart || 0,\n\t\tlength\t: (input.selectionEnd||0) - (input.selectionStart||0),\n\t};\n};\n\n\n/**\n * Prevent default\n *\n */\nexport const preventDefault = (evt?:Event, stop:boolean=false):void => {\n\tif( evt ){\n\t\tevt.preventDefault();\n\t\tif( stop ){\n\t\t\tevt.stopPropagation();\n\t\t}\n\t}\n}\n\n\n/**\n * Add event helper\n *\n */\nexport const addEvent = (target:EventTarget, type:string, callback:EventListenerOrEventListenerObject, options?:object):void => {\n\ttarget.addEventListener(type,callback,options);\n};\n\n\n/**\n * Return true if the requested key is down\n * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )\n * The current evt may not always set ( eg calling advanceSelection() )\n *\n */\nexport const isKeyDown = ( key_name:keyof (KeyboardEvent|MouseEvent), evt?:KeyboardEvent|MouseEvent ) => {\n\n\tif( !evt ){\n\t\treturn false;\n\t}\n\n\tif( !evt[key_name] ){\n\t\treturn false;\n\t}\n\n\tvar count = (evt.altKey?1:0) + (evt.ctrlKey?1:0) + (evt.shiftKey?1:0) + (evt.metaKey?1:0);\n\n\tif( count === 1 ){\n\t\treturn true;\n\t}\n\n\treturn false;\n};\n\n\n/**\n * Get the id of an element\n * If the id attribute is not set, set the attribute with the given id\n *\n */\nexport const getId = (el:Element,id:string) => {\n\tconst existing_id = el.getAttribute('id');\n\tif( existing_id ){\n\t\treturn existing_id;\n\t}\n\n\tel.setAttribute('id',id);\n\treturn id;\n};\n\n\n/**\n * Returns a string with backslashes added before characters that need to be escaped.\n */\nexport const addSlashes = (str:string):string => {\n\treturn str.replace(/[\\\\\"']/g, '\\\\$&');\n};\n\n/**\n *\n */\nexport const append = ( parent:Element|DocumentFragment, node: string|Node|null|undefined ):void =>{\n\tif( node ) parent.append(node);\n};\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nexport const iterate = (object:[]|{[key:string]:any}, callback:(value:any,key:any)=>any) => {\n\n\tif ( Array.isArray(object)) {\n\t\tobject.forEach(callback);\n\n\t}else{\n\n\t\tfor (var key in object) {\n\t\t\tif (object.hasOwnProperty(key)) {\n\t\t\t\tcallback(object[key], key);\n\t\t\t}\n\t\t}\n\t}\n};\n","\nimport { iterate } from './utils.ts';\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nexport const getDom = ( query:any ):HTMLElement => {\n\n\tif( query.jquery ){\n\t\treturn query[0];\n\t}\n\n\tif( query instanceof HTMLElement ){\n\t\treturn query;\n\t}\n\n\tif( isHtmlString(query) ){\n\t\tvar tpl = document.createElement('template');\n\t\ttpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n\t\treturn tpl.content.firstChild as HTMLElement;\n\t}\n\n\treturn document.querySelector(query);\n};\n\nexport const isHtmlString = (arg:any): boolean => {\n\tif( typeof arg === 'string' && arg.indexOf('<') > -1 ){\n\t\treturn true;\n\t}\n\treturn false;\n}\n\nexport const escapeQuery = (query:string):string => {\n\treturn query.replace(/['\"\\\\]/g, '\\\\$&');\n}\n\n/**\n * Dispatch an event\n *\n */\nexport const triggerEvent = ( dom_el:HTMLElement, event_name:string ):void => {\n\tvar event = document.createEvent('HTMLEvents');\n\tevent.initEvent(event_name, true, false);\n\tdom_el.dispatchEvent(event)\n};\n\n/**\n * Apply CSS rules to a dom element\n *\n */\nexport const applyCSS = ( dom_el:HTMLElement, css:{ [key: string]: string|number }):void => {\n\tObject.assign(dom_el.style, css);\n}\n\n\n/**\n * Add css classes\n *\n */\nexport const addClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {\n\n\tvar norm_classes \t= classesArray(classes);\n\telmts\t\t\t\t= castAsArray(elmts);\n\n\telmts.map( el => {\n\t\tnorm_classes.map( cls => {\n\t\t\tel.classList.add( cls );\n\t\t});\n\t});\n}\n\n/**\n * Remove css classes\n *\n */\n export const removeClasses = ( elmts:HTMLElement|HTMLElement[], ...classes:string[]|string[][] ) => {\n\n \tvar norm_classes \t= classesArray(classes);\n\telmts\t\t\t\t= castAsArray(elmts);\n\n\telmts.map( el => {\n\t\tnorm_classes.map(cls => {\n\t \t\tel.classList.remove( cls );\n\t\t});\n \t});\n }\n\n\n/**\n * Return arguments\n *\n */\nexport const classesArray = (args:string[]|string[][]):string[] => {\n\tvar classes:string[] = [];\n\titerate( args, (_classes) =>{\n\t\tif( typeof _classes === 'string' ){\n\t\t\t_classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n\t\t}\n\t\tif( Array.isArray(_classes) ){\n\t\t\tclasses = classes.concat(_classes);\n\t\t}\n\t});\n\n\treturn classes.filter(Boolean);\n}\n\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nexport const castAsArray = (arg:any):Array<any> => {\n\tif( !Array.isArray(arg) ){\n \t\targ = [arg];\n \t}\n\treturn arg;\n}\n\n\n/**\n * Get the closest node to the evt.target matching the selector\n * Stops at wrapper\n *\n */\nexport const parentMatch = ( target:null|HTMLElement, selector:string, wrapper?:HTMLElement ):HTMLElement|void => {\n\n\tif( wrapper && !wrapper.contains(target) ){\n\t\treturn;\n\t}\n\n\twhile( target && target.matches ){\n\n\t\tif( target.matches(selector) ){\n\t\t\treturn target;\n\t\t}\n\n\t\ttarget = target.parentNode as HTMLElement;\n\t}\n}\n\n\n/**\n * Get the first or last item from an array\n *\n * > 0 - right (last)\n * <= 0 - left (first)\n *\n */\nexport const getTail = ( list:Array<any>|NodeList, direction:number=0 ):any => {\n\n\tif( direction > 0 ){\n\t\treturn list[list.length-1];\n\t}\n\n\treturn list[0];\n}\n\n/**\n * Return true if an object is empty\n *\n */\nexport const isEmptyObject = (obj:object):boolean => {\n\treturn (Object.keys(obj).length === 0);\n}\n\n\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nexport const nodeIndex = ( el:null|Element, amongst?:string ):number => {\n\tif (!el) return -1;\n\n\tamongst = amongst || el.nodeName;\n\n\tvar i = 0;\n\twhile( el = el.previousElementSibling ){\n\n\t\tif( el.matches(amongst) ){\n\t\t\ti++;\n\t\t}\n\t}\n\treturn i;\n}\n\n\n/**\n * Set attributes of an element\n *\n */\nexport const setAttr = (el:Element,attrs:{ [key: string]: null|string|number }) => {\n\titerate( attrs,(val,attr) => {\n\t\tif( val == null ){\n\t\t\tel.removeAttribute(attr as string);\n\t\t}else{\n\t\t\tel.setAttribute(attr as string, ''+val);\n\t\t}\n\t});\n}\n\n\n/**\n * Replace a node\n */\nexport const replaceNode = ( existing:Node, replacement:Node ) => {\n\tif( existing.parentNode ) existing.parentNode.replaceChild(replacement, existing);\n}\n","/**\n * Plugin: \"restore_on_backspace\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nimport type TomSelect from '../../tom-select.ts';\nimport { TomOption } from '../../types/index.ts';\nimport { addClasses } from '../../vanilla.ts';\n\nexport default function(this:TomSelect) {\n\tconst self\t\t\t\t\t\t\t= this;\n\tconst orig_canLoad\t\t\t\t\t= self.canLoad;\n\tconst orig_clearActiveOption\t\t= self.clearActiveOption;\n\tconst orig_loadCallback\t\t\t\t= self.loadCallback;\n\n\tvar pagination:{[key:string]:any}\t= {};\n\tvar dropdown_content:HTMLElement;\n\tvar loading_more\t\t\t\t\t= false;\n\tvar load_more_opt:HTMLElement;\n\tvar default_values: string[]\t\t= [];\n\n\tif( !self.settings.shouldLoadMore ){\n\n\t\t// return true if additional results should be loaded\n\t\tself.settings.shouldLoadMore = ():boolean=>{\n\n\t\t\tconst scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);\n\t\t\tif( scroll_percent > 0.9 ){\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif( self.activeOption ){\n\t\t\t\tvar selectable\t= self.selectable();\n\t\t\t\tvar index\t\t= Array.from(selectable).indexOf(self.activeOption);\n\t\t\t\tif( index >= (selectable.length-2) ){\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\t}\n\n\n\tif( !self.settings.firstUrl ){\n\t\tthrow 'virtual_scroll plugin requires a firstUrl() method';\n\t}\n\n\n\t// in order for virtual scrolling to work,\n\t// options need to be ordered the same way they're returned from the remote data source\n\tself.settings.sortField\t\t\t= [{field:'$order'},{field:'$score'}];\n\n\n\t// can we load more results for given query?\n\tconst canLoadMore = (query:string):boolean => {\n\n\t\tif( typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions ){\n\t\t\treturn false;\n\t\t}\n\n\t\tif( (query in pagination) && pagination[query] ){\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\tconst clearFilter = (option:TomOption, value:string):boolean => {\n\t\tif( self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0 ){\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t};\n\n\n\t// set the next url that will be\n\tself.setNextUrl = (value:string,next_url:any):void => {\n\t\tpagination[value] = next_url;\n\t};\n\n\t// getUrl() to be used in settings.load()\n\tself.getUrl = (query:string):any =>{\n\n\t\tif( query in pagination ){\n\t\t\tconst next_url = pagination[query];\n\t\t\tpagination[query] = false;\n\t\t\treturn next_url;\n\t\t}\n\n\t\t// if the user goes back to a previous query\n\t\t// we need to load the first page again\n\t\tself.clearPagination();\n\n\t\treturn self.settings.firstUrl.call(self,query);\n\t};\n\n\t// clear pagination\n\tself.clearPagination = ():void =>{\n\t\tpagination = {};\n\t};\n\n\t// don't clear the active option (and cause unwanted dropdown scroll)\n\t// while loading more results\n\tself.hook('instead','clearActiveOption',()=>{\n\n\t\tif( loading_more ){\n\t\t\treturn;\n\t\t}\n\n\t\treturn orig_clearActiveOption.call(self);\n\t});\n\n\t// override the canLoad method\n\tself.hook('instead','canLoad',(query:string)=>{\n\n\t\t// first time the query has been seen\n\t\tif( !(query in pagination) ){\n\t\t\treturn orig_canLoad.call(self,query);\n\t\t}\n\n\t\treturn canLoadMore(query);\n\t});\n\n\n\t// wrap the load\n\tself.hook('instead','loadCallback',( options:TomOption[], optgroups:TomOption[])=>{\n\n\t\tif( !loading_more ){\n\t\t\tself.clearOptions(clearFilter);\n\t\t}else if( load_more_opt ){\n\t\t\tconst first_option = options[0];\n\t\t\tif( first_option !== undefined ){\n\t\t\t\tload_more_opt.dataset.value\t\t= first_option[self.settings.valueField];\n\t\t\t}\n\t\t}\n\n\t\torig_loadCallback.call( self, options, optgroups);\n\n\t\tloading_more = false;\n\t});\n\n\n\t// add templates to dropdown\n\t//\tloading_more if we have another url in the queue\n\t//\tno_more_results if we don't have another url in the queue\n\tself.hook('after','refreshOptions',()=>{\n\n\t\tconst query\t\t= self.lastValue;\n\t\tvar option;\n\n\t\tif( canLoadMore(query) ){\n\n\t\t\toption = self.render('loading_more',{query:query});\n\t\t\tif( option ){\n\t\t\t\toption.setAttribute('data-selectable',''); // so that navigating dropdown with [down] keypresses can navigate to this node\n\t\t\t\tload_more_opt = option;\n\t\t\t}\n\n\t\t}else if( (query in pagination) && !dropdown_content.querySelector('.no-results') ){\n\t\t\toption = self.render('no_more_results',{query:query});\n\t\t}\n\n\t\tif( option ){\n\t\t\taddClasses(option,self.settings.optionClass);\n\t\t\tdropdown_content.append( option );\n\t\t}\n\n\t});\n\n\n\t// add scroll listener and default templates\n\tself.on('initialize',()=>{\n\t\tdefault_values = Object.keys(self.options);\n\t\tdropdown_content = self.dropdown_content;\n\n\t\t// default templates\n\t\tself.settings.render = Object.assign({}, {\n\t\t\tloading_more:() => {\n\t\t\t\treturn `<div class=\"loading-more-results\">Loading more results ... </div>`;\n\t\t\t},\n\t\t\tno_more_results:() =>{\n\t\t\t\treturn `<div class=\"no-more-results\">No more results</div>`;\n\t\t\t}\n\t\t},self.settings.render);\n\n\n\t\t// watch dropdown content scroll position\n\t\tdropdown_content.addEventListener('scroll',()=>{\n\n\t\t\tif( !self.settings.shouldLoadMore.call(self) ){\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true\n\t\t\tif( !canLoadMore(self.lastValue) ){\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// don't call load() too much\n\t\t\tif( loading_more ) return;\n\n\n\t\t\tloading_more = true;\n\t\t\tself.load.call(self,self.lastValue);\n\t\t});\n\t});\n\n};\n"],"names":["iterate","object","callback","Array","isArray","forEach","key","hasOwnProperty","addClasses","elmts","classes","norm_classes","classesArray","castAsArray","map","el","cls","classList","add","args","_classes","trim","split","concat","filter","Boolean","arg","self","orig_canLoad","canLoad","orig_clearActiveOption","clearActiveOption","orig_loadCallback","loadCallback","pagination","dropdown_content","loading_more","load_more_opt","default_values","settings","shouldLoadMore","scroll_percent","clientHeight","scrollHeight","scrollTop","activeOption","selectable","index","from","indexOf","length","firstUrl","sortField","field","canLoadMore","query","maxOptions","children","clearFilter","option","value","items","setNextUrl","next_url","getUrl","clearPagination","call","hook","options","optgroups","clearOptions","first_option","undefined","dataset","valueField","lastValue","render","setAttribute","querySelector","optionClass","append","on","Object","keys","assign","no_more_results","addEventListener","load"],"mappings":"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"}
|