From b68c1520fb7b3707d8d73bc47190bee788bf3494 Mon Sep 17 00:00:00 2001 From: Andrew Telnov Date: Sat, 26 Aug 2023 13:56:22 +0300 Subject: [PATCH] Add this.panel into expression function context in panel dynamic question fix #6806 --- src/question_matrixdropdownbase.ts | 8 ++--- src/question_paneldynamic.ts | 14 ++++---- tests/entries/test.ts | 2 +- ...ests.ts => question_paneldynamic_tests.ts} | 33 ++++++++++++++++++- 4 files changed, 45 insertions(+), 12 deletions(-) rename tests/{surveypaneldynamictests.ts => question_paneldynamic_tests.ts} (99%) diff --git a/src/question_matrixdropdownbase.ts b/src/question_matrixdropdownbase.ts index 31d948da8a..3f5e4d87b3 100644 --- a/src/question_matrixdropdownbase.ts +++ b/src/question_matrixdropdownbase.ts @@ -358,14 +358,14 @@ implements ISurveyData, ISurveyImpl, ILocalizableOwner { } values[MatrixDropdownRowModelBase.IndexVariableName] = this.rowIndex; values[MatrixDropdownRowModelBase.RowValueVariableName] = this.rowName; - if (!properties) properties = {}; - properties[MatrixDropdownRowModelBase.RowVariableName] = this; + const newProps = Helpers.createCopy(properties); + newProps[MatrixDropdownRowModelBase.RowVariableName] = this; for (var i = 0; i < this.cells.length; i++) { values[MatrixDropdownRowModelBase.RowVariableName] = this.value; - this.cells[i].runCondition(values, properties); + this.cells[i].runCondition(values, newProps); } if (!!this.detailPanel) { - this.detailPanel.runCondition(values, properties); + this.detailPanel.runCondition(values, newProps); } } public clearValue() { diff --git a/src/question_paneldynamic.ts b/src/question_paneldynamic.ts index 007fd98952..b314aba6f7 100644 --- a/src/question_paneldynamic.ts +++ b/src/question_paneldynamic.ts @@ -1518,14 +1518,16 @@ export class QuestionPanelDynamicModel extends Question cachedValues[QuestionPanelDynamicItem.ParentItemVariableName] = (this.parent).getValue(); } for (var i = 0; i < this.panels.length; i++) { - var panelValues = this.getPanelItemData(this.panels[i].data); + const panel = this.panels[i]; + var panelValues = this.getPanelItemData(panel.data); //Should be unique for every panel due async expression support - var newValues = Helpers.createCopy(cachedValues); - newValues[ - QuestionPanelDynamicItem.ItemVariableName.toLowerCase() - ] = panelValues; + const newValues = Helpers.createCopy(cachedValues); + const panelName = QuestionPanelDynamicItem.ItemVariableName; + newValues[panelName] = panelValues; newValues[QuestionPanelDynamicItem.IndexVariableName.toLowerCase()] = i; - this.panels[i].runCondition(newValues, properties); + const newProps = Helpers.createCopy(properties); + newProps[panelName] = panel; + panel.runCondition(newValues, newProps); } } onAnyValueChanged(name: string) { diff --git a/tests/entries/test.ts b/tests/entries/test.ts index feb0fb5d64..1790a5ed90 100644 --- a/tests/entries/test.ts +++ b/tests/entries/test.ts @@ -14,7 +14,7 @@ export * from "../surveyLocalizationTests"; // export * from "../surveyquestiontests"; // export * from "../question_matrixdynamictests"; export * from "../question_matrixdropdownbasetests"; -export * from "../surveypaneldynamictests"; +export * from "../question_paneldynamic_tests"; export * from "../surveyserializationtests"; // export * from "../surveytests"; // export * from "../surveyWindowTests"; // diff --git a/tests/surveypaneldynamictests.ts b/tests/question_paneldynamic_tests.ts similarity index 99% rename from tests/surveypaneldynamictests.ts rename to tests/question_paneldynamic_tests.ts index 82895749bd..ad46eaa8c5 100644 --- a/tests/surveypaneldynamictests.ts +++ b/tests/question_paneldynamic_tests.ts @@ -6037,4 +6037,35 @@ QUnit.test("paneldynamic.removePanelUI & confirmActionAsync, #6736", function(as assert.deepEqual(panel.value, [{ q1: 1 }, { q1: 3 }], "Row is deleted correctly"); settings.confirmActionAsync = prevAsync; -}); \ No newline at end of file +}); +QUnit.test("panel property in custom function", function (assert) { + const panelCustomFunc = function (params: any) { + if(!this.panel) return ""; + const q = this.panel.getQuestionByName(params[0]); + if(q && !q.isEmpty()) return q.value + q.value; + return ""; + }; + FunctionFactory.Instance.register("panelCustomFunc", panelCustomFunc); + const survey = new SurveyModel({ + elements: [ + { + type: "paneldynamic", + name: "panel1", + templateElements: [ + { name: "q1", type: "text" }, + { + name: "q2", + type: "expression", + expression: "panelCustomFunc('q1')", + }, + ], + panelCount: 2, + }, + ], + }); + const question = survey.getQuestionByName("panel1"); + const panel = question.panels[0]; + panel.getQuestionByName("q1").value = "abc"; + assert.equal(panel.getQuestionByName("q2").value, "abcabc", "Custom function with row property works correctly"); + FunctionFactory.Instance.unregister("panelCustomFunc"); +});