Skip to content

Commit

Permalink
resetValueIf doesn't work correctly if there is a cycle of using it fix
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewtelnov authored Sep 28, 2023
1 parent 0d445a9 commit ea11163
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
5 changes: 4 additions & 1 deletion src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ export class Question extends SurveyElement<Question>
private resetValueIfExpression: ExpressionRunner;
private isRunningResetValueIf: boolean;
public runTriggers(name: string, value: any): void {
if(this.isRunningResetValueIf || !this.isVisible || this.isReadOnly || !this.resetValueIf || this.isEmpty()) return;
if(this.isRunningResetValueIf || !this.isVisible || this.isReadOnly || !this.resetValueIf || this.isEmpty() || this.isSettingQuestionValue) return;
if(this.parentQuestion && this.parentQuestion.getValueName() === name) return;
if(!this.resetValueIfExpression) {
this.resetValueIfExpression = new ExpressionRunner(this.resetValueIf);
Expand Down Expand Up @@ -2083,13 +2083,16 @@ export class Question extends SurveyElement<Question>
public allowSpaceAsAnswer: boolean;
private isValueChangedInSurvey = false;
private isOldAnswered: boolean;
private isSettingQuestionValue: boolean;
protected allowNotifyValueChanged = true;
protected setNewValue(newValue: any): void {
if (this.isNewValueEqualsToValue(newValue)) return;
if (!this.checkIsValueCorrect(newValue)) return;
this.isOldAnswered = this.isAnswered;
this.isSettingQuestionValue = true;
this.setNewValueInData(newValue);
this.allowNotifyValueChanged && this.onValueChanged();
this.isSettingQuestionValue = false;
if (this.isAnswered !== this.isOldAnswered) {
this.updateQuestionCss();
}
Expand Down
46 changes: 46 additions & 0 deletions tests/question_matrixdropdownbasetests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,52 @@ QUnit.test("question.resetValueIf based on root and row questions", function (as
q1.value = 1;
assert.equal(q2.isEmpty(), true, "q2.value #5");
});
QUnit.test("question.resetValueIf, cycle calls", function (assert) {
const survey = new SurveyModel({
elements: [
{
"type": "matrixdynamic",
"name": "matrix",
"rowCount": 1,
"columns": [
{
"name": "dog",
"cellType": "checkbox",
"resetValueIf": "{row.none} notempty",
"choices": ["dog"]
},
{
"name": "cat",
"cellType": "checkbox",
"resetValueIf": "{row.none} notempty",
"choices": ["cat"]
},
{
"name": "none",
"cellType": "checkbox",
"resetValueIf": "{row.dog} notempty or {row.cat} notempty",
"choices": ["none"]
}]
}
] });
const row = survey.getQuestionByName("matrix").visibleRows[0];
const q1 = row.getQuestionByName("dog");
const q2 = row.getQuestionByName("cat");
const q3 = row.getQuestionByName("none");
q1.value = ["dog"];
q2.value = ["cat"];
assert.deepEqual(q1.value, ["dog"], "q1.value #1");
assert.deepEqual(q2.value, ["cat"], "q2.value #1");
assert.equal(q3.isEmpty(), true, "q3.value #1");
q3.value = ["none"];
assert.equal(q1.isEmpty(), true, "q1.value #2");
assert.equal(q2.isEmpty(), true, "q2.value #2");
assert.deepEqual(q3.value, ["none"], "q3.value #2");
q1.value = ["dog"];
assert.deepEqual(q1.value, ["dog"], "q1.value #3");
assert.equal(q3.isEmpty(), true, "q2.value #3");
assert.equal(q3.isEmpty(), true, "q3.value #3");
});
QUnit.test("question.onHidingContent", function (assert) {
const survey = new SurveyModel({
questionErrorLocation: "bottom",
Expand Down
37 changes: 37 additions & 0 deletions tests/surveyquestiontests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7288,6 +7288,43 @@ QUnit.test("question.resetValueIf & quesiton.defaultValueExpression", function (
q3.value = 4;
assert.equal(q2.value, "edf", "value is set directly, #3");
});
QUnit.test("question.resetValueIf, cycle calls", function (assert) {
const survey = new SurveyModel({
elements: [{
"name": "dog",
"type": "checkbox",
"resetValueIf": "{none} notempty",
"choices": ["dog"]
},
{
"name": "cat",
"type": "checkbox",
"resetValueIf": "{none} notempty",
"choices": ["cat"]
},
{
"name": "none",
"type": "checkbox",
"resetValueIf": "{dog} notempty or {cat} notempty",
"choices": ["none"]
}] });
const q1 = survey.getQuestionByName("dog");
const q2 = survey.getQuestionByName("cat");
const q3 = survey.getQuestionByName("none");
q1.value = ["dog"];
q2.value = ["cat"];
assert.deepEqual(q1.value, ["dog"], "q1.value #1");
assert.deepEqual(q2.value, ["cat"], "q2.value #1");
assert.equal(q3.isEmpty(), true, "q3.value #1");
q3.value = ["none"];
assert.equal(q1.isEmpty(), true, "q1.value #2");
assert.equal(q2.isEmpty(), true, "q2.value #2");
assert.deepEqual(q3.value, ["none"], "q3.value #2");
q1.value = ["dog"];
assert.deepEqual(q1.value, ["dog"], "q1.value #3");
assert.equal(q3.isEmpty(), true, "q2.value #3");
assert.equal(q3.isEmpty(), true, "q3.value #3");
});
QUnit.test("question.isReady & async functions in expression", function (assert) {
var returnResult1: (res: any) => void;
var returnResult2: (res: any) => void;
Expand Down

0 comments on commit ea11163

Please sign in to comment.