Skip to content

Commit

Permalink
work for #4780 : rename API
Browse files Browse the repository at this point in the history
  • Loading branch information
OlgaLarina committed Oct 18, 2022
1 parent 442acaf commit 7386f4d
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/base-interfaces.ts
Expand Up @@ -169,7 +169,7 @@ export interface ISurvey extends ITextProcessor, ISurveyErrorOwner {
): IQuestion;
canChangeChoiceItemsVisibility(): boolean;
getChoiceItemVisibility(question: IQuestion, item: any, val: boolean): boolean;
getQuestionData(options: { question: IQuestion, filterString: string, startIndex: number, pageSize: number, setItems: (loaded: boolean, items: Array<any>, total: number) => void }): void;
loadQuestionChoices(options: { question: IQuestion, filter: string, skip: number, take: number, setItems: (items: Array<any>, totalCount: number) => void }): void;
matrixRowAdded(question: IQuestion, row: any): any;
matrixBeforeRowAdded(options: {
question: IQuestion,
Expand Down
51 changes: 24 additions & 27 deletions src/dropdownListModel.ts
Expand Up @@ -7,47 +7,43 @@ import { PopupModel } from "./popup";
import { Question } from "./question";
import { doKey2ClickBlur, doKey2ClickUp } from "./utils/utils";

const pageSize = 25;

export class DropdownListModel extends Base {
private _popupModel: PopupModel;
private focusFirstInputSelector = ".sv-list__item--selected";
private itemsSettings: {startIndex: number, pageSize: number, total: number, items: any[] } = { startIndex: 0, pageSize: pageSize, total: 0, items: [] };
private itemsSettings: {skip: number, take: number, totalCount: number, items: any[] } = { skip: 0, take: 0, totalCount: 0, items: [] };
protected listModel: ListModel;
protected popupCssClasses = "sv-single-select-list";

private resetItemsSettings() {
this.itemsSettings.startIndex = 0;
this.itemsSettings.pageSize = pageSize;
this.itemsSettings.total = 0;
this.itemsSettings.skip = 0;
this.itemsSettings.take = this.question.choicesLazyLoadPageSize;
this.itemsSettings.totalCount = 0;
this.itemsSettings.items = [];
}

private updateListItems() {
this._popupModel.contentComponentData.model.setItems(this.getAvailableItems());
}
private setItems(loaded: boolean, items: Array<any>, total: number) {
if(loaded) {
this.itemsSettings.items = [].concat(this.itemsSettings.items, items);
this.question.choices = this.itemsSettings.items;
this.itemsSettings.total = total;
this.updateListItems();
}
private setItems(items: Array<any>, totalCount: number) {
this.itemsSettings.items = [].concat(this.itemsSettings.items, items);
this.question.choices = this.itemsSettings.items;
this.itemsSettings.totalCount = totalCount;
this.updateListItems();
}

private updateQuestionData(): void {
const isUpdate = (this.itemsSettings.startIndex + 1) < this.itemsSettings.total;
if(!this.itemsSettings.startIndex || isUpdate) {
this.question.survey.getQuestionData({
private updateQuestionChoices(): void {
const isUpdate = (this.itemsSettings.skip + 1) < this.itemsSettings.totalCount;
if(!this.itemsSettings.skip || isUpdate) {
this.question.survey.loadQuestionChoices({
question: this.question,
filterString: this.filterString,
startIndex: this.itemsSettings.startIndex,
pageSize: this.itemsSettings.pageSize,
setItems: (loaded: boolean, items: Array<any>, total: number) => {
this.setItems(loaded, items, total);
filter: this.filterString,
skip: this.itemsSettings.skip,
take: this.itemsSettings.take,
setItems: (items: Array<any>, totalCount: number) => {
this.setItems(items, totalCount);
}
});
this.itemsSettings.startIndex += this.itemsSettings.pageSize;
this.itemsSettings.skip += this.itemsSettings.take;
}
}

Expand All @@ -66,9 +62,9 @@ export class DropdownListModel extends Base {
});
this._popupModel.cssClass = this.popupCssClasses;
this._popupModel.onVisibilityChanged.add((_, option: { isVisible: boolean }) => {
if(option.isVisible && this.question.lazyLoading) {
if(option.isVisible && this.question.choicesLazyLoadEnabled) {
this.listModel.actions = [];
this.updateQuestionData();
this.updateQuestionChoices();
}

if (option.isVisible && !!this.question.onOpenedCallBack) {
Expand All @@ -78,7 +74,7 @@ export class DropdownListModel extends Base {
if(!option.isVisible) {
this.onHidePopup();

if(this.question.lazyLoading) {
if(this.question.choicesLazyLoadEnabled) {
this.resetItemsSettings();
}
}
Expand Down Expand Up @@ -167,6 +163,7 @@ export class DropdownListModel extends Base {
this.listModel.cssClasses = question.survey?.getCss().list;
this.setSearchEnabled(this.question.searchEnabled);
this.createPopup();
this.resetItemsSettings();
}

get popupModel(): PopupModel {
Expand Down Expand Up @@ -246,7 +243,7 @@ export class DropdownListModel extends Base {
onScroll(event: Event): void {
const target = event.target as HTMLElement;
if(target.scrollTop + target.offsetHeight === target.scrollHeight) {
this.updateQuestionData();
this.updateQuestionChoices();
}
}
onBlur(event: any): void {
Expand Down
9 changes: 4 additions & 5 deletions src/question_dropdown.ts
Expand Up @@ -15,8 +15,6 @@ import { settings } from "./settings";
* [View Demo](https://surveyjs.io/form-library/examples/questiontype-dropdown/ (linkStyle))
*/
export class QuestionDropdownModel extends QuestionSelectBase {
public lazyLoadingValue = false;

dropdownListModel: DropdownListModel;

updateReadOnlyText(): void {
Expand Down Expand Up @@ -197,6 +195,8 @@ export class QuestionDropdownModel extends QuestionSelectBase {

@property({ defaultValue: false }) inputHasValue: boolean;
@property({ defaultValue: "" }) readOnlyText: string;
@property({ defaultValue: false }) choicesLazyLoadEnabled: boolean;
@property({ defaultValue: 25 }) choicesLazyLoadPageSize: number;

public getControlClass(): string {
return new CssClassBuilder()
Expand Down Expand Up @@ -230,9 +230,6 @@ export class QuestionDropdownModel extends QuestionSelectBase {
}
return this.dropdownListModel?.popupModel;
}
public get lazyLoading(): boolean {
return this.lazyLoadingValue;
}

public onOpened: EventBase<QuestionDropdownModel> = this.addEvent<QuestionDropdownModel>();
public onOpenedCallBack(): void {
Expand Down Expand Up @@ -278,6 +275,8 @@ Serializer.addClass(
{ name: "autoComplete", choices: settings.questions.dataList, },
{ name: "renderAs", default: "default", visible: false },
{ name: "searchEnabled:boolean", default: true, visible: false },
{ name: "choicesLazyLoadEnabled:boolean", default: false, visible: false },
{ name: "choicesLazyLoadPageSize:number", default: 25, visible: false },
{ name: "inputFieldComponent", visible: false },
{ name: "itemComponent", visible: false, default: "" }
],
Expand Down
4 changes: 4 additions & 0 deletions src/question_tagbox.ts
Expand Up @@ -62,6 +62,8 @@ export class QuestionTagboxModel extends QuestionCheckboxModel {
}
})
hideSelectedItems: boolean;
@property({ defaultValue: false }) choicesLazyLoadEnabled: boolean;
@property({ defaultValue: 25 }) choicesLazyLoadPageSize: number;

/**
* A text displayed in the input field when it doesn't have a value.
Expand Down Expand Up @@ -128,6 +130,8 @@ Serializer.addClass(
{ name: "placeholder", serializationProperty: "locPlaceholder" },
{ name: "allowClear:boolean", default: true },
{ name: "searchEnabled:boolean", default: true },
{ name: "choicesLazyLoadEnabled:boolean", default: false, visible: false },
{ name: "choicesLazyLoadPageSize:number", default: 25, visible: false },
{ name: "hideSelectedItems:boolean", default: false },
{ name: "closeOnSelect:boolean", default: true, visible: false },
{ name: "itemComponent", visible: false, default: "" }
Expand Down
6 changes: 3 additions & 3 deletions src/survey.ts
Expand Up @@ -673,7 +673,7 @@ export class SurveyModel extends SurveyElementCore
SurveyModel
>();

public onGetQuestionData: EventBase<SurveyModel> = this.addEvent<SurveyModel>();
public onChoicesLazyLoad: EventBase<SurveyModel> = this.addEvent<SurveyModel>();

/**
* The event is fired on adding a new row in Matrix Dynamic question.
Expand Down Expand Up @@ -4339,8 +4339,8 @@ export class SurveyModel extends SurveyElementCore
this.onShowingChoiceItem.fire(this, options);
return options.visible;
}
getQuestionData(options: { question: IQuestion, filterString: string, startIndex: number, pageSize: number, setItems: (loaded: boolean, items: Array<any>, total: number) => void }): void {
this.onGetQuestionData.fire(this, options);
loadQuestionChoices(options: { question: IQuestion, filter: string, skip: number, take: number, setItems: (items: Array<any>, totalCount: number) => void }): void {
this.onChoicesLazyLoad.fire(this, options);
}
matrixBeforeRowAdded(options: any) {
this.onMatrixBeforeRowAdded.fire(this, options);
Expand Down
73 changes: 35 additions & 38 deletions tests/questionDropdownTests.ts
Expand Up @@ -472,50 +472,47 @@ QUnit.test("hasScroll property", assert => {
document.body.removeChild(element);
});

function getNumberArray(startIndex = 1, count = 25): Array<number> {
function getNumberArray(skip = 1, count = 25): Array<number> {
const result:Array<number> = [];
for(let index = startIndex; index < (startIndex + count); index++) {
for(let index = skip; index < (skip + count); index++) {
result.push(index);
}
return result;
}

const callback = (_, opt) => {
if(opt.question.getType() === "dropdown") {
const total = 55;
setTimeout(() => {
if(opt.startIndex === 0) {
opt.setItems(true, getNumberArray(), total);
} else if(opt.startIndex === 25) {
opt.setItems(true, getNumberArray(26, 25), total);
} else {
opt.setItems(true, getNumberArray(51, 5), total);
}
}, 500);
}
const total = 55;
setTimeout(() => {
if(opt.skip + opt.take < total) {
opt.setItems(getNumberArray(opt.skip + 1, opt.take), total);
} else {
opt.setItems(getNumberArray(opt.skip + 1, total - opt.skip), total);
}
}, 500);
};

QUnit.test("lazy loading: first loading", assert => {
const done = assert.async();
const json = {
questions: [{
"type": "dropdown",
"name": "q1"
"name": "q1",
"choicesLazyLoadEnabled": true,
"choicesLazyLoadPageSize": 30,
}]
};
const survey = new SurveyModel(json);
survey.onGetQuestionData.add(callback);
survey.onChoicesLazyLoad.add(callback);

const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
question.lazyLoadingValue = true;
assert.equal(question.lazyLoading, true);
assert.equal(question.choicesLazyLoadEnabled, true);
assert.equal(question.choices.length, 0);

question.dropdownListModel.popupModel.isVisible = true;
setTimeout(() => {
assert.equal(question.choices.length, 25);
assert.equal(question.choices.length, 30);
assert.equal(question.choices[0].value, 1);
assert.equal(question.choices[24].value, 25);
assert.equal(question.choices[29].value, 30);
done();
}, 550);
});
Expand All @@ -527,15 +524,15 @@ QUnit.test("lazy loading: several loading", assert => {
const json = {
questions: [{
"type": "dropdown",
"name": "q1"
"name": "q1",
"choicesLazyLoadEnabled": true
}]
};
const survey = new SurveyModel(json);
survey.onGetQuestionData.add(callback);
survey.onChoicesLazyLoad.add(callback);

const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
question.lazyLoadingValue = true;
assert.equal(question.lazyLoading, true);
assert.equal(question.choicesLazyLoadEnabled, true);
assert.equal(question.choices.length, 0);

question.dropdownListModel.popupModel.toggleVisibility();
Expand All @@ -544,13 +541,13 @@ QUnit.test("lazy loading: several loading", assert => {
assert.equal(question.choices[0].value, 1);
assert.equal(question.choices[24].value, 25);

question.dropdownListModel["updateQuestionData"]();
question.dropdownListModel["updateQuestionChoices"]();
setTimeout(() => {
assert.equal(question.choices.length, 50);
assert.equal(question.choices[0].value, 1);
assert.equal(question.choices[49].value, 50);

question.dropdownListModel["updateQuestionData"]();
question.dropdownListModel["updateQuestionChoices"]();
setTimeout(() => {
assert.equal(question.choices.length, 55);
assert.equal(question.choices[0].value, 1);
Expand All @@ -572,38 +569,38 @@ QUnit.test("itemsSettings property", assert => {
const json = {
questions: [{
"type": "dropdown",
"name": "q1"
"name": "q1",
"choicesLazyLoadEnabled": true
}]
};
const survey = new SurveyModel(json);
survey.onGetQuestionData.add(callback);
survey.onChoicesLazyLoad.add(callback);

const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
question.lazyLoadingValue = true;
const listModel = question.popupModel.contentComponentData.model as ListModel;
const itemsSettings = question.dropdownListModel["itemsSettings"];
assert.equal(itemsSettings.startIndex, 0);
assert.equal(itemsSettings.pageSize, 25);
assert.equal(itemsSettings.total, 0);
assert.equal(itemsSettings.skip, 0);
assert.equal(itemsSettings.take, 25);
assert.equal(itemsSettings.totalCount, 0);
assert.equal(itemsSettings.items.length, 0);
assert.equal(listModel.actions.length, 0);

question.dropdownListModel.popupModel.isVisible = true;

setTimeout(() => {
assert.equal(listModel.actions.length, 25);
assert.equal(itemsSettings.startIndex, 25);
assert.equal(itemsSettings.pageSize, 25);
assert.equal(itemsSettings.total, 55);
assert.equal(itemsSettings.skip, 25);
assert.equal(itemsSettings.take, 25);
assert.equal(itemsSettings.totalCount, 55);
assert.equal(itemsSettings.items.length, 25);

question.dropdownListModel.popupModel.isVisible = false;

setTimeout(() => {
assert.equal(listModel.actions.length, 25);
assert.equal(itemsSettings.startIndex, 0);
assert.equal(itemsSettings.pageSize, 25);
assert.equal(itemsSettings.total, 0);
assert.equal(itemsSettings.skip, 0);
assert.equal(itemsSettings.take, 25);
assert.equal(itemsSettings.totalCount, 0);
assert.equal(itemsSettings.items.length, 0);

question.dropdownListModel.popupModel.isVisible = true;
Expand Down

0 comments on commit 7386f4d

Please sign in to comment.