@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,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* microplugin.js
|
|
3
|
+
* Copyright (c) 2013 Brian Reavis & contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
6
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*
|
|
14
|
+
* @author Brian Reavis <brian@thirdroute.com>
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
type TSettings = {
|
|
18
|
+
[key:string]:any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type TPlugins = {
|
|
22
|
+
names: string[],
|
|
23
|
+
settings: TSettings,
|
|
24
|
+
requested: {[key:string]:boolean},
|
|
25
|
+
loaded: {[key:string]:any}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type TPluginItem = {name:string,options:{}};
|
|
29
|
+
export type TPluginHash = {[key:string]:{}};
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
export default function MicroPlugin(Interface: any ){
|
|
35
|
+
|
|
36
|
+
Interface.plugins = {};
|
|
37
|
+
|
|
38
|
+
return class extends Interface{
|
|
39
|
+
|
|
40
|
+
public plugins:TPlugins = {
|
|
41
|
+
names : [],
|
|
42
|
+
settings : {},
|
|
43
|
+
requested : {},
|
|
44
|
+
loaded : {}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Registers a plugin.
|
|
49
|
+
*
|
|
50
|
+
* @param {function} fn
|
|
51
|
+
*/
|
|
52
|
+
static define(name:string, fn:(this:any,settings:TSettings)=>any){
|
|
53
|
+
Interface.plugins[name] = {
|
|
54
|
+
'name' : name,
|
|
55
|
+
'fn' : fn
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Initializes the listed plugins (with options).
|
|
62
|
+
* Acceptable formats:
|
|
63
|
+
*
|
|
64
|
+
* List (without options):
|
|
65
|
+
* ['a', 'b', 'c']
|
|
66
|
+
*
|
|
67
|
+
* List (with options):
|
|
68
|
+
* [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
|
|
69
|
+
*
|
|
70
|
+
* Hash (with options):
|
|
71
|
+
* {'a': { ... }, 'b': { ... }, 'c': { ... }}
|
|
72
|
+
*
|
|
73
|
+
* @param {array|object} plugins
|
|
74
|
+
*/
|
|
75
|
+
initializePlugins(plugins:string[]|TPluginItem[]|TPluginHash) {
|
|
76
|
+
var key, name;
|
|
77
|
+
const self = this;
|
|
78
|
+
const queue:string[] = [];
|
|
79
|
+
|
|
80
|
+
if (Array.isArray(plugins)) {
|
|
81
|
+
plugins.forEach((plugin:string|TPluginItem)=>{
|
|
82
|
+
if (typeof plugin === 'string') {
|
|
83
|
+
queue.push(plugin);
|
|
84
|
+
} else {
|
|
85
|
+
self.plugins.settings[plugin.name] = plugin.options;
|
|
86
|
+
queue.push(plugin.name);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
} else if (plugins) {
|
|
90
|
+
for (key in plugins) {
|
|
91
|
+
if (plugins.hasOwnProperty(key)) {
|
|
92
|
+
self.plugins.settings[key] = plugins[key];
|
|
93
|
+
queue.push(key);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
while( name = queue.shift() ){
|
|
99
|
+
self.require(name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
loadPlugin(name:string) {
|
|
104
|
+
var self = this;
|
|
105
|
+
var plugins = self.plugins;
|
|
106
|
+
var plugin = Interface.plugins[name];
|
|
107
|
+
|
|
108
|
+
if (!Interface.plugins.hasOwnProperty(name)) {
|
|
109
|
+
throw new Error('Unable to find "' + name + '" plugin');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
plugins.requested[name] = true;
|
|
113
|
+
plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
|
|
114
|
+
plugins.names.push(name);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Initializes a plugin.
|
|
119
|
+
*
|
|
120
|
+
*/
|
|
121
|
+
require(name:string) {
|
|
122
|
+
var self = this;
|
|
123
|
+
var plugins = self.plugins;
|
|
124
|
+
|
|
125
|
+
if (!self.plugins.loaded.hasOwnProperty(name)) {
|
|
126
|
+
if (plugins.requested[name]) {
|
|
127
|
+
throw new Error('Plugin has circular dependency ("' + name + '")');
|
|
128
|
+
}
|
|
129
|
+
self.loadPlugin(name);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return plugins.loaded[name];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
}
|
package/src/defaults.ts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
export default {
|
|
3
|
+
options: [],
|
|
4
|
+
optgroups: [],
|
|
5
|
+
|
|
6
|
+
plugins: [],
|
|
7
|
+
delimiter: ',',
|
|
8
|
+
splitOn: null, // regexp or string for splitting up values from a paste command
|
|
9
|
+
persist: true,
|
|
10
|
+
diacritics: true,
|
|
11
|
+
create: null,
|
|
12
|
+
createOnBlur: false,
|
|
13
|
+
createFilter: null,
|
|
14
|
+
clearAfterSelect: false,
|
|
15
|
+
highlight: true,
|
|
16
|
+
openOnFocus: true,
|
|
17
|
+
shouldOpen: null,
|
|
18
|
+
maxOptions: 50,
|
|
19
|
+
maxItems: null,
|
|
20
|
+
hideSelected: null,
|
|
21
|
+
duplicates: false,
|
|
22
|
+
addPrecedence: false,
|
|
23
|
+
selectOnTab: false,
|
|
24
|
+
preload: null,
|
|
25
|
+
allowEmptyOption: false,
|
|
26
|
+
//closeAfterSelect: false,
|
|
27
|
+
refreshThrottle: 300,
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
loadThrottle: 300,
|
|
31
|
+
loadingClass: 'loading',
|
|
32
|
+
|
|
33
|
+
dataAttr: null, //'data-data',
|
|
34
|
+
optgroupField: 'optgroup',
|
|
35
|
+
valueField: 'value',
|
|
36
|
+
labelField: 'text',
|
|
37
|
+
disabledField: 'disabled',
|
|
38
|
+
optgroupLabelField: 'label',
|
|
39
|
+
optgroupValueField: 'value',
|
|
40
|
+
lockOptgroupOrder: false,
|
|
41
|
+
|
|
42
|
+
sortField: '$order',
|
|
43
|
+
searchField: ['text'],
|
|
44
|
+
searchConjunction: 'and',
|
|
45
|
+
|
|
46
|
+
mode: null,
|
|
47
|
+
wrapperClass: 'ts-wrapper',
|
|
48
|
+
controlClass: 'ts-control',
|
|
49
|
+
dropdownClass: 'ts-dropdown',
|
|
50
|
+
dropdownContentClass: 'ts-dropdown-content',
|
|
51
|
+
itemClass: 'item',
|
|
52
|
+
optionClass: 'option',
|
|
53
|
+
|
|
54
|
+
dropdownParent: null,
|
|
55
|
+
controlInput: '<input type="text" autocomplete="off" size="1" />',
|
|
56
|
+
|
|
57
|
+
copyClassesToDropdown: false,
|
|
58
|
+
|
|
59
|
+
placeholder: null,
|
|
60
|
+
hidePlaceholder: null,
|
|
61
|
+
|
|
62
|
+
shouldLoad: function(query:string):boolean{
|
|
63
|
+
return query.length > 0;
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
load : null, // function(query, callback) { ... }
|
|
68
|
+
score : null, // function(search) { ... }
|
|
69
|
+
onInitialize : null, // function() { ... }
|
|
70
|
+
onChange : null, // function(value) { ... }
|
|
71
|
+
onItemAdd : null, // function(value, $item) { ... }
|
|
72
|
+
onItemRemove : null, // function(value) { ... }
|
|
73
|
+
onClear : null, // function() { ... }
|
|
74
|
+
onOptionAdd : null, // function(value, data) { ... }
|
|
75
|
+
onOptionRemove : null, // function(value) { ... }
|
|
76
|
+
onOptionClear : null, // function() { ... }
|
|
77
|
+
onOptionGroupAdd : null, // function(id, data) { ... }
|
|
78
|
+
onOptionGroupRemove : null, // function(id) { ... }
|
|
79
|
+
onOptionGroupClear : null, // function() { ... }
|
|
80
|
+
onDropdownOpen : null, // function(dropdown) { ... }
|
|
81
|
+
onDropdownClose : null, // function(dropdown) { ... }
|
|
82
|
+
onType : null, // function(str) { ... }
|
|
83
|
+
onDelete : null, // function(values) { ... }
|
|
84
|
+
*/
|
|
85
|
+
|
|
86
|
+
render: {
|
|
87
|
+
/*
|
|
88
|
+
item: null,
|
|
89
|
+
optgroup: null,
|
|
90
|
+
optgroup_header: null,
|
|
91
|
+
option: null,
|
|
92
|
+
option_create: null
|
|
93
|
+
*/
|
|
94
|
+
}
|
|
95
|
+
};
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import defaults from './defaults.ts';
|
|
2
|
+
import { hash_key, iterate } from './utils.ts';
|
|
3
|
+
import { TomOption, TomSettings, RecursivePartial } from './types/index.ts';
|
|
4
|
+
import { TomInput } from './types/index.ts';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
export default function getSettings( input:TomInput, settings_user:RecursivePartial<TomSettings>):TomSettings{
|
|
8
|
+
var settings:TomSettings = Object.assign({}, defaults, settings_user);
|
|
9
|
+
|
|
10
|
+
var attr_data = settings.dataAttr;
|
|
11
|
+
var field_label = settings.labelField;
|
|
12
|
+
var field_value = settings.valueField;
|
|
13
|
+
var field_disabled = settings.disabledField;
|
|
14
|
+
var field_optgroup = settings.optgroupField;
|
|
15
|
+
var field_optgroup_label = settings.optgroupLabelField;
|
|
16
|
+
var field_optgroup_value = settings.optgroupValueField;
|
|
17
|
+
|
|
18
|
+
var tag_name = input.tagName.toLowerCase();
|
|
19
|
+
var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');
|
|
20
|
+
|
|
21
|
+
if (!placeholder && !settings.allowEmptyOption) {
|
|
22
|
+
let option = input.querySelector('option[value=""]');
|
|
23
|
+
if( option ){
|
|
24
|
+
placeholder = option.textContent;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var settings_element:{
|
|
30
|
+
placeholder : null|string,
|
|
31
|
+
options : TomOption[],
|
|
32
|
+
optgroups : TomOption[],
|
|
33
|
+
items : string[],
|
|
34
|
+
maxItems : null|number,
|
|
35
|
+
} = {
|
|
36
|
+
placeholder : placeholder,
|
|
37
|
+
options : [],
|
|
38
|
+
optgroups : [],
|
|
39
|
+
items : [],
|
|
40
|
+
maxItems : null,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Initialize from a <select> element.
|
|
46
|
+
*
|
|
47
|
+
*/
|
|
48
|
+
var init_select = () => {
|
|
49
|
+
var tagName;
|
|
50
|
+
var options = settings_element.options;
|
|
51
|
+
var optionsMap:{[key:string]:any} = {};
|
|
52
|
+
var group_count = 1;
|
|
53
|
+
let $order = 0;
|
|
54
|
+
|
|
55
|
+
var readData = (el:HTMLElement):TomOption => {
|
|
56
|
+
|
|
57
|
+
var data = Object.assign({},el.dataset); // get plain object from DOMStringMap
|
|
58
|
+
var json = attr_data && data[attr_data];
|
|
59
|
+
|
|
60
|
+
if( typeof json === 'string' && json.length ){
|
|
61
|
+
data = Object.assign(data,JSON.parse(json));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return data;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
var addOption = (option:HTMLOptionElement, group?:string) => {
|
|
68
|
+
|
|
69
|
+
var value = hash_key(option.value);
|
|
70
|
+
if ( value == null ) return;
|
|
71
|
+
if ( !value && !settings.allowEmptyOption) return;
|
|
72
|
+
|
|
73
|
+
// if the option already exists, it's probably been
|
|
74
|
+
// duplicated in another optgroup. in this case, push
|
|
75
|
+
// the current group to the "optgroup" property on the
|
|
76
|
+
// existing option so that it's rendered in both places.
|
|
77
|
+
if (optionsMap.hasOwnProperty(value)) {
|
|
78
|
+
if (group) {
|
|
79
|
+
var arr = optionsMap[value][field_optgroup];
|
|
80
|
+
if (!arr) {
|
|
81
|
+
optionsMap[value][field_optgroup] = group;
|
|
82
|
+
} else if (!Array.isArray(arr)) {
|
|
83
|
+
optionsMap[value][field_optgroup] = [arr, group];
|
|
84
|
+
} else {
|
|
85
|
+
arr.push(group);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}else{
|
|
90
|
+
|
|
91
|
+
var option_data = readData(option);
|
|
92
|
+
option_data[field_label] = option_data[field_label] || option.textContent;
|
|
93
|
+
option_data[field_value] = option_data[field_value] || value;
|
|
94
|
+
option_data[field_disabled] = option_data[field_disabled] || option.disabled;
|
|
95
|
+
option_data[field_optgroup] = option_data[field_optgroup] || group;
|
|
96
|
+
option_data.$option = option;
|
|
97
|
+
option_data.$order = option_data.$order || ++$order;
|
|
98
|
+
|
|
99
|
+
optionsMap[value] = option_data;
|
|
100
|
+
options.push(option_data);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if( option.selected ){
|
|
104
|
+
settings_element.items.push(value);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
var addGroup = ( optgroup:HTMLOptGroupElement ) => {
|
|
109
|
+
var id:string, optgroup_data
|
|
110
|
+
|
|
111
|
+
optgroup_data = readData(optgroup);
|
|
112
|
+
optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';
|
|
113
|
+
optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;
|
|
114
|
+
optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;
|
|
115
|
+
optgroup_data.$order = optgroup_data.$order || ++$order;
|
|
116
|
+
|
|
117
|
+
settings_element.optgroups.push(optgroup_data);
|
|
118
|
+
|
|
119
|
+
id = optgroup_data[field_optgroup_value];
|
|
120
|
+
|
|
121
|
+
iterate(optgroup.children, (option)=>{
|
|
122
|
+
addOption(option as HTMLOptionElement, id);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;
|
|
128
|
+
|
|
129
|
+
iterate(input.children,(child)=>{
|
|
130
|
+
tagName = child.tagName.toLowerCase();
|
|
131
|
+
if (tagName === 'optgroup') {
|
|
132
|
+
addGroup(child as HTMLOptGroupElement);
|
|
133
|
+
} else if (tagName === 'option') {
|
|
134
|
+
addOption(child as HTMLOptionElement);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Initialize from a <input type="text"> element.
|
|
143
|
+
*
|
|
144
|
+
*/
|
|
145
|
+
var init_textbox = () => {
|
|
146
|
+
const data_raw = input.getAttribute(attr_data);
|
|
147
|
+
|
|
148
|
+
if (!data_raw) {
|
|
149
|
+
var value = input.value.trim() || '';
|
|
150
|
+
if (!settings.allowEmptyOption && !value.length) return;
|
|
151
|
+
const values = value.split(settings.delimiter);
|
|
152
|
+
|
|
153
|
+
iterate( values, (value) => {
|
|
154
|
+
const option:TomOption = {};
|
|
155
|
+
option[field_label] = value;
|
|
156
|
+
option[field_value] = value;
|
|
157
|
+
settings_element.options.push(option);
|
|
158
|
+
});
|
|
159
|
+
settings_element.items = values;
|
|
160
|
+
} else {
|
|
161
|
+
settings_element.options = JSON.parse(data_raw);
|
|
162
|
+
iterate( settings_element.options, (opt) => {
|
|
163
|
+
settings_element.items.push(opt[field_value]);
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
if (tag_name === 'select') {
|
|
170
|
+
init_select();
|
|
171
|
+
} else {
|
|
172
|
+
init_textbox();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return Object.assign( {}, defaults, settings_element, settings_user) as TomSettings;
|
|
176
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin: "dropdown_input" (Tom Select)
|
|
3
|
+
* Copyright (c) contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
6
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type TomSelect from '../../tom-select.ts';
|
|
17
|
+
import { nodeIndex, removeClasses } from '../../vanilla.ts';
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
export default function(this:TomSelect) {
|
|
21
|
+
var self = this;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Moves the caret to the specified index.
|
|
25
|
+
*
|
|
26
|
+
* The input must be moved by leaving it in place and moving the
|
|
27
|
+
* siblings, due to the fact that focus cannot be restored once lost
|
|
28
|
+
* on mobile webkit devices
|
|
29
|
+
*
|
|
30
|
+
*/
|
|
31
|
+
self.hook('instead','setCaret',(new_pos:number) => {
|
|
32
|
+
|
|
33
|
+
if( self.settings.mode === 'single' || !self.control.contains(self.control_input) ) {
|
|
34
|
+
new_pos = self.items.length;
|
|
35
|
+
} else {
|
|
36
|
+
new_pos = Math.max(0, Math.min(self.items.length, new_pos));
|
|
37
|
+
|
|
38
|
+
if( new_pos != self.caretPos && !self.isPending ){
|
|
39
|
+
|
|
40
|
+
self.controlChildren().forEach((child,j) => {
|
|
41
|
+
if( j < new_pos ){
|
|
42
|
+
self.control_input.insertAdjacentElement('beforebegin', child );
|
|
43
|
+
} else {
|
|
44
|
+
self.control.appendChild( child );
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
self.caretPos = new_pos;
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
self.hook('instead','moveCaret',(direction:number) => {
|
|
54
|
+
|
|
55
|
+
if( !self.isFocused ) return;
|
|
56
|
+
|
|
57
|
+
// move caret before or after selected items
|
|
58
|
+
const last_active = self.getLastActive(direction);
|
|
59
|
+
if( last_active ){
|
|
60
|
+
const idx = nodeIndex(last_active);
|
|
61
|
+
self.setCaret(direction > 0 ? idx + 1: idx);
|
|
62
|
+
self.setActiveItem();
|
|
63
|
+
removeClasses(last_active as HTMLElement,'last-active');
|
|
64
|
+
|
|
65
|
+
// move caret left or right of current position
|
|
66
|
+
}else{
|
|
67
|
+
self.setCaret(self.caretPos + direction);
|
|
68
|
+
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin: "change_listener" (Tom Select)
|
|
3
|
+
* Copyright (c) contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
6
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type TomSelect from '../../tom-select.ts';
|
|
17
|
+
import { addEvent } from '../../utils.ts';
|
|
18
|
+
|
|
19
|
+
export default function(this:TomSelect) {
|
|
20
|
+
addEvent(this.input,'change',()=>{
|
|
21
|
+
this.sync();
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin: "checkbox_options" (Tom Select)
|
|
3
|
+
* Copyright (c) contributors
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
|
|
6
|
+
* file except in compliance with the License. You may obtain a copy of the License at:
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
10
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
11
|
+
* ANY KIND, either express or implied. See the License for the specific language
|
|
12
|
+
* governing permissions and limitations under the License.
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type TomSelect from '../../tom-select.ts';
|
|
17
|
+
import { TomTemplate } from '../../types/index.ts';
|
|
18
|
+
import { preventDefault, hash_key } from '../../utils.ts';
|
|
19
|
+
import { getDom } from '../../vanilla.ts';
|
|
20
|
+
import { CBOptions } from './types.ts';
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export default function(this:TomSelect, userOptions:CBOptions) {
|
|
24
|
+
var self = this;
|
|
25
|
+
var orig_onOptionSelect = self.onOptionSelect;
|
|
26
|
+
|
|
27
|
+
self.settings.hideSelected = false;
|
|
28
|
+
|
|
29
|
+
const cbOptions : CBOptions = Object.assign({
|
|
30
|
+
// so that the user may add different ones as well
|
|
31
|
+
className : "tomselect-checkbox",
|
|
32
|
+
|
|
33
|
+
// the following default to the historic plugin's values
|
|
34
|
+
checkedClassNames : undefined,
|
|
35
|
+
uncheckedClassNames : undefined,
|
|
36
|
+
}, userOptions);
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
var UpdateChecked = function(checkbox:HTMLInputElement, toCheck : boolean) {
|
|
40
|
+
if( toCheck ){
|
|
41
|
+
checkbox.checked = true;
|
|
42
|
+
if (cbOptions.uncheckedClassNames) {
|
|
43
|
+
checkbox.classList.remove(...cbOptions.uncheckedClassNames);
|
|
44
|
+
}
|
|
45
|
+
if (cbOptions.checkedClassNames) {
|
|
46
|
+
checkbox.classList.add(...cbOptions.checkedClassNames);
|
|
47
|
+
}
|
|
48
|
+
}else{
|
|
49
|
+
checkbox.checked = false;
|
|
50
|
+
if (cbOptions.checkedClassNames) {
|
|
51
|
+
checkbox.classList.remove(...cbOptions.checkedClassNames);
|
|
52
|
+
}
|
|
53
|
+
if (cbOptions.uncheckedClassNames) {
|
|
54
|
+
checkbox.classList.add(...cbOptions.uncheckedClassNames);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// update the checkbox for an option
|
|
60
|
+
var UpdateCheckbox = function(option:HTMLElement){
|
|
61
|
+
setTimeout(()=>{
|
|
62
|
+
var checkbox = option.querySelector('input.' + cbOptions.className);
|
|
63
|
+
if( checkbox instanceof HTMLInputElement ){
|
|
64
|
+
UpdateChecked(checkbox, option.classList.contains('selected'));
|
|
65
|
+
}
|
|
66
|
+
},1);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// add checkbox to option template
|
|
70
|
+
self.hook('after','setupTemplates',() => {
|
|
71
|
+
|
|
72
|
+
var orig_render_option = self.settings.render.option;
|
|
73
|
+
|
|
74
|
+
self.settings.render.option = ((data, escape_html) => {
|
|
75
|
+
var rendered = getDom(orig_render_option.call(self, data, escape_html));
|
|
76
|
+
var checkbox = document.createElement('input');
|
|
77
|
+
if (cbOptions.className) {
|
|
78
|
+
checkbox.classList.add(cbOptions.className);
|
|
79
|
+
}
|
|
80
|
+
checkbox.addEventListener('click',function(evt){
|
|
81
|
+
preventDefault(evt);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
checkbox.type = 'checkbox';
|
|
85
|
+
const hashed = hash_key(data[self.settings.valueField]);
|
|
86
|
+
|
|
87
|
+
UpdateChecked(checkbox, !!(hashed && self.items.indexOf(hashed) > -1) );
|
|
88
|
+
|
|
89
|
+
rendered.prepend(checkbox);
|
|
90
|
+
return rendered;
|
|
91
|
+
}) satisfies TomTemplate;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// uncheck when item removed
|
|
95
|
+
self.on('item_remove',(value:string) => {
|
|
96
|
+
var option = self.getOption(value);
|
|
97
|
+
|
|
98
|
+
if( option ){ // if dropdown hasn't been opened yet, the option won't exist
|
|
99
|
+
option.classList.remove('selected'); // selected class won't be removed yet
|
|
100
|
+
UpdateCheckbox(option);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// check when item added
|
|
105
|
+
self.on('item_add',(value:string) => {
|
|
106
|
+
var option = self.getOption(value);
|
|
107
|
+
|
|
108
|
+
if( option ){ // if dropdown hasn't been opened yet, the option won't exist
|
|
109
|
+
UpdateCheckbox(option);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
// remove items when selected option is clicked
|
|
115
|
+
self.hook('instead','onOptionSelect',( evt:KeyboardEvent, option:HTMLElement )=>{
|
|
116
|
+
|
|
117
|
+
if( option.classList.contains('selected') ){
|
|
118
|
+
option.classList.remove('selected')
|
|
119
|
+
self.removeItem(option.dataset.value);
|
|
120
|
+
self.refreshOptions();
|
|
121
|
+
preventDefault(evt,true);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
orig_onOptionSelect.call(self, evt, option);
|
|
126
|
+
|
|
127
|
+
UpdateCheckbox(option);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
export type CBOptions = {
|
|
3
|
+
/**
|
|
4
|
+
* a unique class name for the checkbox to find the input
|
|
5
|
+
*/
|
|
6
|
+
className ?: string;
|
|
7
|
+
/**
|
|
8
|
+
* class name to add if checkbox is checked and remove otherwise
|
|
9
|
+
*/
|
|
10
|
+
checkedClassNames ?: string[],
|
|
11
|
+
/**
|
|
12
|
+
* class name to add if checkbox was not checked and remove otherwise
|
|
13
|
+
*/
|
|
14
|
+
uncheckedClassNames ?: string[],
|
|
15
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* stylelint-disable function-name-case */
|
|
2
|
+
|
|
3
|
+
.plugin-clear_button {
|
|
4
|
+
--ts-pr-clear-button: 1em;
|
|
5
|
+
|
|
6
|
+
.clear-button{
|
|
7
|
+
opacity: 0;
|
|
8
|
+
position: absolute;
|
|
9
|
+
top: 50%;
|
|
10
|
+
transform: translateY(-50%);
|
|
11
|
+
right: calc(#{$select-padding-x} - #{$select-padding-item-x});
|
|
12
|
+
margin-right: 0 !important;
|
|
13
|
+
background: transparent !important;
|
|
14
|
+
transition: opacity 0.5s;
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
&.form-select .clear-button,
|
|
19
|
+
&.single .clear-button {
|
|
20
|
+
|
|
21
|
+
@if variable-exists(select-padding-dropdown-item-x) {
|
|
22
|
+
right: Max(var(--ts-pr-caret), #{$select-padding-dropdown-item-x});
|
|
23
|
+
}
|
|
24
|
+
@else{
|
|
25
|
+
right: Max(var(--ts-pr-caret), calc(#{$select-padding-x} - #{$select-padding-item-x}));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
&.focus.has-items .clear-button,
|
|
30
|
+
&:not(.disabled):hover.has-items .clear-button{
|
|
31
|
+
opacity: 1;
|
|
32
|
+
}
|
|
33
|
+
}
|