diff --git a/src/base.ts b/src/base.ts index 7092b4884c..d752f8cac3 100644 --- a/src/base.ts +++ b/src/base.ts @@ -675,27 +675,21 @@ export class Base { arrayChanges?: ArrayChanges, target?: Base ) { - if (this.isInternal) return; + const fireCallback = (obj: Base): void => { + if (!!obj && !!obj.onPropertyValueChangedCallback) { + obj.onPropertyValueChangedCallback(name, oldValue, newValue, target, arrayChanges); + } + }; + if (this.isInternal) { + fireCallback(this); + return; + } if (!target) target = this; var notifier: any = this.getSurvey(); if (!notifier) notifier = this; - if (!!notifier.onPropertyValueChangedCallback) { - notifier.onPropertyValueChangedCallback( - name, - oldValue, - newValue, - target, - arrayChanges - ); - } - if (notifier !== this && !!this.onPropertyValueChangedCallback) { - this.onPropertyValueChangedCallback( - name, - oldValue, - newValue, - target, - arrayChanges - ); + fireCallback(notifier); + if (notifier !== this) { + fireCallback(this); } } public addExpressionProperty(name: string, onExecute: (obj: Base, res: any) => void, canRun?: (obj: Base) => boolean): void { diff --git a/src/question_custom.ts b/src/question_custom.ts index d775c67b80..8cac5ccb19 100644 --- a/src/question_custom.ts +++ b/src/question_custom.ts @@ -1,6 +1,6 @@ import { Question, IConditionObject } from "./question"; import { Serializer, CustomPropertiesCollection, JsonObjectProperty } from "./jsonobject"; -import { Base } from "./base"; +import { Base, ArrayChanges } from "./base"; import { ISurveyImpl, ISurveyData, @@ -345,9 +345,8 @@ export class ComponentQuestionJSON { } public getDynamicProperties(): Array { if(!Array.isArray(this.dynamicProperties)) { - + this.dynamicProperties = this.calcDynamicProperties(); } - this.dynamicProperties = this.calcDynamicProperties(); return this.dynamicProperties; } private calcDynamicProperties(): Array { @@ -733,6 +732,21 @@ export class QuestionCustomModel extends QuestionCustomModelBase { protected createWrapper(): void { this.questionWrapper = this.createQuestion(); this.createDynamicProperties(this.questionWrapper); + if(this.getDynamicProperties().length > 0) { + this.questionWrapper.onPropertyValueChangedCallback = (name: string, oldValue: any, newValue: any, sender: Base, arrayChanges: ArrayChanges): void => { + const prop = this.getDynamicProperty(name); + if(prop) { + this.propertyValueChanged(name, oldValue, newValue, arrayChanges); + } + }; + } + } + private getDynamicProperty(name: string): JsonObjectProperty { + const props = this.getDynamicProperties(); + for(let i = 0; i < props.length; i ++) { + if(props[i].name === name) return props[i]; + } + return null; } protected getElement(): SurveyElement { return this.contentQuestion; @@ -1110,7 +1124,9 @@ export class QuestionCompositeModel extends QuestionCustomModelBase { getFilteredValues(): any { const values = !!this.data ? this.data.getFilteredValues() : {}; if (!!this.contentPanel) { - values[QuestionCompositeModel.ItemVariableName] = this.contentPanel.getValue(); + values[ + QuestionCompositeModel.ItemVariableName + ] = this.contentPanel.getValue(); } return values; } diff --git a/tests/question_customtests.ts b/tests/question_customtests.ts index 39447e9b4e..499e639b03 100644 --- a/tests/question_customtests.ts +++ b/tests/question_customtests.ts @@ -15,6 +15,7 @@ import { ItemValue } from "../src/itemvalue"; import { LocalizableString } from "../src/localizablestring"; import { PanelModel } from "../src/panel"; import { StylesManager } from "../src/stylesmanager"; +import { ArrayChanges, Base } from "../src/base"; export default QUnit.module("custom questions"); @@ -2770,7 +2771,7 @@ QUnit.test("single component: inheritBaseProps: array", function (assert ComponentCollection.Instance.clear(); }); -QUnit.test("single component: inheritBaseProps: array #2", function (assert) { +QUnit.test("single component: inheritBaseProps: array #2 + check property change notification #", function (assert) { ComponentCollection.Instance.add({ name: "customtext", inheritBaseProps: ["placeholder"], @@ -2785,11 +2786,19 @@ QUnit.test("single component: inheritBaseProps: array #2", function (ass { type: "customtext", name: "q1" } ] }); + let propertyName = ""; + let counter = 0; const q1 = survey.getQuestionByName("q1"); const content = q1.contentQuestion; assert.equal(q1.placeholder, "abc", "q1.placeholder #1"); assert.equal(content.placeholder, "abc", "content.placeholder #1"); + survey.onPropertyValueChangedCallback = (name: string, oldValue: any, newValue: any, sender: Base, arrayChanges: ArrayChanges): void => { + propertyName = name; + counter ++; + }; q1.placeholder = "bcd"; + assert.equal(propertyName, "placeholder", "send notification, propertyname"); + assert.equal(counter, 1, "send notification, counter"); assert.equal(q1.placeholder, "bcd", "q1.placeholder #2"); assert.equal(content.placeholder, "bcd", "content.placeholder #2"); content.placeholder = "cde";