From c870836e3ba8ce5fdb85fd74d116eed5dbdbc99d Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 30 Oct 2023 18:17:27 +0200 Subject: [PATCH] Custom Component - A component's value is reset in preview when using the defaultValueExpression fix #4836 (#7258) --- src/question.ts | 14 +++++++++----- src/question_custom.ts | 17 ++++++++++++++--- src/question_matrixdropdownbase.ts | 2 +- tests/question_customtests.ts | 29 +++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/question.ts b/src/question.ts index 8cefaced43..de6be3c5af 100644 --- a/src/question.ts +++ b/src/question.ts @@ -83,6 +83,7 @@ export class Question extends SurveyElement valueFromDataCallback: (val: any) => any; valueToDataCallback: (val: any) => any; onUpdateCssClassesCallback: (css: any) => void; + setValueChangedDirectlyCallback: (val: boolean) => void; onGetSurvey: () => ISurvey; private locProcessedTitle: LocalizableString; private isReadyValue: boolean = true; @@ -1522,7 +1523,7 @@ export class Question extends SurveyElement if (!!this.comment) { this.comment = undefined; } - this.isValueChangedDirectly = false; + this.setValueChangedDirectly(false); } public unbindValue(): void { this.clearValue(); @@ -1570,7 +1571,7 @@ export class Question extends SurveyElement protected clearValueIfInvisibleCore(reason: string): void { if (this.canClearValueAsInvisible(reason)) { this.clearValue(); - this.isValueChangedDirectly = undefined; + this.setValueChangedDirectly(undefined); } } /** @@ -2288,14 +2289,17 @@ export class Question extends SurveyElement this.questionComment = newValue; } protected onChangeQuestionValue(newValue: any): void { } - protected setValueChangedDirectly(): void { - this.isValueChangedDirectly = true; + protected setValueChangedDirectly(val: boolean): void { + this.isValueChangedDirectly = val; + if(!!this.setValueChangedDirectlyCallback) { + this.setValueChangedDirectlyCallback(val); + } } protected setQuestionValue(newValue: any, updateIsAnswered: boolean = true): void { newValue = this.convertToCorrectValue(newValue); const isEqual = this.isTwoValueEquals(this.questionValue, newValue); if (!isEqual && !this.isChangingViaDefaultValue) { - this.setValueChangedDirectly(); + this.setValueChangedDirectly(true); } this.questionValue = newValue; if (!isEqual) { diff --git a/src/question_custom.ts b/src/question_custom.ts index f564cb2dc3..20318e7d57 100644 --- a/src/question_custom.ts +++ b/src/question_custom.ts @@ -690,6 +690,7 @@ export class QuestionCustomModel extends QuestionCustomModelBase { this.onUpdateQuestionCssClasses(res, css); }; res.hasCssErrorCallback = (): boolean => this.errors.length > 0; + res.setValueChangedDirectlyCallback = (val: boolean): void => { this.setValueChangedDirectly(val); }; } return res; @@ -744,17 +745,27 @@ export class QuestionCustomModel extends QuestionCustomModelBase { this.setContentQuestionValue(this.getUnbindValue(newValue)); } } - onSurveyValueChanged(newValue: any) { + onSurveyValueChanged(newValue: any): void { super.onSurveyValueChanged(newValue); if (!!this.contentQuestion) { this.contentQuestion.onSurveyValueChanged(newValue); } } - protected getValueCore() { + protected getValueCore(): any { if (!!this.contentQuestion) return this.getContentQuestionValue(); return super.getValueCore(); } - protected initElement(el: SurveyElement) { + private isSettingValueChanged: boolean; + protected setValueChangedDirectly(val: boolean): void { + if(this.isSettingValueChanged) return; + this.isSettingValueChanged = true; + super.setValueChangedDirectly(val); + if(!!this.contentQuestion) { + (this.contentQuestion).setValueChangedDirectly(val); + } + this.isSettingValueChanged = false; + } + protected initElement(el: SurveyElement): void { super.initElement(el); if (!!el) { (el).parent = this; diff --git a/src/question_matrixdropdownbase.ts b/src/question_matrixdropdownbase.ts index aea6fa6428..6848753b25 100644 --- a/src/question_matrixdropdownbase.ts +++ b/src/question_matrixdropdownbase.ts @@ -1068,7 +1068,7 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModelsurvey.getAllQuestions()[0]; + assert.equal(q.value, 2, "defaultValue is set"); + assert.equal(q.contentQuestion.value, 2, "defaultValue is set for contentQuestion"); + q.contentQuestion.value = 3; + assert.equal(q.value, 3, "defaultValue is set, #2"); + assert.equal(q.contentQuestion.value, 3, "defaultValue is set for contentQuestion, #2"); + survey.setValue("q2", 4); + assert.equal(q.value, 3, "defaultValue is set, #3"); + assert.equal(q.contentQuestion.value, 3, "defaultValue is set for contentQuestion, #3"); + assert.deepEqual(survey.data, { q1: 3, q2: 4 }, "set data into survey"); + q.clearValue(); + survey.setValue("q2", 5); + assert.equal(q.value, 2, "defaultValue is set, #4"); + assert.equal(q.contentQuestion.value, 2, "defaultValue is set for contentQuestion, #4"); + assert.deepEqual(survey.data, { q1: 2, q2: 5 }, "set data into survey, #2"); + ComponentCollection.Instance.clear(); +}); QUnit.test("Single: matrixdropdown expressions", function (assert) { var json = { name: "order",