Skip to content

Commit

Permalink
Work for surveyjs/survey-pdf#251: fix isReadyFlag behaviour for onGet…
Browse files Browse the repository at this point in the history
…ChoiceDisplayValue event
  • Loading branch information
dk981234 committed Jun 26, 2023
1 parent daf31ea commit 72af37e
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 27 deletions.
11 changes: 11 additions & 0 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ export class Question extends SurveyElement<Question>
this.valueName ? this.valueName : oldValue
);
}
public set isReady(val: boolean) {
const oldIsReady = this.isReadyValue;
this.isReadyValue = val;
if(oldIsReady != val) {
this.onReadyChanged.fire(this, {
question: this,
isReady: val,
oldIsReady: oldIsReady,
});
}
}
public get isReady(): boolean {
return this.isReadyValue;
}
Expand Down
25 changes: 14 additions & 11 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ export class QuestionSelectBase extends Question {
private newItemValue: ItemValue;
private canShowOptionItemCallback: (item: ItemValue) => boolean;
private waitingGetChoiceDisplayValueResponse: boolean;
private get waitingChoicesByURL(): boolean {
return !this.isChoicesLoaded && !this.choicesByUrl.isEmpty;
}
private get waitingAcyncOperations(): boolean {
return this.waitingChoicesByURL || this.waitingGetChoiceDisplayValueResponse;
}
@property({ onSet: (newVal: any, target: QuestionSelectBase) => {
target.onSelectedItemValuesChangedHandler(newVal);
} }) protected selectedItemValues: any;
Expand Down Expand Up @@ -208,7 +214,7 @@ export class QuestionSelectBase extends Question {
return this.getLocalizableString("noneText");
}
/**
* A Boolean expression that is evaluated against each choice item. If the expression evaluates to `false`, the choice item becomes hidden.
* A Boolean expression that is evaluated against each choice fitem. If the expression evaluates to `false`, the choice item becomes hidden.
*
* A survey parses and runs all expressions on startup. If any values used in the expression change, the survey re-evaluates it.
*
Expand Down Expand Up @@ -333,7 +339,7 @@ export class QuestionSelectBase extends Question {
this.survey?.loadedChoicesFromServer(this);
}
protected getItemIfChoicesNotContainThisValue(value: any, text?: string): any {
if(!this.isReady) {
if(this.waitingChoicesByURL) {
return this.createItemValue(value, text);
} else {
return null;
Expand Down Expand Up @@ -573,13 +579,15 @@ export class QuestionSelectBase extends Question {
protected updateSingleSelectedItemValues(): void {
if (!!this.survey && !this.isEmpty() && !ItemValue.getItemByValue(this.choices, this.value)) {
this.waitingGetChoiceDisplayValueResponse = true;
this.isReady = !this.waitingAcyncOperations;
this.survey.getChoiceDisplayValue({
question: this,
values: [this.value],
setItems: (displayValues: Array<string>) => {
this.waitingGetChoiceDisplayValueResponse = false;
if (!displayValues || !displayValues.length) return;
this.selectedItemValues = this.createItemValue(this.value, displayValues[0]);
this.isReady = !this.waitingAcyncOperations;
}
});
}
Expand All @@ -590,13 +598,15 @@ export class QuestionSelectBase extends Question {

if (!!this.survey && !this.isEmpty() && hasItemWithValues) {
this.waitingGetChoiceDisplayValueResponse = true;
this.isReady = this.waitingAcyncOperations;
this.survey.getChoiceDisplayValue({
question: this,
values: valueArray,
setItems: (displayValues: Array<string>) => {
this.waitingGetChoiceDisplayValueResponse = false;
if (!displayValues || !displayValues.length) return;
this.selectedItemValues = displayValues.map((displayValue, index) => this.createItemValue(this.value[index], displayValue));
this.isReady = !this.waitingAcyncOperations;
}
});
}
Expand Down Expand Up @@ -1189,7 +1199,7 @@ export class QuestionSelectBase extends Question {
: this.textProcessor;
if (!processor) processor = this.survey;
if (!processor) return;
this.isReadyValue = this.isChoicesLoaded || this.choicesByUrl.isEmpty;
this.isReadyValue = !this.waitingAcyncOperations;
this.isRunningChoices = true;
this.choicesByUrl.run(processor);
this.isRunningChoices = false;
Expand Down Expand Up @@ -1561,14 +1571,7 @@ export class QuestionSelectBase extends Question {

public choicesLoaded(): void {
this.isChoicesLoaded = true;
let oldIsReady: boolean = this.isReadyValue;
this.isReadyValue = true;
this.onReadyChanged &&
this.onReadyChanged.fire(this, {
question: this,
isReady: true,
oldIsReady: oldIsReady,
});
this.isReady = !this.waitingAcyncOperations;
if (this.survey) {
this.survey.loadedChoicesFromServer(this);
}
Expand Down
8 changes: 1 addition & 7 deletions src/question_file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,13 +369,7 @@ export class QuestionFileModel extends Question {
this.previewValue.push(val);
});
}
this.isReadyValue = true;
this.onReadyChanged &&
this.onReadyChanged.fire(this, {
question: this,
isReady: true,
oldIsReady: false,
});
this.isReady = true;
this._previewLoader.dispose();
this._previewLoader = undefined;
});
Expand Down
10 changes: 1 addition & 9 deletions src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1834,7 +1834,6 @@ export class QuestionPanelDynamicModel extends Question
this.recalculateIsReadyValue();
};
recalculateIsReadyValue(): void {
let oldIsReady = this.isReadyValue;
let isReady: boolean = true;
this.panels.forEach(panel => {
panel.questions.forEach(q => {
Expand All @@ -1846,14 +1845,7 @@ export class QuestionPanelDynamicModel extends Question
}
});
});
this.isReadyValue = isReady;
if(oldIsReady != this.isReadyValue) {
this.onReadyChanged.fire(this, {
question: this,
oldIsReady: oldIsReady,
isReady: this.isReadyValue
});
}
this.isReady = isReady;
}
protected onSetData() {
super.onSetData();
Expand Down
81 changes: 81 additions & 0 deletions tests/questionDropdownTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1538,4 +1538,85 @@ QUnit.test("lazy loading placeholder", assert => {

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

QUnit.test("isReady flag + onGetChoiceDisplayValue", assert => {
const done = assert.async();

const json = {
questions: [{
"type": "dropdown",
"name": "q1",
"choicesLazyLoadEnabled": true,
}]
};
const survey = new SurveyModel(json);
const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
let log = "";
survey.onGetChoiceDisplayValue.add((_, opt) => {
setTimeout(() => {
log += "->onGetChoiceDisplayValue";
opt.setItems(["Ford"]);
}, 1);
});
question.onReadyChanged.add((_, opt) => {
log += `->onReadyChanged: ${opt.isReady}`;
if(opt.isReady) {
assert.ok(question.isReady);
assert.notOk(question["waitingAcyncOperations"]);
assert.notOk(question["waitingChoicesByURL"]);
assert.notOk(question["waitingGetChoiceDisplayValueResponse"]);
assert.equal(log, "->onReadyChanged: false->onGetChoiceDisplayValue->onReadyChanged: true");
assert.equal(question.displayValue, "Ford");
done();
}
});
survey.data = { "q1": "ford" };
assert.notOk(question.isReady);
assert.ok(question["waitingAcyncOperations"]);
assert.notOk(question["waitingChoicesByURL"]);
assert.ok(question["waitingGetChoiceDisplayValueResponse"]);
});

QUnit.test("isReady flag + onGetChoiceDisplayValue + choicesRestfull", assert => {
const done = assert.async();

const json = {
questions: [{
"type": "dropdown",
"name": "q1",
"choicesLazyLoadEnabled": true,
}]
};
const survey = new SurveyModel(json);
const question = <QuestionDropdownModel>survey.getAllQuestions()[0];
let log = "";
survey.onGetChoiceDisplayValue.add((_, opt) => {
setTimeout(() => {
log += "->onGetChoiceDisplayValue";
opt.setItems(["Ford"]);
}, 1);
});
question.onReadyChanged.add((_, opt) => {
log += `->onReadyChanged: ${opt.isReady}`;
if(opt.isReady) {
assert.ok(question.isReady);
assert.notOk(question["waitingAcyncOperations"]);
assert.notOk(question["waitingChoicesByURL"]);
assert.notOk(question["waitingGetChoiceDisplayValueResponse"]);
assert.equal(log, "->onReadyChanged: false->onGetChoiceDisplayValue->onReadyChanged: true");
done();
}
});
question.choicesByUrl.url = "some url";
survey.data = { "q1": "ford" };
assert.notOk(question.isReady);
assert.ok(question["waitingAcyncOperations"]);
assert.ok(question["waitingChoicesByURL"]);
assert.ok(question["waitingGetChoiceDisplayValueResponse"]);
question.choicesLoaded();
assert.notOk(question.isReady);
assert.ok(question["waitingAcyncOperations"]);
assert.notOk(question["waitingChoicesByURL"]);
assert.ok(question["waitingGetChoiceDisplayValueResponse"]);
});

0 comments on commit 72af37e

Please sign in to comment.