@materializecss/materialize 2.0.3-beta → 2.0.4
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 +1 -1
- package/README.md +16 -18
- package/dist/css/materialize.css +73 -26
- package/dist/css/materialize.min.css +3 -3
- package/dist/js/materialize.js +560 -2015
- package/dist/js/materialize.min.js +3 -3
- package/dist/js/materialize.min.js.map +1 -1
- package/dist/src/buttons.d.ts.map +1 -1
- package/dist/src/cards.d.ts.map +1 -1
- package/dist/src/collapsible.d.ts +1 -0
- package/dist/src/collapsible.d.ts.map +1 -1
- package/dist/src/dropdown.d.ts +1 -0
- package/dist/src/dropdown.d.ts.map +1 -1
- package/dist/src/global.d.ts.map +1 -1
- package/dist/src/materialbox.d.ts +14 -10
- package/dist/src/materialbox.d.ts.map +1 -1
- package/dist/src/modal.d.ts.map +1 -1
- package/dist/src/range.d.ts.map +1 -1
- package/dist/src/scrollspy.d.ts.map +1 -1
- package/dist/src/sidenav.d.ts +25 -25
- package/dist/src/sidenav.d.ts.map +1 -1
- package/dist/src/slider.d.ts +12 -12
- package/dist/src/slider.d.ts.map +1 -1
- package/dist/src/tabs.d.ts +1 -1
- package/dist/src/tabs.d.ts.map +1 -1
- package/dist/src/toasts.d.ts +7 -2
- package/dist/src/toasts.d.ts.map +1 -1
- package/dist/src/tooltip.d.ts.map +1 -1
- package/package.json +29 -44
- package/sass/components/_collapsible.scss +14 -2
- package/sass/components/_materialbox.scss +2 -2
- package/sass/components/_modal.scss +0 -1
- package/sass/components/_tooltip.scss +18 -8
- package/sass/components/_variables.scss +2 -2
- package/Gruntfile.js +0 -385
- package/src/autocomplete.ts +0 -553
- package/src/bounding.ts +0 -6
- package/src/buttons.ts +0 -260
- package/src/cards.ts +0 -53
- package/src/carousel.ts +0 -676
- package/src/characterCounter.ts +0 -117
- package/src/chips.ts +0 -439
- package/src/collapsible.ts +0 -249
- package/src/component.ts +0 -120
- package/src/datepicker.ts +0 -1076
- package/src/dropdown.ts +0 -644
- package/src/edges.ts +0 -6
- package/src/forms.ts +0 -132
- package/src/global.ts +0 -114
- package/src/index.ts +0 -26
- package/src/materialbox.ts +0 -404
- package/src/modal.ts +0 -341
- package/src/parallax.ts +0 -149
- package/src/pushpin.ts +0 -165
- package/src/range.ts +0 -198
- package/src/scrollspy.ts +0 -263
- package/src/select.ts +0 -484
- package/src/sidenav.ts +0 -543
- package/src/slider.ts +0 -474
- package/src/tabs.ts +0 -347
- package/src/tapTarget.ts +0 -273
- package/src/timepicker.ts +0 -832
- package/src/toasts.ts +0 -290
- package/src/tooltip.ts +0 -366
- package/src/utils.ts +0 -271
- package/src/waves.ts +0 -70
package/src/autocomplete.ts
DELETED
|
@@ -1,553 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
import { Dropdown, DropdownOptions } from "./dropdown";
|
|
3
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
4
|
-
|
|
5
|
-
export interface AutocompleteData {
|
|
6
|
-
/**
|
|
7
|
-
* A primitive value that can be converted to string.
|
|
8
|
-
* If "text" is not provided, it will also be used as "option text" as well
|
|
9
|
-
*/
|
|
10
|
-
id: string | number;
|
|
11
|
-
/**
|
|
12
|
-
* This optional attribute is used as "display value" for the current entry.
|
|
13
|
-
* When provided, it will also be taken into consideration by the standard search function.
|
|
14
|
-
*/
|
|
15
|
-
text?: string;
|
|
16
|
-
/**
|
|
17
|
-
* This optional attribute is used to provide a valid image URL to the current option.
|
|
18
|
-
*/
|
|
19
|
-
image?: string;
|
|
20
|
-
/**
|
|
21
|
-
* Optional attributes which describes the option.
|
|
22
|
-
*/
|
|
23
|
-
description?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface AutocompleteOptions extends BaseOptions {
|
|
27
|
-
/**
|
|
28
|
-
* Data object defining autocomplete options with
|
|
29
|
-
* optional icon strings.
|
|
30
|
-
*/
|
|
31
|
-
data: AutocompleteData[];
|
|
32
|
-
/**
|
|
33
|
-
* Flag which can be set if multiple values can be selected. The Result will be an Array.
|
|
34
|
-
* @default false
|
|
35
|
-
*/
|
|
36
|
-
isMultiSelect: boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Callback for when autocompleted.
|
|
39
|
-
*/
|
|
40
|
-
onAutocomplete: (entries: AutocompleteData[]) => void;
|
|
41
|
-
/**
|
|
42
|
-
* Minimum number of characters before autocomplete starts.
|
|
43
|
-
* @default 1
|
|
44
|
-
*/
|
|
45
|
-
minLength: number;
|
|
46
|
-
/**
|
|
47
|
-
* The height of the Menu which can be set via css-property.
|
|
48
|
-
* @default '300px'
|
|
49
|
-
*/
|
|
50
|
-
maxDropDownHeight: string;
|
|
51
|
-
/**
|
|
52
|
-
* Function is called when the input text is altered and data can also be loaded asynchronously.
|
|
53
|
-
* If the results are collected the items in the list can be updated via the function setMenuItems(collectedItems).
|
|
54
|
-
* @param text Searched text.
|
|
55
|
-
* @param autocomplete Current autocomplete instance.
|
|
56
|
-
*/
|
|
57
|
-
onSearch: (text: string, autocomplete: Autocomplete) => void;
|
|
58
|
-
/**
|
|
59
|
-
* If true will render the key from each item directly as HTML.
|
|
60
|
-
* User input MUST be properly sanitized first.
|
|
61
|
-
* @default false
|
|
62
|
-
*/
|
|
63
|
-
allowUnsafeHTML: boolean;
|
|
64
|
-
/**
|
|
65
|
-
* Pass options object to select dropdown initialization.
|
|
66
|
-
* @default {}
|
|
67
|
-
*/
|
|
68
|
-
dropdownOptions: Partial<DropdownOptions>;
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
let _defaults: AutocompleteOptions = {
|
|
72
|
-
data: [], // Autocomplete data set
|
|
73
|
-
onAutocomplete: null, // Callback for when autocompleted
|
|
74
|
-
dropdownOptions: {
|
|
75
|
-
// Default dropdown options
|
|
76
|
-
autoFocus: false,
|
|
77
|
-
closeOnClick: false,
|
|
78
|
-
coverTrigger: false
|
|
79
|
-
},
|
|
80
|
-
minLength: 1, // Min characters before autocomplete starts
|
|
81
|
-
isMultiSelect: false,
|
|
82
|
-
onSearch: (text: string, autocomplete: Autocomplete) => {
|
|
83
|
-
const normSearch = text.toLocaleLowerCase();
|
|
84
|
-
autocomplete.setMenuItems(
|
|
85
|
-
autocomplete.options.data.filter((option) =>
|
|
86
|
-
option.id.toString().toLocaleLowerCase().includes(normSearch)
|
|
87
|
-
|| option.text?.toLocaleLowerCase().includes(normSearch)
|
|
88
|
-
)
|
|
89
|
-
);
|
|
90
|
-
},
|
|
91
|
-
maxDropDownHeight: '300px',
|
|
92
|
-
allowUnsafeHTML: false
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
export class Autocomplete extends Component<AutocompleteOptions> {
|
|
97
|
-
declare el: HTMLInputElement;
|
|
98
|
-
/** If the autocomplete is open. */
|
|
99
|
-
isOpen: boolean;
|
|
100
|
-
/** Number of matching autocomplete options. */
|
|
101
|
-
count: number;
|
|
102
|
-
/** Index of the current selected option. */
|
|
103
|
-
activeIndex: number;
|
|
104
|
-
private oldVal: string;
|
|
105
|
-
private $active: HTMLElement|null;
|
|
106
|
-
private _mousedown: boolean;
|
|
107
|
-
container: HTMLElement;
|
|
108
|
-
/** Instance of the dropdown plugin for this autocomplete. */
|
|
109
|
-
dropdown: Dropdown;
|
|
110
|
-
static _keydown: boolean;
|
|
111
|
-
selectedValues: AutocompleteData[];
|
|
112
|
-
menuItems: AutocompleteData[];
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
constructor(el: HTMLInputElement, options: Partial<AutocompleteOptions>) {
|
|
116
|
-
super(el, options, Autocomplete);
|
|
117
|
-
(this.el as any).M_Autocomplete = this;
|
|
118
|
-
|
|
119
|
-
this.options = {
|
|
120
|
-
...Autocomplete.defaults,
|
|
121
|
-
...options
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
this.isOpen = false;
|
|
125
|
-
this.count = 0;
|
|
126
|
-
this.activeIndex = -1;
|
|
127
|
-
this.oldVal = "";
|
|
128
|
-
this.selectedValues = [];
|
|
129
|
-
this.menuItems = [];
|
|
130
|
-
this.$active = null;
|
|
131
|
-
this._mousedown = false;
|
|
132
|
-
this._setupDropdown();
|
|
133
|
-
this._setupEventHandlers();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
static get defaults(): AutocompleteOptions {
|
|
137
|
-
return _defaults;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Initializes instance of Autocomplete.
|
|
142
|
-
* @param el HTML element.
|
|
143
|
-
* @param options Component options.
|
|
144
|
-
*/
|
|
145
|
-
static init(el: HTMLInputElement, options?: Partial<AutocompleteOptions>): Autocomplete;
|
|
146
|
-
/**
|
|
147
|
-
* Initializes instances of Autocomplete.
|
|
148
|
-
* @param els HTML elements.
|
|
149
|
-
* @param options Component options.
|
|
150
|
-
*/
|
|
151
|
-
static init(els: InitElements<HTMLInputElement | MElement>, options?: Partial<AutocompleteOptions>): Autocomplete[];
|
|
152
|
-
/**
|
|
153
|
-
* Initializes instances of Autocomplete.
|
|
154
|
-
* @param els HTML elements.
|
|
155
|
-
* @param options Component options.
|
|
156
|
-
*/
|
|
157
|
-
static init(els: HTMLInputElement | InitElements<HTMLInputElement | MElement>, options: Partial<AutocompleteOptions> = {}): Autocomplete | Autocomplete[] {
|
|
158
|
-
return super.init(els, options, Autocomplete);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
static getInstance(el: HTMLElement): Autocomplete {
|
|
162
|
-
return (el as any).M_Autocomplete;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
destroy() {
|
|
166
|
-
this._removeEventHandlers();
|
|
167
|
-
this._removeDropdown();
|
|
168
|
-
(this.el as any).M_Autocomplete = undefined;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
_setupEventHandlers() {
|
|
172
|
-
this.el.addEventListener('blur', this._handleInputBlur);
|
|
173
|
-
this.el.addEventListener('keyup', this._handleInputKeyupAndFocus);
|
|
174
|
-
this.el.addEventListener('focus', this._handleInputKeyupAndFocus);
|
|
175
|
-
this.el.addEventListener('keydown', this._handleInputKeydown);
|
|
176
|
-
this.el.addEventListener('click', this._handleInputClick);
|
|
177
|
-
this.container.addEventListener(
|
|
178
|
-
'mousedown',
|
|
179
|
-
this._handleContainerMousedownAndTouchstart
|
|
180
|
-
);
|
|
181
|
-
this.container.addEventListener('mouseup', this._handleContainerMouseupAndTouchend);
|
|
182
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
183
|
-
this.container.addEventListener(
|
|
184
|
-
'touchstart',
|
|
185
|
-
this._handleContainerMousedownAndTouchstart
|
|
186
|
-
);
|
|
187
|
-
this.container.addEventListener('touchend', this._handleContainerMouseupAndTouchend);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
_removeEventHandlers() {
|
|
192
|
-
this.el.removeEventListener('blur', this._handleInputBlur);
|
|
193
|
-
this.el.removeEventListener('keyup', this._handleInputKeyupAndFocus);
|
|
194
|
-
this.el.removeEventListener('focus', this._handleInputKeyupAndFocus);
|
|
195
|
-
this.el.removeEventListener('keydown', this._handleInputKeydown);
|
|
196
|
-
this.el.removeEventListener('click', this._handleInputClick);
|
|
197
|
-
this.container.removeEventListener(
|
|
198
|
-
'mousedown',
|
|
199
|
-
this._handleContainerMousedownAndTouchstart
|
|
200
|
-
);
|
|
201
|
-
this.container.removeEventListener('mouseup', this._handleContainerMouseupAndTouchend);
|
|
202
|
-
|
|
203
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
204
|
-
this.container.removeEventListener(
|
|
205
|
-
'touchstart',
|
|
206
|
-
this._handleContainerMousedownAndTouchstart
|
|
207
|
-
);
|
|
208
|
-
this.container.removeEventListener(
|
|
209
|
-
'touchend',
|
|
210
|
-
this._handleContainerMouseupAndTouchend
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
_setupDropdown() {
|
|
216
|
-
this.container = document.createElement('ul');
|
|
217
|
-
this.container.style.maxHeight = this.options.maxDropDownHeight;
|
|
218
|
-
this.container.id = `autocomplete-options-${Utils.guid()}`;
|
|
219
|
-
this.container.classList.add('autocomplete-content', 'dropdown-content');
|
|
220
|
-
this.el.setAttribute('data-target', this.container.id);
|
|
221
|
-
|
|
222
|
-
// ! Issue in Component Dropdown: _placeDropdown moves dom-position
|
|
223
|
-
this.el.parentElement.appendChild(this.container);
|
|
224
|
-
|
|
225
|
-
// Initialize dropdown
|
|
226
|
-
let dropdownOptions = {
|
|
227
|
-
...Autocomplete.defaults.dropdownOptions,
|
|
228
|
-
...this.options.dropdownOptions
|
|
229
|
-
};
|
|
230
|
-
let userOnItemClick = dropdownOptions.onItemClick;
|
|
231
|
-
// Ensuring the select Option call when user passes custom onItemClick function to dropdown
|
|
232
|
-
dropdownOptions.onItemClick = (li) => {
|
|
233
|
-
if (!li) return;
|
|
234
|
-
const entryID = li.getAttribute('data-id');
|
|
235
|
-
this.selectOption(entryID);
|
|
236
|
-
// Handle user declared onItemClick if needed
|
|
237
|
-
if (userOnItemClick && typeof userOnItemClick === 'function')
|
|
238
|
-
userOnItemClick.call(this.dropdown, this.el);
|
|
239
|
-
};
|
|
240
|
-
this.dropdown = Dropdown.init(this.el, dropdownOptions);
|
|
241
|
-
|
|
242
|
-
// ! Workaround for Label: move label up again
|
|
243
|
-
// TODO: Just use PopperJS in future!
|
|
244
|
-
const label = this.el.parentElement.querySelector('label');
|
|
245
|
-
if (label) this.el.after(label);
|
|
246
|
-
|
|
247
|
-
// Sketchy removal of dropdown click handler
|
|
248
|
-
this.el.removeEventListener('click', this.dropdown._handleClick);
|
|
249
|
-
// Set Value if already set in HTML
|
|
250
|
-
if (this.el.value) this.selectOption(this.el.value);
|
|
251
|
-
// Add StatusInfo
|
|
252
|
-
const div = document.createElement('div');
|
|
253
|
-
div.classList.add('status-info');
|
|
254
|
-
div.setAttribute('style', 'position: absolute;right:0;top:0;');
|
|
255
|
-
this.el.parentElement.appendChild(div);
|
|
256
|
-
this._updateSelectedInfo();
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
_removeDropdown() {
|
|
260
|
-
this.container.parentNode.removeChild(this.container);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
_handleInputBlur = () => {
|
|
264
|
-
if (!this._mousedown) {
|
|
265
|
-
this.close();
|
|
266
|
-
this._resetAutocomplete();
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
_handleInputKeyupAndFocus = (e: KeyboardEvent) => {
|
|
271
|
-
if (e.type === 'keyup') Autocomplete._keydown = false;
|
|
272
|
-
this.count = 0;
|
|
273
|
-
const actualValue = this.el.value.toLocaleLowerCase();
|
|
274
|
-
// Don't capture enter or arrow key usage.
|
|
275
|
-
if (Utils.keys.ENTER.includes(e.key) || Utils.keys.ARROW_UP.includes(e.key) || Utils.keys.ARROW_DOWN.includes(e.key)) return;
|
|
276
|
-
// Check if the input isn't empty
|
|
277
|
-
// Check if focus triggered by tab
|
|
278
|
-
if (this.oldVal !== actualValue && (Utils.tabPressed || e.type !== 'focus')) {
|
|
279
|
-
this.open();
|
|
280
|
-
}
|
|
281
|
-
// Value has changed!
|
|
282
|
-
if (this.oldVal !== actualValue) {
|
|
283
|
-
this._setStatusLoading();
|
|
284
|
-
this.options.onSearch(this.el.value, this);
|
|
285
|
-
}
|
|
286
|
-
// Reset Single-Select when Input cleared
|
|
287
|
-
if (!this.options.isMultiSelect && this.el.value.length === 0) {
|
|
288
|
-
this.selectedValues = [];
|
|
289
|
-
this._triggerChanged();
|
|
290
|
-
}
|
|
291
|
-
this.oldVal = actualValue;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
_handleInputKeydown = (e: KeyboardEvent) => {
|
|
295
|
-
Autocomplete._keydown = true;
|
|
296
|
-
// Arrow keys and enter key usage
|
|
297
|
-
const numItems = this.container.querySelectorAll('li').length;
|
|
298
|
-
// select element on Enter
|
|
299
|
-
if (Utils.keys.ENTER.includes(e.key) && this.activeIndex >= 0) {
|
|
300
|
-
const liElement = this.container.querySelectorAll('li')[this.activeIndex];
|
|
301
|
-
if (liElement) {
|
|
302
|
-
this.selectOption(liElement.getAttribute('data-id'));
|
|
303
|
-
e.preventDefault();
|
|
304
|
-
}
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
// Capture up and down key
|
|
308
|
-
if (Utils.keys.ARROW_UP.includes(e.key) || Utils.keys.ARROW_DOWN.includes(e.key)) {
|
|
309
|
-
e.preventDefault();
|
|
310
|
-
if (Utils.keys.ARROW_UP.includes(e.key) && this.activeIndex > 0) this.activeIndex--;
|
|
311
|
-
if (Utils.keys.ARROW_DOWN.includes(e.key) && this.activeIndex < numItems - 1) this.activeIndex++;
|
|
312
|
-
this.$active?.classList.remove('active');
|
|
313
|
-
if (this.activeIndex >= 0) {
|
|
314
|
-
this.$active = this.container.querySelectorAll('li')[this.activeIndex];
|
|
315
|
-
this.$active?.classList.add('active');
|
|
316
|
-
// Focus selected
|
|
317
|
-
this.container.children[this.activeIndex].scrollIntoView({
|
|
318
|
-
behavior: 'smooth',
|
|
319
|
-
block: 'nearest',
|
|
320
|
-
inline: 'nearest'
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
_handleInputClick = () => {
|
|
327
|
-
this.open();
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
_handleContainerMousedownAndTouchstart = () => {
|
|
331
|
-
this._mousedown = true;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
_handleContainerMouseupAndTouchend = () => {
|
|
335
|
-
this._mousedown = false;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
_resetCurrentElementPosition() {
|
|
339
|
-
this.activeIndex = -1;
|
|
340
|
-
this.$active?.classList.remove('active');
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
_resetAutocomplete() {
|
|
344
|
-
this.container.replaceChildren();
|
|
345
|
-
this._resetCurrentElementPosition();
|
|
346
|
-
this.oldVal = null;
|
|
347
|
-
this.isOpen = false;
|
|
348
|
-
this._mousedown = false;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
_highlightPartialText(input: string, label: string) {
|
|
352
|
-
const start = label.toLocaleLowerCase().indexOf('' + input.toLocaleLowerCase() + '');
|
|
353
|
-
const end = start + input.length - 1;
|
|
354
|
-
//custom filters may return results where the string does not match any part
|
|
355
|
-
if (start == -1 || end == -1) {
|
|
356
|
-
return [label, '', ''];
|
|
357
|
-
}
|
|
358
|
-
return [label.slice(0, start), label.slice(start, end + 1), label.slice(end + 1)];
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
_createDropdownItem(entry: AutocompleteData) {
|
|
362
|
-
const item = document.createElement('li');
|
|
363
|
-
item.setAttribute('data-id', <string>entry.id);
|
|
364
|
-
item.setAttribute(
|
|
365
|
-
'style',
|
|
366
|
-
'display:grid; grid-auto-flow: column; user-select: none; align-items: center;'
|
|
367
|
-
);
|
|
368
|
-
// Checkbox
|
|
369
|
-
if (this.options.isMultiSelect) {
|
|
370
|
-
item.innerHTML = `
|
|
371
|
-
<div class="item-selection" style="text-align:center;">
|
|
372
|
-
<input type="checkbox"${
|
|
373
|
-
this.selectedValues.some((sel) => sel.id === entry.id) ? ' checked="checked"' : ''
|
|
374
|
-
}><span style="padding-left:21px;"></span>
|
|
375
|
-
</div>`;
|
|
376
|
-
}
|
|
377
|
-
// Image
|
|
378
|
-
if (entry.image) {
|
|
379
|
-
const img = document.createElement('img');
|
|
380
|
-
img.classList.add('circle');
|
|
381
|
-
img.src = entry.image;
|
|
382
|
-
item.appendChild(img);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// Text
|
|
386
|
-
const inputText = this.el.value.toLocaleLowerCase();
|
|
387
|
-
const parts = this._highlightPartialText(inputText, (entry.text || entry.id).toString());
|
|
388
|
-
const div = document.createElement('div');
|
|
389
|
-
div.setAttribute('style', 'line-height:1.2;font-weight:500;');
|
|
390
|
-
if (this.options.allowUnsafeHTML) {
|
|
391
|
-
div.innerHTML = parts[0] + '<span class="highlight">' + parts[1] + '</span>' + parts[2];
|
|
392
|
-
} else {
|
|
393
|
-
div.appendChild(document.createTextNode(parts[0]));
|
|
394
|
-
if (parts[1]) {
|
|
395
|
-
const highlight = document.createElement('span');
|
|
396
|
-
highlight.textContent = parts[1];
|
|
397
|
-
highlight.classList.add('highlight');
|
|
398
|
-
div.appendChild(highlight);
|
|
399
|
-
div.appendChild(document.createTextNode(parts[2]));
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
const itemText = document.createElement('div');
|
|
404
|
-
itemText.classList.add('item-text');
|
|
405
|
-
itemText.setAttribute('style', 'padding:5px;overflow:hidden;');
|
|
406
|
-
item.appendChild(itemText);
|
|
407
|
-
item.querySelector('.item-text').appendChild(div);
|
|
408
|
-
// Description
|
|
409
|
-
if (typeof entry.description === 'string' || (typeof entry.description === 'number' && !isNaN(entry.description))) {
|
|
410
|
-
const description = document.createElement('small');
|
|
411
|
-
description.setAttribute(
|
|
412
|
-
'style',
|
|
413
|
-
'line-height:1.3;color:grey;white-space:nowrap;text-overflow:ellipsis;display:block;width:90%;overflow:hidden;'
|
|
414
|
-
);
|
|
415
|
-
description.innerText = entry.description;
|
|
416
|
-
item.querySelector('.item-text').appendChild(description);
|
|
417
|
-
}
|
|
418
|
-
// Set Grid
|
|
419
|
-
const getGridConfig = () => {
|
|
420
|
-
if (this.options.isMultiSelect) {
|
|
421
|
-
if (entry.image) return '40px min-content auto'; // cb-img-txt
|
|
422
|
-
return '40px auto'; // cb-txt
|
|
423
|
-
}
|
|
424
|
-
if (entry.image) return 'min-content auto'; // img-txt
|
|
425
|
-
return 'auto'; // txt
|
|
426
|
-
};
|
|
427
|
-
item.style.gridTemplateColumns = getGridConfig();
|
|
428
|
-
return item;
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
_renderDropdown() {
|
|
432
|
-
this._resetAutocomplete();
|
|
433
|
-
// Check if Data is empty
|
|
434
|
-
if (this.menuItems.length === 0) {
|
|
435
|
-
this.menuItems = this.selectedValues; // Show selected Items
|
|
436
|
-
}
|
|
437
|
-
for (let i = 0; i < this.menuItems.length; i++) {
|
|
438
|
-
const item = this._createDropdownItem(this.menuItems[i]);
|
|
439
|
-
this.container.append(item);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
_setStatusLoading() {
|
|
444
|
-
this.el.parentElement.querySelector(
|
|
445
|
-
'.status-info'
|
|
446
|
-
).innerHTML = `<div style="height:100%;width:50px;"><svg version="1.1" id="L4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100" enable-background="new 0 0 0 0" xml:space="preserve">
|
|
447
|
-
<circle fill="#888c" stroke="none" cx="6" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.1"/></circle>
|
|
448
|
-
<circle fill="#888c" stroke="none" cx="26" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.2"/></circle>
|
|
449
|
-
<circle fill="#888c" stroke="none" cx="46" cy="50" r="6"><animate attributeName="opacity" dur="1s" values="0;1;0" repeatCount="indefinite" begin="0.3"/></circle>
|
|
450
|
-
</svg></div>`;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
_updateSelectedInfo() {
|
|
454
|
-
const statusElement = this.el.parentElement.querySelector('.status-info');
|
|
455
|
-
if (statusElement) {
|
|
456
|
-
if (this.options.isMultiSelect) statusElement.innerHTML = this.selectedValues.length.toString();
|
|
457
|
-
else statusElement.innerHTML = '';
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
_refreshInputText() {
|
|
462
|
-
if (this.selectedValues.length === 1) {
|
|
463
|
-
const entry = this.selectedValues[0];
|
|
464
|
-
this.el.value = entry.text || <string>entry.id; // Write Text to Input
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
_triggerChanged() {
|
|
469
|
-
this.el.dispatchEvent(new Event('change'));
|
|
470
|
-
// Trigger Autocomplete Event
|
|
471
|
-
if (typeof this.options.onAutocomplete === 'function')
|
|
472
|
-
this.options.onAutocomplete.call(this, this.selectedValues);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
/**
|
|
476
|
-
* Show autocomplete.
|
|
477
|
-
*/
|
|
478
|
-
open = () => {
|
|
479
|
-
const inputText = this.el.value.toLocaleLowerCase();
|
|
480
|
-
this._resetAutocomplete();
|
|
481
|
-
if (inputText.length >= this.options.minLength) {
|
|
482
|
-
this.isOpen = true;
|
|
483
|
-
this._renderDropdown();
|
|
484
|
-
}
|
|
485
|
-
// Open dropdown
|
|
486
|
-
if (!this.dropdown.isOpen) {
|
|
487
|
-
setTimeout(() => {
|
|
488
|
-
this.dropdown.open();
|
|
489
|
-
}, 100);
|
|
490
|
-
}
|
|
491
|
-
else this.dropdown.recalculateDimensions(); // Recalculate dropdown when its already open
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* Hide autocomplete.
|
|
496
|
-
*/
|
|
497
|
-
close = () => {
|
|
498
|
-
this.dropdown.close();
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Updates the visible or selectable items shown in the menu.
|
|
503
|
-
* @param menuItems Items to be available.
|
|
504
|
-
*/
|
|
505
|
-
setMenuItems(menuItems: AutocompleteData[]) {
|
|
506
|
-
this.menuItems = menuItems;
|
|
507
|
-
this.open();
|
|
508
|
-
this._updateSelectedInfo();
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
/**
|
|
512
|
-
* Sets selected values.
|
|
513
|
-
* @param entries
|
|
514
|
-
*/
|
|
515
|
-
setValues(entries: AutocompleteData[]) {
|
|
516
|
-
this.selectedValues = entries;
|
|
517
|
-
this._updateSelectedInfo();
|
|
518
|
-
if (!this.options.isMultiSelect) {
|
|
519
|
-
this._refreshInputText();
|
|
520
|
-
}
|
|
521
|
-
this._triggerChanged();
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
/**
|
|
525
|
-
* Select a specific autocomplete option via id-property.
|
|
526
|
-
* @param id The id of a data-entry.
|
|
527
|
-
*/
|
|
528
|
-
selectOption(id: number | string) {
|
|
529
|
-
const entry = this.menuItems.find((item) => item.id == id);
|
|
530
|
-
if (!entry) return;
|
|
531
|
-
// Toggle Checkbox
|
|
532
|
-
const li = this.container.querySelector('li[data-id="'+id+'"]');
|
|
533
|
-
if (!li) return;
|
|
534
|
-
if (this.options.isMultiSelect) {
|
|
535
|
-
const checkbox = <HTMLInputElement|null>li.querySelector('input[type="checkbox"]');
|
|
536
|
-
checkbox.checked = !checkbox.checked;
|
|
537
|
-
if (checkbox.checked) this.selectedValues.push(entry);
|
|
538
|
-
else
|
|
539
|
-
this.selectedValues = this.selectedValues.filter(
|
|
540
|
-
(selectedEntry) => selectedEntry.id !== entry.id
|
|
541
|
-
);
|
|
542
|
-
this.el.focus();
|
|
543
|
-
} else {
|
|
544
|
-
// Single-Select
|
|
545
|
-
this.selectedValues = [entry];
|
|
546
|
-
this._refreshInputText();
|
|
547
|
-
this._resetAutocomplete();
|
|
548
|
-
this.close();
|
|
549
|
-
}
|
|
550
|
-
this._updateSelectedInfo();
|
|
551
|
-
this._triggerChanged();
|
|
552
|
-
}
|
|
553
|
-
}
|