Skip to content

Commit f42ae19

Browse files
authored
feat: add lazyData to lazy load only after clicking/opening select (#361)
1 parent 0491b8d commit f42ae19

28 files changed

+622
-101
lines changed

packages/demo/src/app-routing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ import Options38 from './options/options38.js';
7070
import Options39 from './options/options39.js';
7171
import Options40 from './options/options40.js';
7272
import Options41 from './options/options41.js';
73+
import Options42 from './options/options42.js';
7374

7475
export const navbarRouting = [
7576
{ name: 'getting-started', view: '/src/getting-started.html', viewModel: GettingStarted, title: 'Getting Started' },
@@ -142,6 +143,7 @@ export const exampleRouting = [
142143
{ name: 'options39', view: '/src/options/options39.html', viewModel: Options39, title: 'Label Id (aria-labelledby)' },
143144
{ name: 'options40', view: '/src/options/options40.html', viewModel: Options40, title: 'Pre-Filter Data' },
144145
{ name: 'options41', view: '/src/options/options41.html', viewModel: Options41, title: 'Pre-Sort Data' },
146+
{ name: 'options42', view: '/src/options/options42.html', viewModel: Options42, title: 'Lazy Load Data' },
145147
],
146148
},
147149
{

packages/demo/src/events/events.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ export default class Example {
99
this.ms1 = multipleSelect('select', {
1010
filter: true,
1111
showSearchClear: true,
12+
onBeforeOpen: () => {
13+
this.log('onBeforeOpen event fire!\n');
14+
},
1215
onOpen: () => {
1316
this.log('onOpen event fire!\n');
1417
},
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<div class="row mb-2">
2+
<div class="col-md-12 title-desc">
3+
<h2 class="bd-title">
4+
Lazy Load Data
5+
<span class="float-end links">
6+
Code <span class="fa fa-link"></span>
7+
<span class="small">
8+
<a
9+
target="_blank"
10+
href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options42.html"
11+
>html</a
12+
>
13+
|
14+
<a target="_blank" href="https://github.com/ghiscoding/multiple-select-vanilla/blob/main/packages/demo/src/options/options42.ts"
15+
>ts</a
16+
>
17+
</span>
18+
</span>
19+
</h2>
20+
<div class="demo-subtitle">
21+
Use <code>lazyLoad: callback</code> to lazy load data only after clicking and opening the select dropdown.
22+
Note that once the data is loaded, it no longer needs to be lazy loaded again and so re-opening the select dropdown will show instantly afterward.
23+
You can refresh the page, or change server delay, to retest the lazy loading.
24+
Also note that any option pre-selection will only show up after the data is fully loaded.
25+
</div>
26+
</div>
27+
</div>
28+
29+
<div>
30+
<div class="mb-3 row">
31+
<label class="col-sm-2"> Server Delay (ms) </label>
32+
33+
<div class="col-sm-10">
34+
<input id="serverdelay" type="number" value="1000" step="100" style="width: 100px" />
35+
</div>
36+
</div>
37+
38+
<div class="mb-3 row">
39+
<label class="col-sm-2"> Basic Array </label>
40+
41+
<div class="col-sm-10">
42+
<select id="basic" class="full-width" data-test="select1"></select>
43+
</div>
44+
</div>
45+
46+
<div class="mb-3 row">
47+
<label class="col-sm-2"> Data Array </label>
48+
49+
<div class="col-sm-10">
50+
<select id="group" class="full-width" multiple data-test="select2"></select>
51+
</div>
52+
</div>
53+
54+
<div class="mb-3 row">
55+
<label class="col-sm-2"> Group Array </label>
56+
57+
<div class="col-sm-10">
58+
<select id="group" class="full-width" multiple data-test="select3"></select>
59+
</div>
60+
</div>
61+
</div>
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
import { type MultipleSelectInstance, multipleSelect } from 'multiple-select-vanilla';
2+
3+
export default class Example {
4+
serverDelayInput?: HTMLInputElement | null;
5+
ms1?: MultipleSelectInstance;
6+
ms2?: MultipleSelectInstance;
7+
ms3?: MultipleSelectInstance;
8+
serverDelay = 1000;
9+
10+
changeServerDelay(event: Event) {
11+
const target = event.target as HTMLInputElement;
12+
this.serverDelay = +target.value;
13+
this.createMultipleSelect();
14+
}
15+
16+
mount() {
17+
this.serverDelayInput = document.querySelector('#serverdelay');
18+
this.serverDelayInput!.addEventListener('keyup', this.changeServerDelay.bind(this));
19+
this.createMultipleSelect();
20+
}
21+
22+
createMultipleSelect() {
23+
console.log('recreate ms-select');
24+
this.ms1 = multipleSelect('select[data-test=select1]', {
25+
singleRadio: true,
26+
lazyData: () => {
27+
return new Promise(resolve => {
28+
setTimeout(() => {
29+
resolve([
30+
'January',
31+
'February',
32+
'March',
33+
'April',
34+
'May',
35+
'June',
36+
'July',
37+
'August',
38+
'September',
39+
'October',
40+
'November',
41+
'December',
42+
]);
43+
}, this.serverDelay);
44+
});
45+
},
46+
}) as MultipleSelectInstance;
47+
48+
this.ms2 = multipleSelect('select[data-test=select2]', {
49+
lazyData: () => {
50+
return new Promise(resolve => {
51+
setTimeout(() => {
52+
resolve([
53+
{
54+
text: 'January',
55+
value: 1,
56+
},
57+
{
58+
text: 'February',
59+
value: 2,
60+
selected: true,
61+
},
62+
{
63+
text: 'March',
64+
value: 3,
65+
disabled: true,
66+
},
67+
{
68+
text: 'April',
69+
value: 4,
70+
selected: true,
71+
},
72+
{
73+
text: 'May',
74+
value: 5,
75+
},
76+
{
77+
text: 'June',
78+
value: 6,
79+
},
80+
{
81+
text: 'July',
82+
value: 7,
83+
},
84+
{
85+
text: 'August',
86+
value: 8,
87+
},
88+
{
89+
text: 'September',
90+
value: 9,
91+
},
92+
{
93+
text: 'October',
94+
value: 10,
95+
},
96+
{
97+
text: 'November',
98+
value: 11,
99+
},
100+
{
101+
text: 'December',
102+
value: 12,
103+
},
104+
]);
105+
}, this.serverDelay);
106+
});
107+
},
108+
}) as MultipleSelectInstance;
109+
110+
this.ms3 = multipleSelect('select[data-test=select3]', {
111+
lazyData: () => {
112+
return new Promise(resolve => {
113+
setTimeout(() => {
114+
resolve([
115+
{
116+
type: 'optgroup',
117+
label: 'Q1',
118+
children: [
119+
{
120+
text: 'January',
121+
value: 1,
122+
},
123+
{
124+
text: 'February',
125+
value: 2,
126+
selected: true,
127+
},
128+
{
129+
text: 'March',
130+
value: 3,
131+
selected: true,
132+
},
133+
],
134+
},
135+
{
136+
type: 'optgroup',
137+
label: 'Q2',
138+
children: [
139+
{
140+
text: 'April',
141+
value: 4,
142+
},
143+
{
144+
text: 'May',
145+
value: 5,
146+
},
147+
{
148+
text: 'June',
149+
value: 6,
150+
},
151+
],
152+
},
153+
{
154+
type: 'optgroup',
155+
label: 'Q3',
156+
children: [
157+
{
158+
text: 'July',
159+
value: 7,
160+
},
161+
{
162+
text: 'August',
163+
value: 8,
164+
},
165+
{
166+
text: 'September',
167+
value: 9,
168+
},
169+
],
170+
},
171+
{
172+
type: 'optgroup',
173+
label: 'Q4',
174+
children: [
175+
{
176+
text: 'October',
177+
value: 10,
178+
},
179+
{
180+
text: 'November',
181+
value: 11,
182+
},
183+
{
184+
text: 'December',
185+
value: 12,
186+
},
187+
],
188+
},
189+
]);
190+
}, this.serverDelay);
191+
});
192+
},
193+
}) as MultipleSelectInstance;
194+
}
195+
196+
unmount() {
197+
// destroy ms instance(s) to avoid DOM leaks
198+
this.ms1?.destroy();
199+
this.ms2?.destroy();
200+
this.ms3?.destroy();
201+
this.ms1 = undefined;
202+
this.ms2 = undefined;
203+
this.ms3 = undefined;
204+
this.serverDelayInput!.removeEventListener('click', this.changeServerDelay.bind(this));
205+
}
206+
}

0 commit comments

Comments
 (0)