Skip to content

Commit

Permalink
Merge pull request #9124 from surveyjs/bug/9111-Dropdown-Lazy-Loading…
Browse files Browse the repository at this point in the history
…-display-duplicate-entries

Dropdown with Lazy Loading - A list of items display duplicate entries
  • Loading branch information
OlgaLarina authored Dec 3, 2024
2 parents fbf8a87 + cdaf9b2 commit 05902a8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 4 deletions.
12 changes: 8 additions & 4 deletions packages/survey-core/src/dropdownListModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,8 @@ export class DropdownListModel extends Base {
const isUpdate = (this.itemsSettings.skip + 1) < this.itemsSettings.totalCount;
if (!this.itemsSettings.skip || isUpdate) {

this.resetTimer();
if (!!this.filterString && settings.dropdownSearchDelay > 0) {
if (!!this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
this.timer = setTimeout(() => {
this.loadQuestionChoices(callbackAfterItemsLoaded);
}, settings.dropdownSearchDelay);
Expand All @@ -92,6 +89,13 @@ export class DropdownListModel extends Base {
}
}

private resetTimer(): void {
if (!!this.timer) {
clearTimeout(this.timer);
this.timer = undefined;
}
}

private updatePopupFocusFirstInputSelector() {
this._popupModel.focusFirstInputSelector = this.focusFirstInputSelector;
}
Expand Down
57 changes: 57 additions & 0 deletions packages/survey-core/tests/questionDropdownTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2118,4 +2118,61 @@ QUnit.test("Rapidly Changing Search Filter", (assert) => {
}, callbackTimeOutDelta);
done1();
}, callbackTimeOutDelta);
});

QUnit.test("Dropdown with Lazy Loading - A list of items display duplicate entries #9111", assert => {
const done1 = assert.async();
const done2 = assert.async();
const done3 = assert.async();
const done4 = assert.async();
const newValueDebouncedInputValue = onChoicesLazyLoadCallbackTimeOut;
const oldValueDebouncedInputValue = settings.dropdownSearchDelay;
settings.dropdownSearchDelay = newValueDebouncedInputValue;

const json = {
questions: [{ "type": "dropdown", "name": "q1", "choicesLazyLoadEnabled": true }]
};
const survey = new SurveyModel(json);
survey.onChoicesLazyLoad.add((_, opt) => {
setTimeout(() => {
opt.setItems(getNumberArray(0, 5, opt.filter), 5);
}, onChoicesLazyLoadCallbackTimeOut);
});

const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
const itemsSettings = question.dropdownListModel["itemsSettings"];

assert.equal(question.choicesLazyLoadEnabled, true);
assert.equal(question.choices.length, 0);
assert.equal(question.choices.length, 0, "question.choices.length #1");
assert.equal(itemsSettings.items.length, 0, "itemsSettings.items.length #1");

question.dropdownListModel.popupModel.show();
setTimeout(() => {
assert.equal(question.choices.length, 5, "question.choices.length #2");

question.dropdownListModel.filterString = "22";
setTimeout(() => {
assert.equal(question.choices.length, 5, "question.choices.length #3");

question.dropdownListModel.filterString = "2";
setTimeout(() => {
assert.equal(question.choices.length, 5, "question.choices.length #4");

question.dropdownListModel.filterString = "";
setTimeout(() => {
assert.equal(question.choices.length, 5, "question.choices.length #5");

settings.dropdownSearchDelay = oldValueDebouncedInputValue;
done4();
}, onChoicesLazyLoadCallbackTimeOut + newValueDebouncedInputValue + callbackTimeOutDelta);

done3();
}, callbackTimeOutDelta);

done2();
}, onChoicesLazyLoadCallbackTimeOut + newValueDebouncedInputValue + callbackTimeOutDelta);

done1();
}, onChoicesLazyLoadCallbackTimeOut + newValueDebouncedInputValue + callbackTimeOutDelta);
});

0 comments on commit 05902a8

Please sign in to comment.