Skip to content

Commit

Permalink
Composite question: onValueChanged handler called multiple times if t…
Browse files Browse the repository at this point in the history
…here is a question is type of expression fix #6194 (#6221)
  • Loading branch information
andrewtelnov committed May 18, 2023
1 parent 28d66b4 commit 9f99fd3
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
29 changes: 18 additions & 11 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -793,10 +793,8 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
return this.textProcessing;
}
findQuestionByName(name: string): IQuestion {
if(!!this.contentPanel) {
const res = this.contentPanel.getQuestionByName(name);
if(!!res) return res;
}
const res = this.getQuestionByName(name);
if(!!res) return res;
return super.findQuestionByName(name);
}
protected clearValueIfInvisibleCore(): void {
Expand Down Expand Up @@ -902,15 +900,16 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
this.setValueCore(panelValue);
}
}
this.setNewValueIntoQuestion(name, newValue);
super.setValue(name, newValue, locNotification, allowNotifyValueChanged);
if (!!this.contentPanel) {
var q = this.contentPanel.getQuestionByName(name);
if (!!q && !this.isTwoValueEquals(newValue, q.value)) {
q.value = newValue;
}
}
this.settingNewValue = false;
}
private setNewValueIntoQuestion(name: string, newValue: any): void {
var q = this.getQuestionByName(name);
if (!!q && !this.isTwoValueEquals(newValue, q.value)) {
q.value = newValue;
}
}
public addConditionObjectsByContext(
objects: Array<IConditionObject>,
context: any
Expand All @@ -937,8 +936,15 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
}
return val;
}
protected setQuestionValue(newValue: any, updateIsAnswered: boolean = true) {
protected setQuestionValue(newValue: any, updateIsAnswered: boolean = true): void {
this.setValuesIntoQuestions(newValue);
if (!this.isEditingSurveyElement && !!this.contentPanel) {
newValue = this.contentPanel.getValue();
}
super.setQuestionValue(newValue, updateIsAnswered);
}
private setValuesIntoQuestions(newValue: any): void {
if(!this.contentPanel) return;
this.settingNewValue = true;
var questions = this.contentPanel.questions;
for (var i = 0; i < questions.length; i++) {
Expand All @@ -949,6 +955,7 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
q.value = val;
}
}
this.runCondition(this.getDataFilteredValues(), this.getDataFilteredProperties());
this.settingNewValue = false;
}
protected getDisplayValueCore(keyAsText: boolean, value: any): any {
Expand Down
52 changes: 52 additions & 0 deletions tests/question_customtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2095,3 +2095,55 @@ QUnit.test("Composite: Change css rules for content questions", function (assert
assert.equal(q.contentPanel.questions[1].cssClasses.root, "css_question2", "Set the css correctly, #2");
ComponentCollection.Instance.clear();
});
QUnit.test("Composite: with expression", function (assert) {
const json = {
name: "elementsettings",
elementsJSON: [
{
name: "corner",
type: "text",
inputType: "number",
defaultValue: 0
},
{
type: "expression",
name: "cornerRadius",
expression: "{composite.corner}+'px'",
visible: false
}
],
};
ComponentCollection.Instance.add(json);
const survey = new SurveyModel({ elements: [{ type: "elementsettings", name: "q1" }] });
let _data = {};
let onValueChangedCounter = 0;
survey.onValueChanged.add((sender, options) => {
onValueChangedCounter++;
_data = {};
if (options.question?.getType() === "elementsettings") {
Object.keys(options.value).forEach(key => {
if (key === "corner") return;
_data[`${options.name.toLocaleLowerCase()}-${key}`] = options.value[key];
});
}
});
const q = <QuestionCompositeModel>survey.getAllQuestions()[0];

assert.equal(_data["q1-corner"], undefined);
assert.equal(_data["q1-cornerRadius"], undefined);
assert.equal(onValueChangedCounter, 0);

q.value = { corner: 4 };
assert.equal(_data["q1-corner"], undefined);
assert.equal(_data["q1-cornerRadius"], "4px");
assert.deepEqual(q.value, { corner: 4, cornerRadius: "4px" });
assert.equal(onValueChangedCounter, 1);

q.contentPanel.getQuestionByName("corner").value = 5;
assert.deepEqual(q.value, { corner: 5, cornerRadius: "5px" });
assert.equal(_data["q1-corner"], undefined);
assert.equal(_data["q1-cornerRadius"], "5px");
assert.equal(onValueChangedCounter, 2);

ComponentCollection.Instance.clear();
});

0 comments on commit 9f99fd3

Please sign in to comment.