Skip to content

Commit

Permalink
resolve #7043 Dropdown with Lazy loading throws Duplicate keys detect…
Browse files Browse the repository at this point in the history
…ed errors Vue2
  • Loading branch information
OlgaLarina committed Oct 4, 2023
1 parent 6ecdce2 commit 3d4c09b
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/dropdownListModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ export class DropdownListModel extends Base {
this.resetFilterString();
}
protected onSetFilterString(): void {
if (!this.filterString && !this.popupModel.isVisible) return;
if (!!this.filterString && !this.popupModel.isVisible) {
this.popupModel.isVisible = true;
}
Expand Down Expand Up @@ -508,11 +509,11 @@ export class DropdownListModel extends Base {
this._popupModel.isVisible = true;
return;
}
doKey2ClickBlur(event);
this._popupModel.isVisible = false;
this.resetFilterString();
this.inputString = null;
this.hintString = "";
doKey2ClickBlur(event);
this._popupModel.isVisible = false;
event.stopPropagation();
}
onFocus(event: any): void {
Expand Down
119 changes: 119 additions & 0 deletions tests/questionDropdownTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1744,4 +1744,123 @@ QUnit.test("lazy loading: change choicesLazyLoadEnabled on runtime", assert => {
assert.equal(question.choices.length, 5);
assert.equal(question.dropdownListModel["listModel"].visibleItems.length, 6, "#3");
assert.equal(question.dropdownListModel["listModel"].visibleItems[5].id, "loadingIndicator");
});
QUnit.test("lazy loading: duplication of elements after blur", assert => {
const done = assert.async(4);
const json = {
questions: [{
"type": "dropdown",
"name": "q1",
"choicesLazyLoadEnabled": true,
"choicesLazyLoadPageSize": 25,
}]
};
const survey = new SurveyModel(json);
survey.onChoicesLazyLoad.add(callback);
const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
const itemsSettings = question.dropdownListModel["itemsSettings"];

assert.equal(question.choicesLazyLoadEnabled, true);
assert.equal(question.choices.length, 0, "question.choices.length #0");
question.dropdownListModel.popupModel.isVisible = true;
question.dropdownListModel.changeSelectionWithKeyboard(false);
setTimeout(() => {
assert.equal(question.choices.length, 25, "question.choices.length #1");
assert.equal(question.dropdownListModel.inputStringRendered, "", "question.dropdownListModel.inputStringRendered #1");
assert.equal(itemsSettings.skip, 25, "skip #1");
assert.equal(itemsSettings.take, 25, "take #1");
assert.equal(itemsSettings.totalCount, 55, "totalCount #1");
assert.equal(itemsSettings.items.length, 25, "items.length #1");
question.dropdownListModel.inputStringRendered = "11";

setTimeout(() => {
assert.equal(question.choices.length, 25, "question.choices.length #2");
assert.equal(question.dropdownListModel.inputStringRendered, "11", "question.dropdownListModel.inputStringRendered #2");
assert.equal(itemsSettings.skip, 25, "skip #2");
assert.equal(itemsSettings.take, 25, "take #2");
assert.equal(itemsSettings.totalCount, 55, "totalCount #2");
assert.equal(itemsSettings.items.length, 25, "items.length #2");
question.dropdownListModel.onBlur({
keyCode: 0,
preventDefault: () => { },
stopPropagation: () => { }
});

setTimeout(() => {
assert.equal(question.value, undefined);
assert.equal(question.choices.length, 25, "question.choices.length #3");
assert.equal(question.dropdownListModel.inputStringRendered, "", "question.dropdownListModel.inputStringRendered #3");
assert.equal(itemsSettings.skip, 0, "skip #3");
assert.equal(itemsSettings.take, 25, "take #3");
assert.equal(itemsSettings.totalCount, 0, "totalCount #3");
assert.equal(itemsSettings.items.length, 0, "items.length #3");
question.dropdownListModel.popupModel.isVisible = true;

setTimeout(() => {
assert.equal(question.choices.length, 25, "question.choices.length #4");
assert.equal(question.dropdownListModel.inputStringRendered, "", "question.dropdownListModel.inputStringRendered #4");

done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
});
QUnit.test("lazy loading: check onChoicesLazyLoad callback count", assert => {
const done = assert.async(4);
let callbackCount = 0;
const json = {
questions: [{
"type": "dropdown",
"name": "q1",
"choicesLazyLoadEnabled": true,
"choicesLazyLoadPageSize": 25,
}]
};
const survey = new SurveyModel(json);
survey.onChoicesLazyLoad.add((_, opt) => {
const total = 55;
setTimeout(() => {
callbackCount++;
if(opt.skip + opt.take < total) {
opt.setItems(getNumberArray(opt.skip + 1, opt.take, opt.filter), total);
} else {
opt.setItems(getNumberArray(opt.skip + 1, total - opt.skip, opt.filter), total);
}
}, onChoicesLazyLoadCallbackTimeOut); });
const question = <QuestionDropdownModel>survey.getAllQuestions()[0];

assert.equal(callbackCount, 0);
question.dropdownListModel.popupModel.isVisible = true;
question.dropdownListModel.changeSelectionWithKeyboard(false);
setTimeout(() => {
assert.equal(callbackCount, 1);
question.dropdownListModel.inputStringRendered = "11";

setTimeout(() => {
assert.equal(callbackCount, 2);
question.dropdownListModel.onBlur({
keyCode: 0,
preventDefault: () => { },
stopPropagation: () => { }
});

setTimeout(() => {
assert.equal(callbackCount, 2);
question.dropdownListModel.popupModel.isVisible = true;

setTimeout(() => {
assert.equal(callbackCount, 3);

done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
done();
}, onChoicesLazyLoadCallbackTimeOut + callbackTimeOutDelta);
});

0 comments on commit 3d4c09b

Please sign in to comment.