Skip to content

Commit

Permalink
Refactor code to avoid code duplication for array value questions #6061
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov committed Aug 10, 2023
1 parent ca92209 commit 413b93b
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 25 deletions.
24 changes: 23 additions & 1 deletion src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export class Question extends SurveyElement<Question>
private locProcessedTitle: LocalizableString;
protected isReadyValue: boolean = true;
private commentElements: Array<HTMLElement>;
private dependedQuestions: Array<Question> = [];

/**
* An event that is raised when the question's ready state has changed (expressions are evaluated, choices are loaded from a web resource specified by the `choicesByUrl` property, etc.).
Expand Down Expand Up @@ -268,6 +269,24 @@ export class Question extends SurveyElement<Question>
this.removeSelfFromList(this.parent.elements);
}
}
protected addDependedQuestion(question: Question): void {
if (!question || this.dependedQuestions.indexOf(question) > -1) return;
this.dependedQuestions.push(question);
}
protected removeDependedQuestion(question: Question): void {
if (!question) return;
var index = this.dependedQuestions.indexOf(question);
if (index > -1) {
this.dependedQuestions.splice(index, 1);
}
}
protected updateDependedQuestions(): void {
for (var i = 0; i < this.dependedQuestions.length; i++) {
this.dependedQuestions[i].updateDependedQuestion();
}
}
protected updateDependedQuestion(): void {}
protected resetDependedQuestion(): void {}
public get isFlowLayout(): boolean {
return this.getLayoutType() === "flow";
}
Expand Down Expand Up @@ -2235,8 +2254,11 @@ export class Question extends SurveyElement<Question>
this.renderAs = this.getDesktopRenderAs();
}
}
public dispose() {
public dispose(): void {
super.dispose();
for (var i = 0; i < this.dependedQuestions.length; i++) {
this.dependedQuestions[i].resetDependedQuestion();
}
this.destroyResizeObserver();
}
}
Expand Down
42 changes: 18 additions & 24 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export class QuestionSelectBase extends Question {
private cachedValueForUrlRequests: any;
private isChoicesLoaded: boolean;
private enableOnLoadingChoices: boolean;
private dependedQuestions: Array<QuestionSelectBase> = [];
private noneItemValue: ItemValue = new ItemValue(settings.noneItemValue);
private newItemValue: ItemValue;
private canShowOptionItemCallback: (item: ItemValue) => boolean;
Expand Down Expand Up @@ -95,10 +94,13 @@ export class QuestionSelectBase extends Question {
}
public dispose(): void {
super.dispose();
for (var i = 0; i < this.dependedQuestions.length; i++) {
this.dependedQuestions[i].choicesFromQuestion = "";
const q = this.getQuestionWithChoices();
if(!!q) {
q.removeDependedQuestion(this);
}
this.removeFromDependedQuestion(this.getQuestionWithChoices());
}
protected resetDependedQuestion(): void {
this.choicesFromQuestion = "";
}
public get otherId(): string {
return this.id + "_other";
Expand Down Expand Up @@ -693,23 +695,12 @@ export class QuestionSelectBase extends Question {
var question = this.getQuestionWithChoices();
this.isLockVisibleChoices = !!question && question.name === val;
if (!!question && question.name !== val) {
question.removeFromDependedQuestion(this);
question.removeDependedQuestion(this);
}
this.setPropertyValue("choicesFromQuestion", val);
this.isLockVisibleChoices = false;
}
private isLockVisibleChoices: boolean;
private addIntoDependedQuestion(question: QuestionSelectBase) {
if (!question || question.dependedQuestions.indexOf(this) > -1) return;
question.dependedQuestions.push(this);
}
private removeFromDependedQuestion(question: QuestionSelectBase) {
if (!question) return;
var index = question.dependedQuestions.indexOf(this);
if (index > -1) {
question.dependedQuestions.splice(index, 1);
}
}
/**
* Specifies which choice items to inherit from another question. Applies only when the `choicesFromQuestion` property is specified.
*
Expand Down Expand Up @@ -1033,10 +1024,11 @@ export class QuestionSelectBase extends Question {
const arrayQuestion = !selBaseQuestion ? this.getQuestionWithArrayValue(question) : null;
this.setCarryForwardQuestionType(!!selBaseQuestion, !!arrayQuestion);
if (this.carryForwardQuestionType === "select") {
this.addIntoDependedQuestion(selBaseQuestion);
selBaseQuestion.addDependedQuestion(this);
return this.getChoicesFromSelectQuestion(selBaseQuestion);
}
if (this.carryForwardQuestionType === "array") {
(<any>arrayQuestion).addDependedQuestion(this);
return this.getChoicesFromArrayQuestion(arrayQuestion);
}
return this.choicesFromUrl ? this.choicesFromUrl : this.getChoices();
Expand All @@ -1049,7 +1041,9 @@ export class QuestionSelectBase extends Question {
return <Question>this.data.findQuestionByName(this.choicesFromQuestion);
}
private getQuestionWithChoicesCore(question: Question): QuestionSelectBase {
return !!question && !!question.visibleChoices && Array.isArray(question.dependedQuestions) && question !== this ? <QuestionSelectBase>question : null;
if(!!question && !!question.visibleChoices && (Serializer.isDescendantOf(question.getType(), "selectbase")) && question !== this)
return <QuestionSelectBase>question;
return null;
}
private getQuestionWithArrayValue(question: Question): Question {
return !!question && question.isValueArray ? question : null;
Expand Down Expand Up @@ -1389,13 +1383,13 @@ export class QuestionSelectBase extends Question {
if (this.isLoadingFromJson || this.isUpdatingChoicesDependedQuestions ||
!this.allowNotifyValueChanged || this.choicesByUrl.isRunning) return;
this.isUpdatingChoicesDependedQuestions = true;
for (var i = 0; i < this.dependedQuestions.length; i++) {
const q = this.dependedQuestions[i];
q.onVisibleChoicesChanged();
q.clearIncorrectValues();
}
this.updateDependedQuestions();
this.isUpdatingChoicesDependedQuestions = false;
}
protected updateDependedQuestion(): void {
this.onVisibleChoicesChanged();
this.clearIncorrectValues();
}
onSurveyValueChanged(newValue: any) {
super.onSurveyValueChanged(newValue);
this.updateChoicesDependedQuestions();
Expand Down Expand Up @@ -1788,7 +1782,7 @@ Serializer.addClass(
"selectbase",
[
{ name: "showCommentArea:switch", layout: "row", visible: true, category: "general" },
"choicesFromQuestion:question_selectbase",
"choicesFromQuestion:question_carryforward",
{
name: "choices:itemvalue[]", uniqueProperty: "value",
baseValue: function () {
Expand Down
15 changes: 15 additions & 0 deletions tests/question_baseselecttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1158,3 +1158,18 @@ QUnit.test("Use carryForward with panel dynamic + choicesFromValueName&choicesFr
assert.equal(q2.visibleChoices[2].value, "CC", "the third value is correct");
assert.equal(q2.visibleChoices[2].text, "CC-cc", "the third text is correct");
});
QUnit.test("Check isUsingCarryForward on deleting matrix dynamic question", function (assert) {
const survey = new SurveyModel();
survey.setDesignMode(true);
survey.fromJSON({ elements: [
{ type: "matrixdynamic", name: "q1" },
{ type: "dropdown", name: "q2", choicesFromQuestion: "q1" }
] });
const q1 = <QuestionSelectBase>survey.getQuestionByName("q1");
const q2 = <QuestionSelectBase>survey.getQuestionByName("q2");
assert.equal(q2.choicesFromQuestion, "q1", "set correctly");
assert.equal(q2.isUsingCarryForward, true, "Carryforward flag is set");
q1.delete();
assert.notOk(q2.choicesFromQuestion, "it is empty");
assert.equal(q2.isUsingCarryForward, false, "Carryforward flag is unset");
});

0 comments on commit 413b93b

Please sign in to comment.