diff --git a/js/bootstrap-select.js b/js/bootstrap-select.js index 9f1390c..8827de4 100644 --- a/js/bootstrap-select.js +++ b/js/bootstrap-select.js @@ -3434,6 +3434,19 @@ class Selectpicker { this.element.classList.add('mobile-device'); } + resetMenuData () { + this.selectpicker.main.data = []; + this.selectpicker.main.elements = []; + this.selectpicker.main.hasMore = false; + this.selectpicker.search.data = []; + this.selectpicker.search.elements = []; + this.selectpicker.search.hasMore = false; + this.selectpicker.current.data = this.selectpicker.main.data; + this.selectpicker.current.elements = this.selectpicker.main.elements; + this.selectpicker.current.hasMore = false; + this.selectpicker.isSearching = false; + } + refresh () { var that = this; // update options if data attributes have been changed @@ -3444,6 +3457,7 @@ class Selectpicker { this.render(); this.buildList(); } else { + this.resetMenuData(); this.fetchData(function () { that.render(); that.buildList(); diff --git a/tests/e2e/tags-editor.spec.js b/tests/e2e/tags-editor.spec.js index 2f3bba9..b2c3473 100644 --- a/tests/e2e/tags-editor.spec.js +++ b/tests/e2e/tags-editor.spec.js @@ -134,6 +134,44 @@ test.describe('Tags-style live search editor', () => { await expect(optionAnchor(picker, 'DELTA')).toBeVisible(); }); + test('does not duplicate selected tags after repeated refresh calls', async ({ page }) => { + const id = await page.evaluate(() => { + document.body.innerHTML += ` + + `; + + new Selectpicker('#tags-editor-refresh', { + liveSearch: true, + showSelectedTags: true, + openOptions: true + }); + + return 'tags-editor-refresh'; + }); + + const picker = widget(page, id); + + await expect(picker.locator('> .bs-selected-items-external .bs-selected-item')).toHaveCount(2); + await expect(picker.locator('.filter-option-inner-inner')).toHaveText('2 items selected'); + + await page.evaluate((selectId) => { + const instance = Selectpicker.getInstance('#' + selectId); + instance.refresh(); + instance.refresh(); + }, id); + + await expect(picker.locator('> .bs-selected-items-external .bs-selected-item')).toHaveCount(2); + await expect(picker.locator('> .bs-selected-items-external .bs-selected-item')).toContainText(['Option 1', 'Option 2']); + await expect(picker.locator('.filter-option-inner-inner')).toHaveText('2 items selected'); + await expect.poll(async () => page.evaluate((selectId) => { + return Array.from(document.getElementById(selectId).selectedOptions).map(option => option.value); + }, id)).toEqual(['one', 'two']); + }); + test('supports checkbox selection indicators and search placeholder fallback', async ({ page }) => { const id = await page.evaluate(() => { document.body.innerHTML += `