Skip to content

Commit

Permalink
Copying choices from a Dynamic Panel doesn't work if two dynamic pane… (
Browse files Browse the repository at this point in the history
#6949)

* Copying choices from a Dynamic Panel doesn't work if two dynamic panels share data using the valueName fix #6948

* Add explicitErrorHandler into a functional test
  • Loading branch information
andrewtelnov authored Sep 13, 2023
1 parent c69286c commit d22676a
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 37 deletions.
5 changes: 3 additions & 2 deletions src/base-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export interface ISurveyData {
name: string,
newValue: any,
locNotification: any,
allowNotifyValueChanged?: boolean
allowNotifyValueChanged?: boolean,
questionName?: string
): any;
getVariable(name: string): any;
setVariable(name: string, newValue: any): void;
Expand Down Expand Up @@ -283,7 +284,7 @@ export interface IElement extends IConditionRunner, ISurveyElement {
getLayoutType(): string;
isLayoutTypeSupported(layoutType: string): boolean;
removeElement(el: IElement): boolean;
onAnyValueChanged(name: string): any;
onAnyValueChanged(name: string, questionName: string): void;
updateCustomWidgets(): any;
clearIncorrectValues(): any;
clearErrors(): any;
Expand Down
4 changes: 2 additions & 2 deletions src/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1427,10 +1427,10 @@ export class PanelModelBase extends SurveyElement<Question>
}
this.runConditionCore(values, properties);
}
onAnyValueChanged(name: string) {
onAnyValueChanged(name: string, questionName: string): void {
var els = this.elements;
for (var i = 0; i < els.length; i++) {
els[i].onAnyValueChanged(name);
els[i].onAnyValueChanged(name, questionName);
}
}
checkBindings(valueName: string, value: any) {
Expand Down
5 changes: 3 additions & 2 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2035,7 +2035,8 @@ export class Question extends SurveyElement<Question>
this.getValueName(),
newValue,
this.getDataLocNotification(),
this.allowNotifyValueChanged
this.allowNotifyValueChanged,
this.name
);
}
this.isMouseDown = false;
Expand Down Expand Up @@ -2140,7 +2141,7 @@ export class Question extends SurveyElement<Question>
this.errors = [];
}
public clearUnusedValues(): void { }
onAnyValueChanged(name: string): void { }
onAnyValueChanged(name: string, questionName: string): void { }
checkBindings(valueName: string, value: any): void {
if (this.bindings.isEmpty() || !this.data) return;
var props = this.bindings.getPropertiesByValueName(valueName);
Expand Down
7 changes: 4 additions & 3 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1191,12 +1191,13 @@ export class QuestionSelectBase extends Question {
this.onVisibleChoicesChanged();
super.onSurveyLoad();
}
onAnyValueChanged(name: string) {
super.onAnyValueChanged(name);
onAnyValueChanged(name: string, questionName: string): void {
super.onAnyValueChanged(name, questionName);
if (name != this.getValueName()) {
this.runChoicesByUrl();
}
if (!!name && name == this.choicesFromQuestion) {
const chQuestion = this.choicesFromQuestion;
if (!!name && chQuestion && (name === chQuestion || questionName === chQuestion)) {
this.onVisibleChoicesChanged();
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/question_custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -610,10 +610,10 @@ export class QuestionCustomModel extends QuestionCustomModelBase {
protected getElement(): SurveyElement {
return this.contentQuestion;
}
onAnyValueChanged(name: string) {
super.onAnyValueChanged(name);
onAnyValueChanged(name: string, questionName: string): void {
super.onAnyValueChanged(name, questionName);
if (!!this.contentQuestion) {
this.contentQuestion.onAnyValueChanged(name);
this.contentQuestion.onAnyValueChanged(name, questionName);
}
}
protected getQuestionByName(name: string): IQuestion {
Expand Down Expand Up @@ -848,11 +848,11 @@ export class QuestionCompositeModel extends QuestionCustomModelBase {
questions[i].clearValueIfInvisible(reason);
}
}
onAnyValueChanged(name: string) {
super.onAnyValueChanged(name);
onAnyValueChanged(name: string, questionName: string): void {
super.onAnyValueChanged(name, questionName);
var questions = this.contentPanel.questions;
for (var i = 0; i < questions.length; i++) {
questions[i].onAnyValueChanged(name);
questions[i].onAnyValueChanged(name, questionName);
}
}
public get hasSingleInput(): boolean { return false; }
Expand Down
12 changes: 6 additions & 6 deletions src/question_matrixdropdownbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,10 +372,10 @@ implements ISurveyData, ISurveyImpl, ILocalizableOwner {
questions[i].clearValue();
}
}
public onAnyValueChanged(name: string) {
public onAnyValueChanged(name: string, questionName: string): void {
var questions = this.questions;
for (var i = 0; i < questions.length; i++) {
questions[i].onAnyValueChanged(name);
questions[i].onAnyValueChanged(name, questionName);
}
}
public getDataValueCore(valuesHash: any, key: string): any {
Expand Down Expand Up @@ -438,7 +438,7 @@ implements ISurveyData, ISurveyImpl, ILocalizableOwner {
const isDeleting = newColumnValue == null && !changedQuestion ||
isComment && !newColumnValue && !!changedQuestion && changedQuestion.autoOtherMode;
this.data.onRowChanged(this, changedName, newValue, isDeleting);
this.onAnyValueChanged(MatrixDropdownRowModelBase.RowVariableName);
this.onAnyValueChanged(MatrixDropdownRowModelBase.RowVariableName, "");
}

private updateQuestionsValue(
Expand Down Expand Up @@ -2084,7 +2084,7 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
: newValue;
}
private isDoingonAnyValueChanged = false;
onAnyValueChanged(name: string) {
onAnyValueChanged(name: string, questionName: string): void {
if (
this.isUpdateLocked ||
this.isDoingonAnyValueChanged ||
Expand All @@ -2094,11 +2094,11 @@ export class QuestionMatrixDropdownModelBase extends QuestionMatrixBaseModel<Mat
this.isDoingonAnyValueChanged = true;
var rows = this.visibleRows;
for (var i = 0; i < rows.length; i++) {
rows[i].onAnyValueChanged(name);
rows[i].onAnyValueChanged(name, questionName);
}
var totalRow = this.visibleTotalRow;
if (!!totalRow) {
totalRow.onAnyValueChanged(name);
totalRow.onAnyValueChanged(name, questionName);
}
this.isDoingonAnyValueChanged = false;
}
Expand Down
10 changes: 4 additions & 6 deletions src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1534,13 +1534,11 @@ export class QuestionPanelDynamicModel extends Question
}
this.isValueChangingInternally = false;
}
onAnyValueChanged(name: string) {
super.onAnyValueChanged(name);
onAnyValueChanged(name: string, questionName: string): void {
super.onAnyValueChanged(name, questionName);
for (var i = 0; i < this.panels.length; i++) {
this.panels[i].onAnyValueChanged(name);
this.panels[i].onAnyValueChanged(
QuestionPanelDynamicItem.ItemVariableName
);
this.panels[i].onAnyValueChanged(name, questionName);
this.panels[i].onAnyValueChanged(QuestionPanelDynamicItem.ItemVariableName, "");
}
}
private hasKeysDuplicated(fireCallback: boolean, rec: any = null) {
Expand Down
22 changes: 13 additions & 9 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5417,7 +5417,7 @@ export class SurveyModel extends SurveyElementCore
}
return res;
}
protected notifyQuestionOnValueChanged(valueName: string, newValue: any) {
protected notifyQuestionOnValueChanged(valueName: string, newValue: any, questionName: string): void {
if (this.isLoadingFromJson) return;
var questions = this.getQuestionsByValueName(valueName);
if (!!questions) {
Expand All @@ -5440,7 +5440,7 @@ export class SurveyModel extends SurveyElementCore
}
if (this.isDisposed) return;
this.checkElementsBindings(valueName, newValue);
this.notifyElementsOnAnyValueOrVariableChanged(valueName);
this.notifyElementsOnAnyValueOrVariableChanged(valueName, questionName);
}
private isRunningElementsBindings: boolean;
private updateVisibleIndexAfterBindings: boolean;
Expand All @@ -5455,14 +5455,14 @@ export class SurveyModel extends SurveyElementCore
this.updateVisibleIndexAfterBindings = false;
}
}
private notifyElementsOnAnyValueOrVariableChanged(name: string) {
private notifyElementsOnAnyValueOrVariableChanged(name: string, questionName?: string) {
if (this.isEndLoadingFromJson === "processing") return;
if (this.isRunningConditions) {
this.conditionNotifyElementsOnAnyValueOrVariableChanged = true;
return;
}
for (var i = 0; i < this.pages.length; i++) {
this.pages[i].onAnyValueChanged(name);
this.pages[i].onAnyValueChanged(name, questionName);
}
if (!this.isEndLoadingFromJson) {
this.locStrsChanged();
Expand Down Expand Up @@ -6147,8 +6147,9 @@ export class SurveyModel extends SurveyElementCore
name: string,
newQuestionValue: any,
locNotification: any = false,
allowNotifyValueChanged: boolean = true
) {
allowNotifyValueChanged: boolean = true,
questionName?: string
):void {
var newValue = newQuestionValue;
if (allowNotifyValueChanged) {
newValue = this.questionOnValueChanging(name, newQuestionValue);
Expand Down Expand Up @@ -6176,7 +6177,8 @@ export class SurveyModel extends SurveyElementCore
newValue,
oldValue,
locNotification,
allowNotifyValueChanged
allowNotifyValueChanged,
questionName
);
}
private isValueEmpyOnSetValue(name: string, val: any): boolean {
Expand All @@ -6189,16 +6191,18 @@ export class SurveyModel extends SurveyElementCore
newValue: any,
oldValue: any,
locNotification: any = false,
allowNotifyValueChanged: boolean = true
allowNotifyValueChanged: boolean = true,
questionName?: string
) {
this.updateQuestionValue(name, newValue);
if (locNotification === true || this.isDisposed || this.isRunningElementsBindings) return;
questionName = questionName || name;
var triggerKeys: { [index: string]: any } = {};
triggerKeys[name] = { newValue: newValue, oldValue: oldValue };
this.runConditionOnValueChanged(name, newValue);
this.checkTriggers(triggerKeys, false, false, name);
if (allowNotifyValueChanged)
this.notifyQuestionOnValueChanged(name, newValue);
this.notifyQuestionOnValueChanged(name, newValue, questionName);
if (locNotification !== "text") {
this.tryGoNextPageAutomatic(name);
}
Expand Down
3 changes: 2 additions & 1 deletion testCafe/survey/titleActions.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { frameworks, url, initSurvey, url_test, applyTheme } from "../helper";
import { frameworks, url, initSurvey, url_test, applyTheme, explicitErrorHandler } from "../helper";
import { Selector, ClientFunction, fixture, test } from "testcafe";
const title = "titleActions";

Expand Down Expand Up @@ -320,6 +320,7 @@ frameworks.forEach((framework) => {
await applyTheme(themeName);
});
test("check hidden action content has non-zero width", async (t) => {
await explicitErrorHandler();
await initSurvey(framework, json, {
onGetQuestionTitleActions: (_, opt) => {
opt.titleActions = [
Expand Down
37 changes: 37 additions & 0 deletions tests/question_baseselecttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1238,4 +1238,41 @@ QUnit.test("Allow to override default value fro choicesByUrl.path Bug#6766", fun
assert.equal(q1.choicesByUrl.path, "list", "get new default value for path");
prop.defaultValue = undefined;
});
QUnit.test("Use carryForward with panel dynamic + choiceValuesFromQuestion + valueName, Bug#6948-1", function (assert) {
const survey = new SurveyModel({ elements: [
{ type: "paneldynamic", name: "q1", valueName: "sharedData",
templateElements: [{ name: "q1-q1", type: "text" }]
},
{ type: "checkbox", name: "q2", choicesFromQuestion: "q1", choiceValuesFromQuestion: "q1-q1" }
] });
const q1 = <QuestionPanelDynamicModel>survey.getQuestionByName("q1");
const q2 = <QuestionCheckboxModel>survey.getQuestionByName("q2");
q1.addPanel();
q1.panels[0].getQuestionByName("q1-q1").value = "aaa";
q1.addPanel();
q1.panels[1].getQuestionByName("q1-q1").value = "bbb";
assert.equal(q2.visibleChoices.length, 2, "There are two choice");
assert.equal(q2.visibleChoices[0].value, "aaa", "the first value is correct");
assert.equal(q2.visibleChoices[1].value, "bbb", "the second value is correct");
});

QUnit.test("Use carryForward with panel dynamic + choiceValuesFromQuestion + valueName, Bug#6948-2", function (assert) {
const survey = new SurveyModel({ elements: [
{ type: "paneldynamic", name: "q1", valueName: "sharedData",
templateElements: [{ name: "q1-q1", type: "text" }]
},
{ type: "paneldynamic", name: "q2", valueName: "sharedData",
templateElements: [{ name: "q2-q2", type: "checkbox", choicesFromQuestion: "q1", choiceValuesFromQuestion: "q1-q1" }]
}
] });
const q1 = <QuestionPanelDynamicModel>survey.getQuestionByName("q1");
const q2 = <QuestionPanelDynamicModel>survey.getQuestionByName("q2");
q1.addPanel();
q1.panels[0].getQuestionByName("q1-q1").value = "aaa";
q1.addPanel();
q1.panels[1].getQuestionByName("q1-q1").value = "bbb";
const q2_q2 = q2.panels[0].getQuestionByName("q2-q2");
assert.equal(q2_q2.visibleChoices.length, 2, "There are two choice");
assert.equal(q2_q2.visibleChoices[0].value, "aaa", "the first value is correct");
assert.equal(q2_q2.visibleChoices[1].value, "bbb", "the second value is correct");
});

0 comments on commit d22676a

Please sign in to comment.