@materializecss/materialize 1.2.0 → 1.2.2
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/Gruntfile.js +722 -712
- package/LICENSE +21 -21
- package/README.md +91 -91
- package/dist/css/materialize.css +78 -137
- package/dist/css/materialize.min.css +12 -12
- package/dist/js/materialize.js +1502 -1378
- package/dist/js/materialize.min.js +6 -6
- package/extras/noUiSlider/nouislider.css +403 -403
- package/extras/noUiSlider/nouislider.js +2147 -2147
- package/js/anime.min.js +34 -34
- package/js/autocomplete.js +479 -479
- package/js/buttons.js +354 -354
- package/js/cards.js +40 -40
- package/js/carousel.js +732 -732
- package/js/cash.js +960 -960
- package/js/characterCounter.js +136 -136
- package/js/chips.js +486 -486
- package/js/collapsible.js +275 -275
- package/js/component.js +44 -44
- package/js/datepicker.js +983 -983
- package/js/dropdown.js +669 -669
- package/js/forms.js +285 -285
- package/js/global.js +428 -428
- package/js/materialbox.js +453 -453
- package/js/modal.js +382 -382
- package/js/parallax.js +138 -138
- package/js/pushpin.js +148 -148
- package/js/range.js +263 -263
- package/js/scrollspy.js +295 -295
- package/js/select.js +391 -391
- package/js/sidenav.js +583 -583
- package/js/slider.js +497 -359
- package/js/tabs.js +402 -402
- package/js/tapTarget.js +315 -315
- package/js/timepicker.js +712 -712
- package/js/toasts.js +325 -325
- package/js/tooltip.js +320 -320
- package/js/waves.js +614 -614
- package/package.json +87 -84
- package/sass/components/_badges.scss +55 -55
- package/sass/components/_buttons.scss +322 -322
- package/sass/components/_cards.scss +195 -195
- package/sass/components/_carousel.scss +90 -90
- package/sass/components/_chips.scss +96 -96
- package/sass/components/_collapsible.scss +91 -91
- package/sass/components/_collection.scss +106 -106
- package/sass/components/_color-classes.scss +32 -32
- package/sass/components/_color-variables.scss +370 -370
- package/sass/components/_datepicker.scss +191 -191
- package/sass/components/_dropdown.scss +84 -84
- package/sass/components/_global.scss +646 -646
- package/sass/components/_grid.scss +158 -158
- package/sass/components/_icons-material-design.scss +5 -5
- package/sass/components/_materialbox.scss +42 -42
- package/sass/components/_modal.scss +97 -97
- package/sass/components/_navbar.scss +208 -208
- package/sass/components/_normalize.scss +447 -447
- package/sass/components/_preloader.scss +334 -334
- package/sass/components/_pulse.scss +34 -34
- package/sass/components/_sidenav.scss +214 -214
- package/sass/components/_slider.scss +100 -91
- package/sass/components/_table_of_contents.scss +33 -33
- package/sass/components/_tabs.scss +99 -99
- package/sass/components/_tapTarget.scss +103 -103
- package/sass/components/_timepicker.scss +199 -199
- package/sass/components/_toast.scss +58 -58
- package/sass/components/_tooltip.scss +32 -32
- package/sass/components/_transitions.scss +12 -12
- package/sass/components/_typography.scss +62 -62
- package/sass/components/_variables.scss +352 -352
- package/sass/components/_waves.scss +187 -187
- package/sass/components/forms/_checkboxes.scss +200 -200
- package/sass/components/forms/_file-input.scss +44 -44
- package/sass/components/forms/_forms.scss +22 -22
- package/sass/components/forms/_input-fields.scss +388 -388
- package/sass/components/forms/_radio-buttons.scss +115 -115
- package/sass/components/forms/_range.scss +161 -161
- package/sass/components/forms/_select.scss +199 -199
- package/sass/components/forms/_switches.scss +91 -91
- package/sass/materialize.scss +42 -42
- package/sass/_style.scss +0 -929
- package/sass/ghpages-materialize.scss +0 -7
package/js/autocomplete.js
CHANGED
|
@@ -1,479 +1,479 @@
|
|
|
1
|
-
(function($) {
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
let _defaults = {
|
|
5
|
-
data: {}, // Autocomplete data set
|
|
6
|
-
limit: Infinity, // Limit of results the autocomplete shows
|
|
7
|
-
onAutocomplete: null, // Callback for when autocompleted
|
|
8
|
-
dropdownOptions: {
|
|
9
|
-
// Default dropdown options
|
|
10
|
-
autoFocus: false,
|
|
11
|
-
closeOnClick: false,
|
|
12
|
-
coverTrigger: false
|
|
13
|
-
},
|
|
14
|
-
minLength: 1, // Min characters before autocomplete starts
|
|
15
|
-
sortFunction: function(a, b, inputString) {
|
|
16
|
-
// Sort function for sorting autocomplete results
|
|
17
|
-
return a.indexOf(inputString) - b.indexOf(inputString);
|
|
18
|
-
},
|
|
19
|
-
allowUnsafeHTML: false
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @class
|
|
24
|
-
*
|
|
25
|
-
*/
|
|
26
|
-
class Autocomplete extends Component {
|
|
27
|
-
/**
|
|
28
|
-
* Construct Autocomplete instance
|
|
29
|
-
* @constructor
|
|
30
|
-
* @param {Element} el
|
|
31
|
-
* @param {Object} options
|
|
32
|
-
*/
|
|
33
|
-
constructor(el, options) {
|
|
34
|
-
super(Autocomplete, el, options);
|
|
35
|
-
|
|
36
|
-
this.el.M_Autocomplete = this;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Options for the autocomplete
|
|
40
|
-
* @member Autocomplete#options
|
|
41
|
-
* @prop {Number} duration
|
|
42
|
-
* @prop {Number} dist
|
|
43
|
-
* @prop {number} shift
|
|
44
|
-
* @prop {number} padding
|
|
45
|
-
* @prop {Boolean} fullWidth
|
|
46
|
-
* @prop {Boolean} indicators
|
|
47
|
-
* @prop {Boolean} noWrap
|
|
48
|
-
* @prop {Function} onCycleTo
|
|
49
|
-
*/
|
|
50
|
-
this.options = $.extend({}, Autocomplete.defaults, options);
|
|
51
|
-
|
|
52
|
-
// Setup
|
|
53
|
-
this.isOpen = false;
|
|
54
|
-
this.count = 0;
|
|
55
|
-
this.activeIndex = -1;
|
|
56
|
-
this.oldVal;
|
|
57
|
-
this.$inputField = this.$el.closest('.input-field');
|
|
58
|
-
this.$active = $();
|
|
59
|
-
this._mousedown = false;
|
|
60
|
-
this._setupDropdown();
|
|
61
|
-
|
|
62
|
-
this._setupEventHandlers();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
static get defaults() {
|
|
66
|
-
return _defaults;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
static init(els, options) {
|
|
70
|
-
return super.init(this, els, options);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Get Instance
|
|
75
|
-
*/
|
|
76
|
-
static getInstance(el) {
|
|
77
|
-
let domElem = !!el.jquery ? el[0] : el;
|
|
78
|
-
return domElem.M_Autocomplete;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Teardown component
|
|
83
|
-
*/
|
|
84
|
-
destroy() {
|
|
85
|
-
this._removeEventHandlers();
|
|
86
|
-
this._removeDropdown();
|
|
87
|
-
this.el.M_Autocomplete = undefined;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Setup Event Handlers
|
|
92
|
-
*/
|
|
93
|
-
_setupEventHandlers() {
|
|
94
|
-
this._handleInputBlurBound = this._handleInputBlur.bind(this);
|
|
95
|
-
this._handleInputKeyupAndFocusBound = this._handleInputKeyupAndFocus.bind(this);
|
|
96
|
-
this._handleInputKeydownBound = this._handleInputKeydown.bind(this);
|
|
97
|
-
this._handleInputClickBound = this._handleInputClick.bind(this);
|
|
98
|
-
this._handleContainerMousedownAndTouchstartBound = this._handleContainerMousedownAndTouchstart.bind(
|
|
99
|
-
this
|
|
100
|
-
);
|
|
101
|
-
this._handleContainerMouseupAndTouchendBound = this._handleContainerMouseupAndTouchend.bind(
|
|
102
|
-
this
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
this.el.addEventListener('blur', this._handleInputBlurBound);
|
|
106
|
-
this.el.addEventListener('keyup', this._handleInputKeyupAndFocusBound);
|
|
107
|
-
this.el.addEventListener('focus', this._handleInputKeyupAndFocusBound);
|
|
108
|
-
this.el.addEventListener('keydown', this._handleInputKeydownBound);
|
|
109
|
-
this.el.addEventListener('click', this._handleInputClickBound);
|
|
110
|
-
this.container.addEventListener(
|
|
111
|
-
'mousedown',
|
|
112
|
-
this._handleContainerMousedownAndTouchstartBound
|
|
113
|
-
);
|
|
114
|
-
this.container.addEventListener('mouseup', this._handleContainerMouseupAndTouchendBound);
|
|
115
|
-
|
|
116
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
117
|
-
this.container.addEventListener(
|
|
118
|
-
'touchstart',
|
|
119
|
-
this._handleContainerMousedownAndTouchstartBound
|
|
120
|
-
);
|
|
121
|
-
this.container.addEventListener('touchend', this._handleContainerMouseupAndTouchendBound);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Remove Event Handlers
|
|
127
|
-
*/
|
|
128
|
-
_removeEventHandlers() {
|
|
129
|
-
this.el.removeEventListener('blur', this._handleInputBlurBound);
|
|
130
|
-
this.el.removeEventListener('keyup', this._handleInputKeyupAndFocusBound);
|
|
131
|
-
this.el.removeEventListener('focus', this._handleInputKeyupAndFocusBound);
|
|
132
|
-
this.el.removeEventListener('keydown', this._handleInputKeydownBound);
|
|
133
|
-
this.el.removeEventListener('click', this._handleInputClickBound);
|
|
134
|
-
this.container.removeEventListener(
|
|
135
|
-
'mousedown',
|
|
136
|
-
this._handleContainerMousedownAndTouchstartBound
|
|
137
|
-
);
|
|
138
|
-
this.container.removeEventListener('mouseup', this._handleContainerMouseupAndTouchendBound);
|
|
139
|
-
|
|
140
|
-
if (typeof window.ontouchstart !== 'undefined') {
|
|
141
|
-
this.container.removeEventListener(
|
|
142
|
-
'touchstart',
|
|
143
|
-
this._handleContainerMousedownAndTouchstartBound
|
|
144
|
-
);
|
|
145
|
-
this.container.removeEventListener(
|
|
146
|
-
'touchend',
|
|
147
|
-
this._handleContainerMouseupAndTouchendBound
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Setup dropdown
|
|
154
|
-
*/
|
|
155
|
-
_setupDropdown() {
|
|
156
|
-
this.container = document.createElement('ul');
|
|
157
|
-
this.container.id = `autocomplete-options-${M.guid()}`;
|
|
158
|
-
$(this.container).addClass('autocomplete-content dropdown-content');
|
|
159
|
-
this.$inputField.append(this.container);
|
|
160
|
-
this.el.setAttribute('data-target', this.container.id);
|
|
161
|
-
|
|
162
|
-
// Initialize dropdown
|
|
163
|
-
let dropdownOptions = $.extend(
|
|
164
|
-
{},
|
|
165
|
-
Autocomplete.defaults.dropdownOptions,
|
|
166
|
-
this.options.dropdownOptions
|
|
167
|
-
);
|
|
168
|
-
let userOnItemClick = dropdownOptions.onItemClick;
|
|
169
|
-
|
|
170
|
-
// Ensuring the selectOption call when user passes custom onItemClick function to dropdown
|
|
171
|
-
dropdownOptions.onItemClick = (el) => {
|
|
172
|
-
this.selectOption($(el));
|
|
173
|
-
|
|
174
|
-
// Handle user declared onItemClick if needed
|
|
175
|
-
if (userOnItemClick && typeof userOnItemClick === 'function') {
|
|
176
|
-
userOnItemClick.call(this.dropdown, this.el);
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
this.dropdown = M.Dropdown.init(this.el, dropdownOptions);
|
|
181
|
-
|
|
182
|
-
// Sketchy removal of dropdown click handler
|
|
183
|
-
this.el.removeEventListener('click', this.dropdown._handleClickBound);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Remove dropdown
|
|
188
|
-
*/
|
|
189
|
-
_removeDropdown() {
|
|
190
|
-
this.container.parentNode.removeChild(this.container);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Handle Input Blur
|
|
195
|
-
*/
|
|
196
|
-
_handleInputBlur() {
|
|
197
|
-
if (!this._mousedown) {
|
|
198
|
-
this.close();
|
|
199
|
-
this._resetAutocomplete();
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Handle Input Keyup and Focus
|
|
205
|
-
* @param {Event} e
|
|
206
|
-
*/
|
|
207
|
-
_handleInputKeyupAndFocus(e) {
|
|
208
|
-
if (e.type === 'keyup') {
|
|
209
|
-
Autocomplete._keydown = false;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
this.count = 0;
|
|
213
|
-
let val = this.el.value.toLowerCase();
|
|
214
|
-
|
|
215
|
-
// Don't capture enter or arrow key usage.
|
|
216
|
-
if (e.keyCode === 13 || e.keyCode === 38 || e.keyCode === 40) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Check if the input isn't empty
|
|
221
|
-
// Check if focus triggered by tab
|
|
222
|
-
if (this.oldVal !== val && (M.tabPressed || e.type !== 'focus')) {
|
|
223
|
-
this.open();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// Update oldVal
|
|
227
|
-
this.oldVal = val;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Handle Input Keydown
|
|
232
|
-
* @param {Event} e
|
|
233
|
-
*/
|
|
234
|
-
_handleInputKeydown(e) {
|
|
235
|
-
Autocomplete._keydown = true;
|
|
236
|
-
|
|
237
|
-
// Arrow keys and enter key usage
|
|
238
|
-
let keyCode = e.keyCode,
|
|
239
|
-
liElement,
|
|
240
|
-
numItems = $(this.container).children('li').length;
|
|
241
|
-
|
|
242
|
-
// select element on Enter
|
|
243
|
-
if (keyCode === M.keys.ENTER && this.activeIndex >= 0) {
|
|
244
|
-
liElement = $(this.container)
|
|
245
|
-
.children('li')
|
|
246
|
-
.eq(this.activeIndex);
|
|
247
|
-
if (liElement.length) {
|
|
248
|
-
this.selectOption(liElement);
|
|
249
|
-
e.preventDefault();
|
|
250
|
-
}
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
// Capture up and down key
|
|
255
|
-
if (keyCode === M.keys.ARROW_UP || keyCode === M.keys.ARROW_DOWN) {
|
|
256
|
-
e.preventDefault();
|
|
257
|
-
|
|
258
|
-
if (keyCode === M.keys.ARROW_UP && this.activeIndex > 0) {
|
|
259
|
-
this.activeIndex--;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (keyCode === M.keys.ARROW_DOWN && this.activeIndex < numItems - 1) {
|
|
263
|
-
this.activeIndex++;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
this.$active.removeClass('active');
|
|
267
|
-
if (this.activeIndex >= 0) {
|
|
268
|
-
this.$active = $(this.container)
|
|
269
|
-
.children('li')
|
|
270
|
-
.eq(this.activeIndex);
|
|
271
|
-
this.$active.addClass('active');
|
|
272
|
-
|
|
273
|
-
// Focus selected
|
|
274
|
-
this.container.children[this.activeIndex].scrollIntoView({
|
|
275
|
-
behavior: 'smooth',
|
|
276
|
-
block: 'nearest',
|
|
277
|
-
inline: 'nearest'
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Handle Input Click
|
|
285
|
-
* @param {Event} e
|
|
286
|
-
*/
|
|
287
|
-
_handleInputClick(e) {
|
|
288
|
-
this.open();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* Handle Container Mousedown and Touchstart
|
|
293
|
-
* @param {Event} e
|
|
294
|
-
*/
|
|
295
|
-
_handleContainerMousedownAndTouchstart(e) {
|
|
296
|
-
this._mousedown = true;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Handle Container Mouseup and Touchend
|
|
301
|
-
* @param {Event} e
|
|
302
|
-
*/
|
|
303
|
-
_handleContainerMouseupAndTouchend(e) {
|
|
304
|
-
this._mousedown = false;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Highlight partial match
|
|
309
|
-
*/
|
|
310
|
-
_highlight(input, label) {
|
|
311
|
-
const start = label.toLowerCase().indexOf('' + input.toLowerCase() + '');
|
|
312
|
-
const end = start + input.length - 1;
|
|
313
|
-
//custom filters may return results where the string does not match any part
|
|
314
|
-
if (start == -1 || end == -1) {
|
|
315
|
-
return [label, '', ''];
|
|
316
|
-
}
|
|
317
|
-
return [label.slice(0, start), label.slice(start, end + 1), label.slice(end + 1)];
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Reset current element position
|
|
322
|
-
*/
|
|
323
|
-
_resetCurrentElement() {
|
|
324
|
-
this.activeIndex = -1;
|
|
325
|
-
this.$active.removeClass('active');
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
/**
|
|
329
|
-
* Reset autocomplete elements
|
|
330
|
-
*/
|
|
331
|
-
_resetAutocomplete() {
|
|
332
|
-
$(this.container).empty();
|
|
333
|
-
this._resetCurrentElement();
|
|
334
|
-
this.oldVal = null;
|
|
335
|
-
this.isOpen = false;
|
|
336
|
-
this._mousedown = false;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* Select autocomplete option
|
|
341
|
-
* @param {Element} el Autocomplete option list item element
|
|
342
|
-
*/
|
|
343
|
-
selectOption(el) {
|
|
344
|
-
let text = el.text().trim();
|
|
345
|
-
this.el.value = text;
|
|
346
|
-
this.$el.trigger('change');
|
|
347
|
-
this._resetAutocomplete();
|
|
348
|
-
this.close();
|
|
349
|
-
|
|
350
|
-
// Handle onAutocomplete callback.
|
|
351
|
-
if (typeof this.options.onAutocomplete === 'function') {
|
|
352
|
-
this.options.onAutocomplete.call(this, text);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Render dropdown content
|
|
358
|
-
* @param {Object} data data set
|
|
359
|
-
* @param {String} val current input value
|
|
360
|
-
*/
|
|
361
|
-
_renderDropdown(data, val) {
|
|
362
|
-
this._resetAutocomplete();
|
|
363
|
-
|
|
364
|
-
let matchingData = [];
|
|
365
|
-
|
|
366
|
-
// Gather all matching data
|
|
367
|
-
for (let key in data) {
|
|
368
|
-
if (data.hasOwnProperty(key) && key.toLowerCase().indexOf(val) !== -1) {
|
|
369
|
-
let entry = {
|
|
370
|
-
data: data[key],
|
|
371
|
-
key: key
|
|
372
|
-
};
|
|
373
|
-
matchingData.push(entry);
|
|
374
|
-
|
|
375
|
-
this.count++;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Sort
|
|
380
|
-
if (this.options.sortFunction) {
|
|
381
|
-
let sortFunctionBound = (a, b) => {
|
|
382
|
-
return this.options.sortFunction(
|
|
383
|
-
a.key.toLowerCase(),
|
|
384
|
-
b.key.toLowerCase(),
|
|
385
|
-
val.toLowerCase()
|
|
386
|
-
);
|
|
387
|
-
};
|
|
388
|
-
matchingData.sort(sortFunctionBound);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// Limit
|
|
392
|
-
matchingData = matchingData.slice(0, this.options.limit);
|
|
393
|
-
|
|
394
|
-
// Render
|
|
395
|
-
for (let i = 0; i < matchingData.length; i++) {
|
|
396
|
-
const entry = matchingData[i];
|
|
397
|
-
const item = document.createElement('li');
|
|
398
|
-
if (!!entry.data) {
|
|
399
|
-
const img = document.createElement('img');
|
|
400
|
-
img.classList.add('right', 'circle');
|
|
401
|
-
img.src = entry.data;
|
|
402
|
-
item.appendChild(img);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
const parts = this._highlight(val, entry.key);
|
|
406
|
-
const s = document.createElement('span');
|
|
407
|
-
if (this.options.allowUnsafeHTML) {
|
|
408
|
-
s.innerHTML = parts[0] + '<span class="highlight">' + parts[1] + '</span>' + parts[2];
|
|
409
|
-
} else {
|
|
410
|
-
s.appendChild(document.createTextNode(parts[0]));
|
|
411
|
-
if (!!parts[1]) {
|
|
412
|
-
const highlight = document.createElement('span');
|
|
413
|
-
highlight.textContent = parts[1];
|
|
414
|
-
highlight.classList.add('highlight');
|
|
415
|
-
s.appendChild(highlight);
|
|
416
|
-
s.appendChild(document.createTextNode(parts[2]));
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
item.appendChild(s);
|
|
420
|
-
|
|
421
|
-
$(this.container).append(item);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
/**
|
|
426
|
-
* Open Autocomplete Dropdown
|
|
427
|
-
*/
|
|
428
|
-
open() {
|
|
429
|
-
let val = this.el.value.toLowerCase();
|
|
430
|
-
|
|
431
|
-
this._resetAutocomplete();
|
|
432
|
-
|
|
433
|
-
if (val.length >= this.options.minLength) {
|
|
434
|
-
this.isOpen = true;
|
|
435
|
-
this._renderDropdown(this.options.data, val);
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// Open dropdown
|
|
439
|
-
if (!this.dropdown.isOpen) {
|
|
440
|
-
this.dropdown.open();
|
|
441
|
-
} else {
|
|
442
|
-
// Recalculate dropdown when its already open
|
|
443
|
-
this.dropdown.recalculateDimensions();
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Close Autocomplete Dropdown
|
|
449
|
-
*/
|
|
450
|
-
close() {
|
|
451
|
-
this.dropdown.close();
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* Update Data
|
|
456
|
-
* @param {Object} data
|
|
457
|
-
*/
|
|
458
|
-
updateData(data) {
|
|
459
|
-
let val = this.el.value.toLowerCase();
|
|
460
|
-
this.options.data = data;
|
|
461
|
-
|
|
462
|
-
if (this.isOpen) {
|
|
463
|
-
this._renderDropdown(data, val);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* @static
|
|
470
|
-
* @memberof Autocomplete
|
|
471
|
-
*/
|
|
472
|
-
Autocomplete._keydown = false;
|
|
473
|
-
|
|
474
|
-
M.Autocomplete = Autocomplete;
|
|
475
|
-
|
|
476
|
-
if (M.jQueryLoaded) {
|
|
477
|
-
M.initializeJqueryWrapper(Autocomplete, 'autocomplete', 'M_Autocomplete');
|
|
478
|
-
}
|
|
479
|
-
})(cash);
|
|
1
|
+
(function($) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
let _defaults = {
|
|
5
|
+
data: {}, // Autocomplete data set
|
|
6
|
+
limit: Infinity, // Limit of results the autocomplete shows
|
|
7
|
+
onAutocomplete: null, // Callback for when autocompleted
|
|
8
|
+
dropdownOptions: {
|
|
9
|
+
// Default dropdown options
|
|
10
|
+
autoFocus: false,
|
|
11
|
+
closeOnClick: false,
|
|
12
|
+
coverTrigger: false
|
|
13
|
+
},
|
|
14
|
+
minLength: 1, // Min characters before autocomplete starts
|
|
15
|
+
sortFunction: function(a, b, inputString) {
|
|
16
|
+
// Sort function for sorting autocomplete results
|
|
17
|
+
return a.indexOf(inputString) - b.indexOf(inputString);
|
|
18
|
+
},
|
|
19
|
+
allowUnsafeHTML: false
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @class
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
class Autocomplete extends Component {
|
|
27
|
+
/**
|
|
28
|
+
* Construct Autocomplete instance
|
|
29
|
+
* @constructor
|
|
30
|
+
* @param {Element} el
|
|
31
|
+
* @param {Object} options
|
|
32
|
+
*/
|
|
33
|
+
constructor(el, options) {
|
|
34
|
+
super(Autocomplete, el, options);
|
|
35
|
+
|
|
36
|
+
this.el.M_Autocomplete = this;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Options for the autocomplete
|
|
40
|
+
* @member Autocomplete#options
|
|
41
|
+
* @prop {Number} duration
|
|
42
|
+
* @prop {Number} dist
|
|
43
|
+
* @prop {number} shift
|
|
44
|
+
* @prop {number} padding
|
|
45
|
+
* @prop {Boolean} fullWidth
|
|
46
|
+
* @prop {Boolean} indicators
|
|
47
|
+
* @prop {Boolean} noWrap
|
|
48
|
+
* @prop {Function} onCycleTo
|
|
49
|
+
*/
|
|
50
|
+
this.options = $.extend({}, Autocomplete.defaults, options);
|
|
51
|
+
|
|
52
|
+
// Setup
|
|
53
|
+
this.isOpen = false;
|
|
54
|
+
this.count = 0;
|
|
55
|
+
this.activeIndex = -1;
|
|
56
|
+
this.oldVal;
|
|
57
|
+
this.$inputField = this.$el.closest('.input-field');
|
|
58
|
+
this.$active = $();
|
|
59
|
+
this._mousedown = false;
|
|
60
|
+
this._setupDropdown();
|
|
61
|
+
|
|
62
|
+
this._setupEventHandlers();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static get defaults() {
|
|
66
|
+
return _defaults;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static init(els, options) {
|
|
70
|
+
return super.init(this, els, options);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get Instance
|
|
75
|
+
*/
|
|
76
|
+
static getInstance(el) {
|
|
77
|
+
let domElem = !!el.jquery ? el[0] : el;
|
|
78
|
+
return domElem.M_Autocomplete;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Teardown component
|
|
83
|
+
*/
|
|
84
|
+
destroy() {
|
|
85
|
+
this._removeEventHandlers();
|
|
86
|
+
this._removeDropdown();
|
|
87
|
+
this.el.M_Autocomplete = undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Setup Event Handlers
|
|
92
|
+
*/
|
|
93
|
+
_setupEventHandlers() {
|
|
94
|
+
this._handleInputBlurBound = this._handleInputBlur.bind(this);
|
|
95
|
+
this._handleInputKeyupAndFocusBound = this._handleInputKeyupAndFocus.bind(this);
|
|
96
|
+
this._handleInputKeydownBound = this._handleInputKeydown.bind(this);
|
|
97
|
+
this._handleInputClickBound = this._handleInputClick.bind(this);
|
|
98
|
+
this._handleContainerMousedownAndTouchstartBound = this._handleContainerMousedownAndTouchstart.bind(
|
|
99
|
+
this
|
|
100
|
+
);
|
|
101
|
+
this._handleContainerMouseupAndTouchendBound = this._handleContainerMouseupAndTouchend.bind(
|
|
102
|
+
this
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
this.el.addEventListener('blur', this._handleInputBlurBound);
|
|
106
|
+
this.el.addEventListener('keyup', this._handleInputKeyupAndFocusBound);
|
|
107
|
+
this.el.addEventListener('focus', this._handleInputKeyupAndFocusBound);
|
|
108
|
+
this.el.addEventListener('keydown', this._handleInputKeydownBound);
|
|
109
|
+
this.el.addEventListener('click', this._handleInputClickBound);
|
|
110
|
+
this.container.addEventListener(
|
|
111
|
+
'mousedown',
|
|
112
|
+
this._handleContainerMousedownAndTouchstartBound
|
|
113
|
+
);
|
|
114
|
+
this.container.addEventListener('mouseup', this._handleContainerMouseupAndTouchendBound);
|
|
115
|
+
|
|
116
|
+
if (typeof window.ontouchstart !== 'undefined') {
|
|
117
|
+
this.container.addEventListener(
|
|
118
|
+
'touchstart',
|
|
119
|
+
this._handleContainerMousedownAndTouchstartBound
|
|
120
|
+
);
|
|
121
|
+
this.container.addEventListener('touchend', this._handleContainerMouseupAndTouchendBound);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Remove Event Handlers
|
|
127
|
+
*/
|
|
128
|
+
_removeEventHandlers() {
|
|
129
|
+
this.el.removeEventListener('blur', this._handleInputBlurBound);
|
|
130
|
+
this.el.removeEventListener('keyup', this._handleInputKeyupAndFocusBound);
|
|
131
|
+
this.el.removeEventListener('focus', this._handleInputKeyupAndFocusBound);
|
|
132
|
+
this.el.removeEventListener('keydown', this._handleInputKeydownBound);
|
|
133
|
+
this.el.removeEventListener('click', this._handleInputClickBound);
|
|
134
|
+
this.container.removeEventListener(
|
|
135
|
+
'mousedown',
|
|
136
|
+
this._handleContainerMousedownAndTouchstartBound
|
|
137
|
+
);
|
|
138
|
+
this.container.removeEventListener('mouseup', this._handleContainerMouseupAndTouchendBound);
|
|
139
|
+
|
|
140
|
+
if (typeof window.ontouchstart !== 'undefined') {
|
|
141
|
+
this.container.removeEventListener(
|
|
142
|
+
'touchstart',
|
|
143
|
+
this._handleContainerMousedownAndTouchstartBound
|
|
144
|
+
);
|
|
145
|
+
this.container.removeEventListener(
|
|
146
|
+
'touchend',
|
|
147
|
+
this._handleContainerMouseupAndTouchendBound
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Setup dropdown
|
|
154
|
+
*/
|
|
155
|
+
_setupDropdown() {
|
|
156
|
+
this.container = document.createElement('ul');
|
|
157
|
+
this.container.id = `autocomplete-options-${M.guid()}`;
|
|
158
|
+
$(this.container).addClass('autocomplete-content dropdown-content');
|
|
159
|
+
this.$inputField.append(this.container);
|
|
160
|
+
this.el.setAttribute('data-target', this.container.id);
|
|
161
|
+
|
|
162
|
+
// Initialize dropdown
|
|
163
|
+
let dropdownOptions = $.extend(
|
|
164
|
+
{},
|
|
165
|
+
Autocomplete.defaults.dropdownOptions,
|
|
166
|
+
this.options.dropdownOptions
|
|
167
|
+
);
|
|
168
|
+
let userOnItemClick = dropdownOptions.onItemClick;
|
|
169
|
+
|
|
170
|
+
// Ensuring the selectOption call when user passes custom onItemClick function to dropdown
|
|
171
|
+
dropdownOptions.onItemClick = (el) => {
|
|
172
|
+
this.selectOption($(el));
|
|
173
|
+
|
|
174
|
+
// Handle user declared onItemClick if needed
|
|
175
|
+
if (userOnItemClick && typeof userOnItemClick === 'function') {
|
|
176
|
+
userOnItemClick.call(this.dropdown, this.el);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
this.dropdown = M.Dropdown.init(this.el, dropdownOptions);
|
|
181
|
+
|
|
182
|
+
// Sketchy removal of dropdown click handler
|
|
183
|
+
this.el.removeEventListener('click', this.dropdown._handleClickBound);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Remove dropdown
|
|
188
|
+
*/
|
|
189
|
+
_removeDropdown() {
|
|
190
|
+
this.container.parentNode.removeChild(this.container);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Handle Input Blur
|
|
195
|
+
*/
|
|
196
|
+
_handleInputBlur() {
|
|
197
|
+
if (!this._mousedown) {
|
|
198
|
+
this.close();
|
|
199
|
+
this._resetAutocomplete();
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Handle Input Keyup and Focus
|
|
205
|
+
* @param {Event} e
|
|
206
|
+
*/
|
|
207
|
+
_handleInputKeyupAndFocus(e) {
|
|
208
|
+
if (e.type === 'keyup') {
|
|
209
|
+
Autocomplete._keydown = false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
this.count = 0;
|
|
213
|
+
let val = this.el.value.toLowerCase();
|
|
214
|
+
|
|
215
|
+
// Don't capture enter or arrow key usage.
|
|
216
|
+
if (e.keyCode === 13 || e.keyCode === 38 || e.keyCode === 40) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Check if the input isn't empty
|
|
221
|
+
// Check if focus triggered by tab
|
|
222
|
+
if (this.oldVal !== val && (M.tabPressed || e.type !== 'focus')) {
|
|
223
|
+
this.open();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Update oldVal
|
|
227
|
+
this.oldVal = val;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Handle Input Keydown
|
|
232
|
+
* @param {Event} e
|
|
233
|
+
*/
|
|
234
|
+
_handleInputKeydown(e) {
|
|
235
|
+
Autocomplete._keydown = true;
|
|
236
|
+
|
|
237
|
+
// Arrow keys and enter key usage
|
|
238
|
+
let keyCode = e.keyCode,
|
|
239
|
+
liElement,
|
|
240
|
+
numItems = $(this.container).children('li').length;
|
|
241
|
+
|
|
242
|
+
// select element on Enter
|
|
243
|
+
if (keyCode === M.keys.ENTER && this.activeIndex >= 0) {
|
|
244
|
+
liElement = $(this.container)
|
|
245
|
+
.children('li')
|
|
246
|
+
.eq(this.activeIndex);
|
|
247
|
+
if (liElement.length) {
|
|
248
|
+
this.selectOption(liElement);
|
|
249
|
+
e.preventDefault();
|
|
250
|
+
}
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Capture up and down key
|
|
255
|
+
if (keyCode === M.keys.ARROW_UP || keyCode === M.keys.ARROW_DOWN) {
|
|
256
|
+
e.preventDefault();
|
|
257
|
+
|
|
258
|
+
if (keyCode === M.keys.ARROW_UP && this.activeIndex > 0) {
|
|
259
|
+
this.activeIndex--;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (keyCode === M.keys.ARROW_DOWN && this.activeIndex < numItems - 1) {
|
|
263
|
+
this.activeIndex++;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
this.$active.removeClass('active');
|
|
267
|
+
if (this.activeIndex >= 0) {
|
|
268
|
+
this.$active = $(this.container)
|
|
269
|
+
.children('li')
|
|
270
|
+
.eq(this.activeIndex);
|
|
271
|
+
this.$active.addClass('active');
|
|
272
|
+
|
|
273
|
+
// Focus selected
|
|
274
|
+
this.container.children[this.activeIndex].scrollIntoView({
|
|
275
|
+
behavior: 'smooth',
|
|
276
|
+
block: 'nearest',
|
|
277
|
+
inline: 'nearest'
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Handle Input Click
|
|
285
|
+
* @param {Event} e
|
|
286
|
+
*/
|
|
287
|
+
_handleInputClick(e) {
|
|
288
|
+
this.open();
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Handle Container Mousedown and Touchstart
|
|
293
|
+
* @param {Event} e
|
|
294
|
+
*/
|
|
295
|
+
_handleContainerMousedownAndTouchstart(e) {
|
|
296
|
+
this._mousedown = true;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Handle Container Mouseup and Touchend
|
|
301
|
+
* @param {Event} e
|
|
302
|
+
*/
|
|
303
|
+
_handleContainerMouseupAndTouchend(e) {
|
|
304
|
+
this._mousedown = false;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Highlight partial match
|
|
309
|
+
*/
|
|
310
|
+
_highlight(input, label) {
|
|
311
|
+
const start = label.toLowerCase().indexOf('' + input.toLowerCase() + '');
|
|
312
|
+
const end = start + input.length - 1;
|
|
313
|
+
//custom filters may return results where the string does not match any part
|
|
314
|
+
if (start == -1 || end == -1) {
|
|
315
|
+
return [label, '', ''];
|
|
316
|
+
}
|
|
317
|
+
return [label.slice(0, start), label.slice(start, end + 1), label.slice(end + 1)];
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Reset current element position
|
|
322
|
+
*/
|
|
323
|
+
_resetCurrentElement() {
|
|
324
|
+
this.activeIndex = -1;
|
|
325
|
+
this.$active.removeClass('active');
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Reset autocomplete elements
|
|
330
|
+
*/
|
|
331
|
+
_resetAutocomplete() {
|
|
332
|
+
$(this.container).empty();
|
|
333
|
+
this._resetCurrentElement();
|
|
334
|
+
this.oldVal = null;
|
|
335
|
+
this.isOpen = false;
|
|
336
|
+
this._mousedown = false;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Select autocomplete option
|
|
341
|
+
* @param {Element} el Autocomplete option list item element
|
|
342
|
+
*/
|
|
343
|
+
selectOption(el) {
|
|
344
|
+
let text = el.text().trim();
|
|
345
|
+
this.el.value = text;
|
|
346
|
+
this.$el.trigger('change');
|
|
347
|
+
this._resetAutocomplete();
|
|
348
|
+
this.close();
|
|
349
|
+
|
|
350
|
+
// Handle onAutocomplete callback.
|
|
351
|
+
if (typeof this.options.onAutocomplete === 'function') {
|
|
352
|
+
this.options.onAutocomplete.call(this, text);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Render dropdown content
|
|
358
|
+
* @param {Object} data data set
|
|
359
|
+
* @param {String} val current input value
|
|
360
|
+
*/
|
|
361
|
+
_renderDropdown(data, val) {
|
|
362
|
+
this._resetAutocomplete();
|
|
363
|
+
|
|
364
|
+
let matchingData = [];
|
|
365
|
+
|
|
366
|
+
// Gather all matching data
|
|
367
|
+
for (let key in data) {
|
|
368
|
+
if (data.hasOwnProperty(key) && key.toLowerCase().indexOf(val) !== -1) {
|
|
369
|
+
let entry = {
|
|
370
|
+
data: data[key],
|
|
371
|
+
key: key
|
|
372
|
+
};
|
|
373
|
+
matchingData.push(entry);
|
|
374
|
+
|
|
375
|
+
this.count++;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Sort
|
|
380
|
+
if (this.options.sortFunction) {
|
|
381
|
+
let sortFunctionBound = (a, b) => {
|
|
382
|
+
return this.options.sortFunction(
|
|
383
|
+
a.key.toLowerCase(),
|
|
384
|
+
b.key.toLowerCase(),
|
|
385
|
+
val.toLowerCase()
|
|
386
|
+
);
|
|
387
|
+
};
|
|
388
|
+
matchingData.sort(sortFunctionBound);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// Limit
|
|
392
|
+
matchingData = matchingData.slice(0, this.options.limit);
|
|
393
|
+
|
|
394
|
+
// Render
|
|
395
|
+
for (let i = 0; i < matchingData.length; i++) {
|
|
396
|
+
const entry = matchingData[i];
|
|
397
|
+
const item = document.createElement('li');
|
|
398
|
+
if (!!entry.data) {
|
|
399
|
+
const img = document.createElement('img');
|
|
400
|
+
img.classList.add('right', 'circle');
|
|
401
|
+
img.src = entry.data;
|
|
402
|
+
item.appendChild(img);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const parts = this._highlight(val, entry.key);
|
|
406
|
+
const s = document.createElement('span');
|
|
407
|
+
if (this.options.allowUnsafeHTML) {
|
|
408
|
+
s.innerHTML = parts[0] + '<span class="highlight">' + parts[1] + '</span>' + parts[2];
|
|
409
|
+
} else {
|
|
410
|
+
s.appendChild(document.createTextNode(parts[0]));
|
|
411
|
+
if (!!parts[1]) {
|
|
412
|
+
const highlight = document.createElement('span');
|
|
413
|
+
highlight.textContent = parts[1];
|
|
414
|
+
highlight.classList.add('highlight');
|
|
415
|
+
s.appendChild(highlight);
|
|
416
|
+
s.appendChild(document.createTextNode(parts[2]));
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
item.appendChild(s);
|
|
420
|
+
|
|
421
|
+
$(this.container).append(item);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Open Autocomplete Dropdown
|
|
427
|
+
*/
|
|
428
|
+
open() {
|
|
429
|
+
let val = this.el.value.toLowerCase();
|
|
430
|
+
|
|
431
|
+
this._resetAutocomplete();
|
|
432
|
+
|
|
433
|
+
if (val.length >= this.options.minLength) {
|
|
434
|
+
this.isOpen = true;
|
|
435
|
+
this._renderDropdown(this.options.data, val);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Open dropdown
|
|
439
|
+
if (!this.dropdown.isOpen) {
|
|
440
|
+
this.dropdown.open();
|
|
441
|
+
} else {
|
|
442
|
+
// Recalculate dropdown when its already open
|
|
443
|
+
this.dropdown.recalculateDimensions();
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Close Autocomplete Dropdown
|
|
449
|
+
*/
|
|
450
|
+
close() {
|
|
451
|
+
this.dropdown.close();
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Update Data
|
|
456
|
+
* @param {Object} data
|
|
457
|
+
*/
|
|
458
|
+
updateData(data) {
|
|
459
|
+
let val = this.el.value.toLowerCase();
|
|
460
|
+
this.options.data = data;
|
|
461
|
+
|
|
462
|
+
if (this.isOpen) {
|
|
463
|
+
this._renderDropdown(data, val);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* @static
|
|
470
|
+
* @memberof Autocomplete
|
|
471
|
+
*/
|
|
472
|
+
Autocomplete._keydown = false;
|
|
473
|
+
|
|
474
|
+
M.Autocomplete = Autocomplete;
|
|
475
|
+
|
|
476
|
+
if (M.jQueryLoaded) {
|
|
477
|
+
M.initializeJqueryWrapper(Autocomplete, 'autocomplete', 'M_Autocomplete');
|
|
478
|
+
}
|
|
479
|
+
})(cash);
|