Skip to content

Commit 1087e38

Browse files
committed
fix(select): fixed pre-select bug in multi-select and improved code-structure
1 parent cb52a6e commit 1087e38

File tree

2 files changed

+73
-59
lines changed

2 files changed

+73
-59
lines changed

js/select.js

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@
8080
} else {
8181
// Single-Select
8282
this._deselectAll();
83-
value.el.setAttribute('selected', 'selected');
83+
this._selectValue(value);
8484
}
85+
// Refresh Input-Text
86+
this._setValueToInput();
87+
// Trigger Change-Event only when data is different
8588
const actualSelectedValues = this.getSelectedValues();
8689
const selectionHasChanged = !this._arraysEqual(
8790
previousSelectedValues,
@@ -166,6 +169,7 @@
166169
// Initialize dropdown
167170
if (!this.el.disabled) {
168171
let dropdownOptions = $.extend({}, this.options.dropdownOptions);
172+
dropdownOptions.coverTrigger = false;
169173
let userOnOpenEnd = dropdownOptions.onOpenEnd;
170174
// Add callback for centering selected option when dropdown content is scrollable
171175
dropdownOptions.onOpenEnd = (el) => {
@@ -233,44 +237,41 @@
233237
$(this.dropdownOptions).append(li);
234238
return li;
235239
}
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+
}
236247
_deselectValue(value) {
248+
value.el.selected = false;
237249
value.optionEl.classList.remove('selected');
238-
value.el.removeAttribute('selected');
250+
const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
251+
if (checkbox) checkbox.checked = false;
239252
}
240253
_deselectAll() {
241254
this._values.forEach((value) => {
242255
this._deselectValue(value);
243256
});
244257
}
258+
_isValueSelected(value) {
259+
const realValues = this.getSelectedValues();
260+
return realValues.some((realValue) => realValue === value.el.value);
261+
}
245262
_toggleEntryFromArray(value) {
246-
const li = value.optionEl;
247-
const isSelected = li.classList.contains('selected');
248-
if (isSelected) {
249-
value.el.removeAttribute('selected');
250-
li.classList.remove('selected');
251-
} else {
252-
value.el.setAttribute('selected', 'selected');
253-
li.classList.add('selected');
254-
}
255-
li.querySelector('input[type="checkbox"]').checked = !isSelected;
256-
return isSelected;
263+
const isSelected = this._isValueSelected(value);
264+
if (isSelected) this._deselectValue(value);
265+
else this._selectValue(value);
257266
}
258-
_isOptionChosen(realOption) {
259-
if (realOption.hasAttribute('disabled')) return false;
260-
return realOption.selected || realOption.hasAttribute('selected');
267+
_getSelectedOptions() {
268+
return Array.prototype.map.call(this.el.selectedOptions, (realOption) => realOption);
261269
}
270+
262271
_setValueToInput() {
263-
const texts = this._values
264-
.filter((value) => this._isOptionChosen(value.el))
265-
.map((value) => value.optionEl.querySelector('span').innerText.trim());
266-
// Set input-text to first Option with empty value which indicates a description like "choose your option"
267-
if (texts.length === 0) {
268-
const firstDisabledOption = this.$el.find('option:disabled').eq(0);
269-
if (firstDisabledOption.length > 0 && firstDisabledOption[0].value === '') {
270-
this.input.value = firstDisabledOption.text();
271-
return;
272-
}
273-
}
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());
274275
this.input.value = texts.join(', ');
275276
}
276277
_setSelectedStates() {
@@ -291,9 +292,7 @@
291292
}
292293

293294
getSelectedValues() {
294-
return this._values
295-
.filter((value) => this._isOptionChosen(value.el))
296-
.map((value) => value.el.value);
295+
return this._getSelectedOptions().map((realOption) => realOption.value);
297296
}
298297
}
299298

test/html/select.html

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,31 @@
1818
</head>
1919
<body>
2020

21-
<div class="input-field col s12">
22-
<select>
23-
<option value="" disabled selected>Choose your option</option>
24-
<option value="1">Option 1</option>
25-
<option value="2">Option 2</option>
26-
<option value="3">Option 3</option>
27-
</select>
28-
<label>Single-Select</label>
29-
</div>
30-
31-
<div class="input-field col s12">
32-
<select multiple>
33-
<option value="" disabled selected>Choose your option</option>
34-
<option value="1">Option 1</option>
35-
<option value="2">Option 2</option>
36-
<option value="3">Option 3</option>
37-
</select>
38-
<label>Multi-Select</label>
21+
<div class="row">
22+
<div class="input-field col s12 m6">
23+
<select>
24+
<option value="1">Option 1</option>
25+
<option value="2">Option 2</option>
26+
<option value="3">Option 3</option>
27+
</select>
28+
<label>Single-Select</label>
29+
<div>
30+
<button class="btn1">Get Single-Select Values</button>
31+
</div>
32+
</div>
33+
<div class="input-field col s12 m6">
34+
<select multiple>
35+
<option value="1">Option 1</option>
36+
<option value="2">Option 2</option>
37+
<option value="3">Option 3</option>
38+
</select>
39+
<label>Multi-Select</label>
40+
<div>
41+
<button class="btn2">Get Multi-Select Values</button>
42+
</div>
43+
</div>
3944
</div>
4045

41-
<div class="input-field col s12">
42-
<button class="btn1">Get Single-Select Values</button>
43-
<button class="btn2">Get Multi-Select Values</button>
44-
</div>
4546

4647
<div class="input-field col s12">
4748
<select>
@@ -116,13 +117,27 @@ <h5>Dynamically generated Select-Options <button class="btn3">Create + Init Sele
116117
</div>
117118
</div>
118119

119-
<label>Browser Select</label>
120-
<select class="browser-default">
121-
<option value="" disabled selected>Choose your option</option>
122-
<option value="1">Option 1</option>
123-
<option value="2">Option 2</option>
124-
<option value="3">Option 3</option>
125-
</select>
120+
<div class="row">
121+
<div class="col s12 m6">
122+
<label>Browser Single-Select</label>
123+
<select class="browser-default">
124+
<option value="" disabled selected>Choose your option</option>
125+
<option value="1">Option 1</option>
126+
<option value="2">Option 2</option>
127+
<option value="3">Option 3</option>
128+
</select>
129+
</div>
130+
<div class="col s12 m6">
131+
<label>Browser Multi-Select</label>
132+
<select class="browser-default" multiple style="height:150px;">
133+
<option value="" disabled selected>Choose your option</option>
134+
<option value="1">Option 1</option>
135+
<option value="2">Option 2</option>
136+
<option value="3">Option 3</option>
137+
</select>
138+
</div>
139+
</div>
140+
126141

127142

128143
<script src="../../../bin/materialize.js"></script>

0 commit comments

Comments
 (0)