Skip to content

Commit d8fb3fb

Browse files
pierredupsmnandre
authored andcommitted
[Autocomplete] Reset TomSelect when updating controller attributes
1 parent cddafa8 commit d8fb3fb

File tree

5 files changed

+86
-3
lines changed

5 files changed

+86
-3
lines changed

src/Autocomplete/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 2.23.0
4+
5+
- Reset TomSelect when updating url attribute #1505
6+
37
## 2.22.0
48

59
- Take `labelField` TomSelect option into account #2382

src/Autocomplete/assets/dist/controller.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export default class extends Controller {
4040
connect(): void;
4141
initializeTomSelect(): void;
4242
disconnect(): void;
43+
urlValueChanged(): void;
4344
private getMaxOptions;
4445
get selectElement(): HTMLSelectElement | null;
4546
get formElement(): HTMLInputElement | HTMLSelectElement;

src/Autocomplete/assets/dist/controller.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class default_1 extends Controller {
9191
}
9292
}
9393
}
94+
urlValueChanged() {
95+
this.resetTomSelect();
96+
}
9497
getMaxOptions() {
9598
return this.selectElement ? this.selectElement.options.length : 50;
9699
}
@@ -131,7 +134,6 @@ class default_1 extends Controller {
131134
this.element.innerHTML = currentHtml;
132135
this.initializeTomSelect();
133136
this.tomSelect.setValue(currentValue);
134-
this.startMutationObserver();
135137
}
136138
}
137139
changeTomSelectDisabledState(isDisabled) {

src/Autocomplete/assets/src/controller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ export default class extends Controller {
128128
}
129129
}
130130

131+
urlValueChanged() {
132+
this.resetTomSelect();
133+
}
134+
131135
#getCommonConfig(): Partial<TomSettings> {
132136
const plugins: TPluginHash = {};
133137

@@ -391,8 +395,6 @@ export default class extends Controller {
391395
this.element.innerHTML = currentHtml;
392396
this.initializeTomSelect();
393397
this.tomSelect.setValue(currentValue);
394-
395-
this.startMutationObserver();
396398
}
397399
}
398400

src/Autocomplete/assets/test/controller.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,80 @@ describe('AutocompleteController', () => {
138138
expect(fetchMock.requests()[1].url).toEqual('/path/to/autocomplete?query=foo');
139139
});
140140

141+
it('resets when ajax URL attribute on a select element changes', async () => {
142+
const { container, tomSelect } = await startAutocompleteTest(`
143+
<label for="the-select">Items</label>
144+
<select
145+
id="the-select"
146+
data-testid="main-element"
147+
data-controller="autocomplete"
148+
data-autocomplete-url-value="/path/to/autocomplete"
149+
></select>
150+
`);
151+
152+
const selectElement = getByTestId(container, 'main-element') as HTMLSelectElement;
153+
154+
// initial Ajax request on focus
155+
fetchMock.mockResponseOnce(
156+
JSON.stringify({
157+
results: [
158+
{
159+
value: 3,
160+
text: 'salad',
161+
},
162+
],
163+
})
164+
);
165+
166+
fetchMock.mockResponseOnce(
167+
JSON.stringify({
168+
results: [
169+
{
170+
value: 1,
171+
text: 'pizza',
172+
},
173+
{
174+
value: 2,
175+
text: 'popcorn',
176+
},
177+
],
178+
})
179+
);
180+
181+
const controlInput = tomSelect.control_input;
182+
183+
// wait for the initial Ajax request to finish
184+
userEvent.click(controlInput);
185+
await waitFor(() => {
186+
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(1);
187+
});
188+
189+
controlInput.value = 'foo';
190+
controlInput.dispatchEvent(new Event('input'));
191+
192+
await waitFor(() => {
193+
expect(container.querySelectorAll('.option[data-selectable]')).toHaveLength(2);
194+
});
195+
196+
expect(selectElement.value).toBe('');
197+
tomSelect.addItem('2');
198+
expect(selectElement.value).toBe('2');
199+
200+
selectElement.outerHTML = `
201+
<select
202+
id="the-select"
203+
data-testid="main-element"
204+
data-controller="autocomplete"
205+
data-autocomplete-url-value="/path/to/autocomplete2"
206+
></select>
207+
`;
208+
209+
// wait for the MutationObserver to flush these changes
210+
await shortDelay(10);
211+
212+
expect(selectElement.value).toBe('');
213+
});
214+
141215
it('connect with ajax URL on an input element', async () => {
142216
const { container, tomSelect } = await startAutocompleteTest(`
143217
<label for="the-input">Items</label>

0 commit comments

Comments
 (0)