@materializecss/materialize 1.1.0-alpha → 1.1.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/Gruntfile.js +115 -132
- package/LICENSE +21 -21
- package/README.md +97 -97
- package/dist/css/materialize.css +8462 -8987
- package/dist/css/materialize.min.css +7 -7
- package/dist/js/materialize.js +12669 -12791
- package/dist/js/materialize.min.js +6 -6
- package/extras/noUiSlider/nouislider.css +406 -406
- package/extras/noUiSlider/nouislider.js +2147 -2147
- package/extras/noUiSlider/nouislider.min.js +0 -0
- 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 -717
- 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 -976
- package/js/dropdown.js +669 -668
- package/js/forms.js +275 -275
- package/js/global.js +424 -424
- 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 +310 -451
- package/js/sidenav.js +583 -583
- package/js/slider.js +359 -359
- package/js/tabs.js +402 -402
- package/js/tapTarget.js +315 -315
- package/js/timepicker.js +648 -647
- package/js/toasts.js +322 -322
- package/js/tooltip.js +320 -320
- package/js/waves.js +614 -614
- package/package.json +82 -74
- package/sass/_style.scss +929 -0
- 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 +107 -0
- 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 +642 -771
- package/sass/components/_grid.scss +158 -156
- 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 +91 -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 +183 -183
- 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 -60
- package/sass/components/_variables.scss +352 -349
- 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 +379 -379
- 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/ghpages-materialize.scss +7 -0
- package/sass/materialize.scss +42 -41
- package/CHANGELOG.md +0 -76
- package/HISTORY.md +0 -527
package/js/select.js
CHANGED
|
@@ -1,451 +1,310 @@
|
|
|
1
|
-
(function($) {
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
let _defaults = {
|
|
5
|
-
classes: '',
|
|
6
|
-
dropdownOptions: {}
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.
|
|
40
|
-
this.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
this.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
this.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
$(this.wrapper).remove();
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Setup dropdown
|
|
316
|
-
* @param {Element} select select element
|
|
317
|
-
* @param {Element} option option element from select
|
|
318
|
-
* @param {String} type
|
|
319
|
-
* @return {Element} option element added
|
|
320
|
-
*/
|
|
321
|
-
_appendOptionWithIcon(select, option, type) {
|
|
322
|
-
// Add disabled attr if disabled
|
|
323
|
-
let disabledClass = option.disabled ? 'disabled ' : '';
|
|
324
|
-
let optgroupClass = type === 'optgroup-option' ? 'optgroup-option ' : '';
|
|
325
|
-
let multipleCheckbox = this.isMultiple
|
|
326
|
-
? `<label><input type="checkbox"${disabledClass}"/><span>${option.innerHTML}</span></label>`
|
|
327
|
-
: option.innerHTML;
|
|
328
|
-
let liEl = $('<li></li>');
|
|
329
|
-
let spanEl = $('<span></span>');
|
|
330
|
-
spanEl.html(multipleCheckbox);
|
|
331
|
-
liEl.addClass(`${disabledClass} ${optgroupClass}`);
|
|
332
|
-
liEl.append(spanEl);
|
|
333
|
-
|
|
334
|
-
// add icons
|
|
335
|
-
let iconUrl = option.getAttribute('data-icon');
|
|
336
|
-
let classes = option.getAttribute('class');
|
|
337
|
-
if (!!iconUrl) {
|
|
338
|
-
let imgEl = $(`<img alt="" class="${classes}" src="${iconUrl}">`);
|
|
339
|
-
liEl.prepend(imgEl);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Check for multiple type.
|
|
343
|
-
$(this.dropdownOptions).append(liEl[0]);
|
|
344
|
-
return liEl[0];
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Toggle entry from option
|
|
349
|
-
* @param {String} key Option key
|
|
350
|
-
* @return {Boolean} if entry was added or removed
|
|
351
|
-
*/
|
|
352
|
-
_toggleEntryFromArray(key) {
|
|
353
|
-
let notAdded = !this._keysSelected.hasOwnProperty(key);
|
|
354
|
-
let $optionLi = $(this._valueDict[key].optionEl);
|
|
355
|
-
|
|
356
|
-
if (notAdded) {
|
|
357
|
-
this._keysSelected[key] = true;
|
|
358
|
-
} else {
|
|
359
|
-
delete this._keysSelected[key];
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
$optionLi.toggleClass('selected', notAdded);
|
|
363
|
-
|
|
364
|
-
// Set checkbox checked value
|
|
365
|
-
$optionLi.find('input[type="checkbox"]').prop('checked', notAdded);
|
|
366
|
-
|
|
367
|
-
// use notAdded instead of true (to detect if the option is selected or not)
|
|
368
|
-
$optionLi.prop('selected', notAdded);
|
|
369
|
-
|
|
370
|
-
return notAdded;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Set text value to input
|
|
375
|
-
*/
|
|
376
|
-
_setValueToInput() {
|
|
377
|
-
let values = [];
|
|
378
|
-
let options = this.$el.find('option');
|
|
379
|
-
|
|
380
|
-
options.each((el) => {
|
|
381
|
-
if ($(el).prop('selected')) {
|
|
382
|
-
let text = $(el).text().trim();
|
|
383
|
-
values.push(text);
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
if (!values.length) {
|
|
388
|
-
let firstDisabled = this.$el.find('option:disabled').eq(0);
|
|
389
|
-
if (firstDisabled.length && firstDisabled[0].value === '') {
|
|
390
|
-
values.push(firstDisabled.text());
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
this.input.value = values.join(', ');
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/**
|
|
398
|
-
* Set selected state of dropdown to match actual select element
|
|
399
|
-
*/
|
|
400
|
-
_setSelectedStates() {
|
|
401
|
-
this._keysSelected = {};
|
|
402
|
-
|
|
403
|
-
for (let key in this._valueDict) {
|
|
404
|
-
let option = this._valueDict[key];
|
|
405
|
-
let optionIsSelected = $(option.el).prop('selected');
|
|
406
|
-
$(option.optionEl)
|
|
407
|
-
.find('input[type="checkbox"]')
|
|
408
|
-
.prop('checked', optionIsSelected);
|
|
409
|
-
if (optionIsSelected) {
|
|
410
|
-
this._activateOption($(this.dropdownOptions), $(option.optionEl));
|
|
411
|
-
this._keysSelected[key] = true;
|
|
412
|
-
} else {
|
|
413
|
-
$(option.optionEl).removeClass('selected');
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Make option as selected and scroll to selected position
|
|
420
|
-
* @param {jQuery} collection Select options jQuery element
|
|
421
|
-
* @param {Element} newOption element of the new option
|
|
422
|
-
*/
|
|
423
|
-
_activateOption(collection, newOption) {
|
|
424
|
-
if (newOption) {
|
|
425
|
-
if (!this.isMultiple) {
|
|
426
|
-
collection.find('li.selected').removeClass('selected');
|
|
427
|
-
}
|
|
428
|
-
let option = $(newOption);
|
|
429
|
-
option.addClass('selected');
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Get Selected Values
|
|
435
|
-
* @return {Array} Array of selected values
|
|
436
|
-
*/
|
|
437
|
-
getSelectedValues() {
|
|
438
|
-
let selectedValues = [];
|
|
439
|
-
for (let key in this._keysSelected) {
|
|
440
|
-
selectedValues.push(this._valueDict[key].el.value);
|
|
441
|
-
}
|
|
442
|
-
return selectedValues;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
M.FormSelect = FormSelect;
|
|
447
|
-
|
|
448
|
-
if (M.jQueryLoaded) {
|
|
449
|
-
M.initializeJqueryWrapper(FormSelect, 'formSelect', 'M_FormSelect');
|
|
450
|
-
}
|
|
451
|
-
})(cash);
|
|
1
|
+
(function($) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
let _defaults = {
|
|
5
|
+
classes: '',
|
|
6
|
+
dropdownOptions: {}
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
class FormSelect extends Component {
|
|
10
|
+
constructor(el, options) {
|
|
11
|
+
super(FormSelect, el, options);
|
|
12
|
+
if (this.$el.hasClass('browser-default')) return;
|
|
13
|
+
this.el.M_FormSelect = this;
|
|
14
|
+
this.options = $.extend({}, FormSelect.defaults, options);
|
|
15
|
+
this.isMultiple = this.$el.prop('multiple');
|
|
16
|
+
this.el.tabIndex = -1;
|
|
17
|
+
this._values = [];
|
|
18
|
+
this._setupDropdown();
|
|
19
|
+
this._setupEventHandlers();
|
|
20
|
+
}
|
|
21
|
+
static get defaults() {
|
|
22
|
+
return _defaults;
|
|
23
|
+
}
|
|
24
|
+
static init(els, options) {
|
|
25
|
+
return super.init(this, els, options);
|
|
26
|
+
}
|
|
27
|
+
static getInstance(el) {
|
|
28
|
+
let domElem = !!el.jquery ? el[0] : el;
|
|
29
|
+
return domElem.M_FormSelect;
|
|
30
|
+
}
|
|
31
|
+
destroy() {
|
|
32
|
+
this._removeEventHandlers();
|
|
33
|
+
this._removeDropdown();
|
|
34
|
+
this.el.M_FormSelect = undefined;
|
|
35
|
+
}
|
|
36
|
+
_setupEventHandlers() {
|
|
37
|
+
this._handleSelectChangeBound = this._handleSelectChange.bind(this);
|
|
38
|
+
this._handleOptionClickBound = this._handleOptionClick.bind(this);
|
|
39
|
+
this._handleInputClickBound = this._handleInputClick.bind(this);
|
|
40
|
+
$(this.dropdownOptions)
|
|
41
|
+
.find('li:not(.optgroup)')
|
|
42
|
+
.each((el) => {
|
|
43
|
+
el.addEventListener('click', this._handleOptionClickBound);
|
|
44
|
+
});
|
|
45
|
+
this.el.addEventListener('change', this._handleSelectChangeBound);
|
|
46
|
+
this.input.addEventListener('click', this._handleInputClickBound);
|
|
47
|
+
}
|
|
48
|
+
_removeEventHandlers() {
|
|
49
|
+
$(this.dropdownOptions)
|
|
50
|
+
.find('li:not(.optgroup)')
|
|
51
|
+
.each((el) => {
|
|
52
|
+
el.removeEventListener('click', this._handleOptionClickBound);
|
|
53
|
+
});
|
|
54
|
+
this.el.removeEventListener('change', this._handleSelectChangeBound);
|
|
55
|
+
this.input.removeEventListener('click', this._handleInputClickBound);
|
|
56
|
+
}
|
|
57
|
+
_handleSelectChange(e) {
|
|
58
|
+
this._setValueToInput();
|
|
59
|
+
}
|
|
60
|
+
_handleOptionClick(e) {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
let virtualOption = $(e.target).closest('li')[0];
|
|
63
|
+
this._selectOptionElement(virtualOption);
|
|
64
|
+
e.stopPropagation();
|
|
65
|
+
}
|
|
66
|
+
_arraysEqual(a, b) {
|
|
67
|
+
if (a === b) return true;
|
|
68
|
+
if (a == null || b == null) return false;
|
|
69
|
+
if (a.length !== b.length) return false;
|
|
70
|
+
for (let i = 0; i < a.length; ++i) if (a[i] !== b[i]) return false;
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
_selectOptionElement(virtualOption) {
|
|
74
|
+
if (!$(virtualOption).hasClass('disabled') && !$(virtualOption).hasClass('optgroup')) {
|
|
75
|
+
const value = this._values.filter((value) => value.optionEl === virtualOption)[0];
|
|
76
|
+
const previousSelectedValues = this.getSelectedValues();
|
|
77
|
+
if (this.isMultiple) {
|
|
78
|
+
// Multi-Select
|
|
79
|
+
this._toggleEntryFromArray(value);
|
|
80
|
+
} else {
|
|
81
|
+
// Single-Select
|
|
82
|
+
this._deselectAll();
|
|
83
|
+
this._selectValue(value);
|
|
84
|
+
}
|
|
85
|
+
// Refresh Input-Text
|
|
86
|
+
this._setValueToInput();
|
|
87
|
+
// Trigger Change-Event only when data is different
|
|
88
|
+
const actualSelectedValues = this.getSelectedValues();
|
|
89
|
+
const selectionHasChanged = !this._arraysEqual(
|
|
90
|
+
previousSelectedValues,
|
|
91
|
+
actualSelectedValues
|
|
92
|
+
);
|
|
93
|
+
if (selectionHasChanged) this.$el.trigger('change');
|
|
94
|
+
}
|
|
95
|
+
if (!this.isMultiple) this.dropdown.close();
|
|
96
|
+
}
|
|
97
|
+
_handleInputClick() {
|
|
98
|
+
if (this.dropdown && this.dropdown.isOpen) {
|
|
99
|
+
this._setValueToInput();
|
|
100
|
+
this._setSelectedStates();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
_setupDropdown() {
|
|
104
|
+
this.wrapper = document.createElement('div');
|
|
105
|
+
$(this.wrapper).addClass('select-wrapper ' + this.options.classes);
|
|
106
|
+
this.$el.before($(this.wrapper));
|
|
107
|
+
|
|
108
|
+
// Move actual select element into overflow hidden wrapper
|
|
109
|
+
let $hideSelect = $('<div class="hide-select"></div>');
|
|
110
|
+
$(this.wrapper).append($hideSelect);
|
|
111
|
+
$hideSelect[0].appendChild(this.el);
|
|
112
|
+
|
|
113
|
+
if (this.el.disabled) this.wrapper.classList.add('disabled');
|
|
114
|
+
|
|
115
|
+
// Create dropdown
|
|
116
|
+
this.$selectOptions = this.$el.children('option, optgroup');
|
|
117
|
+
this.dropdownOptions = document.createElement('ul');
|
|
118
|
+
this.dropdownOptions.id = `select-options-${M.guid()}`;
|
|
119
|
+
$(this.dropdownOptions).addClass(
|
|
120
|
+
'dropdown-content select-dropdown ' + (this.isMultiple ? 'multiple-select-dropdown' : '')
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
// Create dropdown structure
|
|
124
|
+
if (this.$selectOptions.length) {
|
|
125
|
+
this.$selectOptions.each((realOption) => {
|
|
126
|
+
if ($(realOption).is('option')) {
|
|
127
|
+
// Option
|
|
128
|
+
const virtualOption = this._createAndAppendOptionWithIcon(
|
|
129
|
+
realOption,
|
|
130
|
+
this.isMultiple ? 'multiple' : undefined
|
|
131
|
+
);
|
|
132
|
+
this._addOptionToValues(realOption, virtualOption);
|
|
133
|
+
} else if ($(realOption).is('optgroup')) {
|
|
134
|
+
// Optgroup
|
|
135
|
+
const selectOptions = $(realOption).children('option');
|
|
136
|
+
$(this.dropdownOptions).append(
|
|
137
|
+
$(
|
|
138
|
+
'<li class="optgroup"><span>' + realOption.getAttribute('label') + '</span></li>'
|
|
139
|
+
)[0]
|
|
140
|
+
);
|
|
141
|
+
selectOptions.each((realOption) => {
|
|
142
|
+
const virtualOption = this._createAndAppendOptionWithIcon(
|
|
143
|
+
realOption,
|
|
144
|
+
'optgroup-option'
|
|
145
|
+
);
|
|
146
|
+
this._addOptionToValues(realOption, virtualOption);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
$(this.wrapper).append(this.dropdownOptions);
|
|
152
|
+
|
|
153
|
+
// Add input dropdown
|
|
154
|
+
this.input = document.createElement('input');
|
|
155
|
+
$(this.input).addClass('select-dropdown dropdown-trigger');
|
|
156
|
+
this.input.setAttribute('type', 'text');
|
|
157
|
+
this.input.setAttribute('readonly', 'true');
|
|
158
|
+
this.input.setAttribute('data-target', this.dropdownOptions.id);
|
|
159
|
+
if (this.el.disabled) $(this.input).prop('disabled', 'true');
|
|
160
|
+
|
|
161
|
+
$(this.wrapper).prepend(this.input);
|
|
162
|
+
this._setValueToInput();
|
|
163
|
+
|
|
164
|
+
// Add caret
|
|
165
|
+
let dropdownIcon = $(
|
|
166
|
+
'<svg class="caret" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>'
|
|
167
|
+
);
|
|
168
|
+
$(this.wrapper).prepend(dropdownIcon[0]);
|
|
169
|
+
// Initialize dropdown
|
|
170
|
+
if (!this.el.disabled) {
|
|
171
|
+
let dropdownOptions = $.extend({}, this.options.dropdownOptions);
|
|
172
|
+
dropdownOptions.coverTrigger = false;
|
|
173
|
+
let userOnOpenEnd = dropdownOptions.onOpenEnd;
|
|
174
|
+
// Add callback for centering selected option when dropdown content is scrollable
|
|
175
|
+
dropdownOptions.onOpenEnd = (el) => {
|
|
176
|
+
let selectedOption = $(this.dropdownOptions)
|
|
177
|
+
.find('.selected')
|
|
178
|
+
.first();
|
|
179
|
+
if (selectedOption.length) {
|
|
180
|
+
// Focus selected option in dropdown
|
|
181
|
+
M.keyDown = true;
|
|
182
|
+
this.dropdown.focusedIndex = selectedOption.index();
|
|
183
|
+
this.dropdown._focusFocusedItem();
|
|
184
|
+
M.keyDown = false;
|
|
185
|
+
// Handle scrolling to selected option
|
|
186
|
+
if (this.dropdown.isScrollable) {
|
|
187
|
+
let scrollOffset =
|
|
188
|
+
selectedOption[0].getBoundingClientRect().top -
|
|
189
|
+
this.dropdownOptions.getBoundingClientRect().top; // scroll to selected option
|
|
190
|
+
scrollOffset -= this.dropdownOptions.clientHeight / 2; // center in dropdown
|
|
191
|
+
this.dropdownOptions.scrollTop = scrollOffset;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Handle user declared onOpenEnd if needed
|
|
195
|
+
if (userOnOpenEnd && typeof userOnOpenEnd === 'function')
|
|
196
|
+
userOnOpenEnd.call(this.dropdown, this.el);
|
|
197
|
+
};
|
|
198
|
+
// Prevent dropdown from closing too early
|
|
199
|
+
dropdownOptions.closeOnClick = false;
|
|
200
|
+
this.dropdown = M.Dropdown.init(this.input, dropdownOptions);
|
|
201
|
+
}
|
|
202
|
+
// Add initial selections
|
|
203
|
+
this._setSelectedStates();
|
|
204
|
+
}
|
|
205
|
+
_addOptionToValues(realOption, virtualOption) {
|
|
206
|
+
this._values.push({ el: realOption, optionEl: virtualOption });
|
|
207
|
+
}
|
|
208
|
+
_removeDropdown() {
|
|
209
|
+
$(this.wrapper)
|
|
210
|
+
.find('.caret')
|
|
211
|
+
.remove();
|
|
212
|
+
$(this.input).remove();
|
|
213
|
+
$(this.dropdownOptions).remove();
|
|
214
|
+
$(this.wrapper).before(this.$el);
|
|
215
|
+
$(this.wrapper).remove();
|
|
216
|
+
}
|
|
217
|
+
_createAndAppendOptionWithIcon(realOption, type) {
|
|
218
|
+
const li = document.createElement('li');
|
|
219
|
+
if (realOption.disabled) li.classList.add('disabled');
|
|
220
|
+
if (type === 'optgroup-option') li.classList.add(type);
|
|
221
|
+
// Text / Checkbox
|
|
222
|
+
const span = document.createElement('span');
|
|
223
|
+
if (this.isMultiple)
|
|
224
|
+
span.innerHTML = `<label><input type="checkbox"${
|
|
225
|
+
realOption.disabled ? ' disabled="disabled"' : ''
|
|
226
|
+
}><span>${realOption.innerHTML}</span></label>`;
|
|
227
|
+
else span.innerHTML = realOption.innerHTML;
|
|
228
|
+
li.appendChild(span);
|
|
229
|
+
// add Icon
|
|
230
|
+
const iconUrl = realOption.getAttribute('data-icon');
|
|
231
|
+
const classes = realOption.getAttribute('class');
|
|
232
|
+
if (iconUrl) {
|
|
233
|
+
const img = $(`<img alt="" class="${classes}" src="${iconUrl}">`);
|
|
234
|
+
li.prepend(img[0]);
|
|
235
|
+
}
|
|
236
|
+
// Check for multiple type
|
|
237
|
+
$(this.dropdownOptions).append(li);
|
|
238
|
+
return li;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
_selectValue(value) {
|
|
242
|
+
value.el.selected = true;
|
|
243
|
+
value.optionEl.classList.add('selected');
|
|
244
|
+
const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
|
|
245
|
+
if (checkbox) checkbox.checked = true;
|
|
246
|
+
}
|
|
247
|
+
_deselectValue(value) {
|
|
248
|
+
value.el.selected = false;
|
|
249
|
+
value.optionEl.classList.remove('selected');
|
|
250
|
+
const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
|
|
251
|
+
if (checkbox) checkbox.checked = false;
|
|
252
|
+
}
|
|
253
|
+
_deselectAll() {
|
|
254
|
+
this._values.forEach((value) => {
|
|
255
|
+
this._deselectValue(value);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
_isValueSelected(value) {
|
|
259
|
+
const realValues = this.getSelectedValues();
|
|
260
|
+
return realValues.some((realValue) => realValue === value.el.value);
|
|
261
|
+
}
|
|
262
|
+
_toggleEntryFromArray(value) {
|
|
263
|
+
const isSelected = this._isValueSelected(value);
|
|
264
|
+
if (isSelected) this._deselectValue(value);
|
|
265
|
+
else this._selectValue(value);
|
|
266
|
+
}
|
|
267
|
+
_getSelectedOptions() {
|
|
268
|
+
return Array.prototype.filter.call(this.el.selectedOptions, (realOption) => realOption);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
_setValueToInput() {
|
|
272
|
+
const realOptions = this._getSelectedOptions();
|
|
273
|
+
const values = this._values.filter((value) => realOptions.indexOf(value.el) >= 0);
|
|
274
|
+
const texts = values.map((value) => value.optionEl.querySelector('span').innerText.trim());
|
|
275
|
+
// Set input-text to first Option with empty value which indicates a description like "choose your option"
|
|
276
|
+
if (texts.length === 0) {
|
|
277
|
+
const firstDisabledOption = this.$el.find('option:disabled').eq(0);
|
|
278
|
+
if (firstDisabledOption.length > 0 && firstDisabledOption[0].value === '') {
|
|
279
|
+
this.input.value = firstDisabledOption.text();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
this.input.value = texts.join(', ');
|
|
284
|
+
}
|
|
285
|
+
_setSelectedStates() {
|
|
286
|
+
this._values.forEach((value) => {
|
|
287
|
+
const optionIsSelected = $(value.el).prop('selected');
|
|
288
|
+
$(value.optionEl)
|
|
289
|
+
.find('input[type="checkbox"]')
|
|
290
|
+
.prop('checked', optionIsSelected);
|
|
291
|
+
if (optionIsSelected) {
|
|
292
|
+
this._activateOption($(this.dropdownOptions), $(value.optionEl));
|
|
293
|
+
} else $(value.optionEl).removeClass('selected');
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
_activateOption(ul, li) {
|
|
297
|
+
if (!li) return;
|
|
298
|
+
if (!this.isMultiple) ul.find('li.selected').removeClass('selected');
|
|
299
|
+
$(li).addClass('selected');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
getSelectedValues() {
|
|
303
|
+
return this._getSelectedOptions().map((realOption) => realOption.value);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
M.FormSelect = FormSelect;
|
|
308
|
+
|
|
309
|
+
if (M.jQueryLoaded) M.initializeJqueryWrapper(FormSelect, 'formSelect', 'M_FormSelect');
|
|
310
|
+
})(cash);
|