Skip to content

Commit ddbc32c

Browse files
committed
create helpers + add example
1 parent dbe6f2b commit ddbc32c

File tree

4 files changed

+57
-26
lines changed

4 files changed

+57
-26
lines changed

packages/demo/src/examples/example07.html

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ <h2 class="bd-title">
2929
<label class="col-sm-2">Single Select </label>
3030

3131
<div class="col-sm-10">
32-
<select name="select1" class="full-width">
32+
<select id="select1" name="select1" class="full-width">
3333
<option value="1">First</option>
3434
<option value="2">Second</option>
3535
<option value="3">Third</option>
@@ -42,7 +42,7 @@ <h2 class="bd-title">
4242
<label class="col-sm-2">Multiple Select </label>
4343

4444
<div class="col-sm-10">
45-
<select name="select2" class="full-width" data-test="select2" multiple required>
45+
<select id="select2" name="select2" class="full-width" data-test="select2" multiple required>
4646
<option value="1">First</option>
4747
<option value="2">Second</option>
4848
<option value="3">Third</option>
@@ -51,6 +51,15 @@ <h2 class="bd-title">
5151
</div>
5252
</div>
5353

54+
<div class="mb-3 row">
55+
<label class="col-sm-2">Select with dynamic options</label>
56+
57+
<div class="col-sm-10">
58+
<select id="select3" name="select3" class="full-width" data-test="select3" required>
59+
</select>
60+
</div>
61+
</div>
62+
5463
<div class="mb-3 row">
5564
<div class="col-sm-10 offset-sm-2">
5665
<button type="button" class="btn btn-primary submit7" data-testid="submit">Submit</button>

packages/demo/src/examples/example07.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@ export default class Example {
55
ms: MultipleSelectInstance[] = [];
66

77
mount() {
8-
this.ms = multipleSelect('select') as MultipleSelectInstance[];
8+
this.ms = multipleSelect('#select1, #select2') as MultipleSelectInstance[];
9+
this.ms3 = multipleSelect('#select3', {
10+
lazyData: () => {
11+
return new Promise(resolve => {
12+
resolve({ '1': 'First', '2': 'Second', '3': 'Third', '4': 'Fourth', '5': 'Fifth'})
13+
})
14+
}
15+
});
916
this.btnElm = document.querySelector('.submit7');
1017
this.btnElm!.addEventListener('click', this.clickListener);
1118
}
@@ -16,6 +23,8 @@ export default class Example {
1623
// destroy ms instance(s) to avoid DOM leaks
1724
this.ms.forEach(m => m.destroy());
1825
this.ms = [];
26+
this.ms3.destroy();
27+
this.ms = undefined;
1928
}
2029

2130
clickListener = () => {

packages/multiple-select-vanilla/src/MultipleSelectInstance.ts

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
classNameToList,
1414
convertItemRowToHtml,
1515
createDomElement,
16+
createDomStructureFromData,
1617
emptyElement,
1718
findParent,
1819
getComputedSize,
@@ -336,7 +337,7 @@ export class MultipleSelectInstance {
336337
}
337338

338339
if (!this.fromHtml) {
339-
this.initHtmlRows();
340+
// this.initHtmlRows();
340341
}
341342

342343
this.dataTotal = setDataKeys(this.data || []);
@@ -345,25 +346,7 @@ export class MultipleSelectInstance {
345346
protected initHtmlRows() {
346347
this.elm.innerHTML = '';
347348
if (!this.data) return;
348-
this.data.forEach((it: OptGroupRowData | OptionRowData) => {
349-
if (it.type === 'optgroup') {
350-
const optgroup = document.createElement('optgroup');
351-
optgroup.label = (it as OptGroupRowData).label;
352-
(it as OptGroupRowData).children.forEach((opt: OptionRowData) => {
353-
this.buildOption(optgroup, opt);
354-
});
355-
this.elm.appendChild(optgroup);
356-
} else {
357-
this.buildOption(this.elm, it as OptionRowData);
358-
}
359-
});
360-
}
361-
362-
protected buildOption(parent: HTMLElement, it: OptionRowData) {
363-
const option = document.createElement('option');
364-
option.value = it.value.toString();
365-
option.text = it.text;
366-
parent.appendChild(option);
349+
return createDomStructureFromData(this.data, this.elm);
367350
}
368351

369352
protected initRow(elm: HTMLOptionElement, groupDisabled?: boolean) {
@@ -1271,10 +1254,10 @@ export class MultipleSelectInstance {
12711254
isLazyProcess = true;
12721255
this.dropElm?.querySelector('ul.ms-list')?.remove();
12731256
this.options.lazyData().then(data => {
1274-
this.fromHtml = false;
12751257
// when data is ready, remove spinner & update dropdown and selection
12761258
this.options.data = data;
12771259
this._isLazyLoaded = true;
1260+
this.fromHtml = false;
12781261
this.dropElm?.querySelector('.ms-loading')?.remove();
12791262
this.initData();
12801263
this.initList(true);
@@ -1582,7 +1565,7 @@ export class MultipleSelectInstance {
15821565
} else {
15831566
// when multiple values could be set, we need to loop through each
15841567
Array.from(this.elm.options).forEach(option => {
1585-
option.selected = selectedValues.some(val => val.toString() === option.value);
1568+
option.selected = selectedValues.some(val => val().toString() === option.value);
15861569
});
15871570
}
15881571

packages/multiple-select-vanilla/src/utils/domUtils.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { HtmlStruct, InferDOMType } from '../models/interfaces.js';
1+
import type { HtmlStruct, InferDOMType, OptGroupRowData, OptionRowData } from '../models/interfaces.js';
22
import { isDefined, objectRemoveEmptyProps } from './utils.js';
33

44
export interface HtmlElementPosition {
@@ -102,6 +102,36 @@ export function createDomStructure(item: HtmlStruct, appendToElm?: HTMLElement,
102102
return elm;
103103
}
104104

105+
106+
/**
107+
* Create html node with optgroups and options from data
108+
* @param data - array of options and/or optgroups
109+
* @param parent - parent element to append to
110+
* @return {object} element - updated element
111+
*/
112+
export function createDomStructureFromData(data: Array<OptGroupRowData | OptionRowData>, parent: HTMLElement): HTMLElement {
113+
data.forEach(row => {
114+
if (row.type === 'optgroup') {
115+
const optgroup = createDomElement('optgroup', { label: (row as OptGroupRowData).label }, parent);
116+
if ((row as OptGroupRowData).children) {
117+
createDomStructureFromData((row as OptGroupRowData).children, optgroup);
118+
}
119+
} else {
120+
const optionProps: any = {
121+
value: row.value,
122+
disabled: row.disabled || false,
123+
selected: row.selected || false
124+
};
125+
if (row.classes) {
126+
optionProps.className = row.classes;
127+
}
128+
const option = createDomElement('option', optionProps, parent);
129+
option.textContent = (row as OptionRowData).text;
130+
}
131+
});
132+
return parent;
133+
}
134+
105135
/** takes an html block object and converts to a real HTMLElement */
106136
export function convertItemRowToHtml(item: HtmlStruct): HTMLElement {
107137
if (item.hasOwnProperty('tagName')) {

0 commit comments

Comments
 (0)