Skip to content

Commit

Permalink
Features/9336 on dynamic panel value changed (#9350)
Browse files Browse the repository at this point in the history
* Dynamic Panel - Introduce the onDynamicPanelValueChanging event fix #9336

* Fix compile error in test
  • Loading branch information
andrewtelnov committed Jan 28, 2025
1 parent 273b83c commit 5bee3cd
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
3 changes: 2 additions & 1 deletion packages/survey-core/src/base-interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ export interface ISurvey extends ITextProcessor, ISurveyErrorOwner {
dynamicPanelAdded(question: IQuestion, panelIndex?: number, panel?: IPanel): void;
dynamicPanelRemoved(question: IQuestion, panelIndex: number, panel: IPanel): void;
dynamicPanelRemoving(question: IQuestion, panelIndex: number, panel: IPanel): boolean;
dynamicPanelItemValueChanged(question: IQuestion, options: any): any;
dynamicPanelItemValueChanged(question: IQuestion, options: any): void;
dynamicPanelItemValueChanging(question: IQuestion, options: any): void;
dynamicPanelGetTabTitle(question: IQuestion, options: any): any;
dynamicPanelCurrentIndexChanged(question: IQuestion, options: any): void;

Expand Down
20 changes: 12 additions & 8 deletions packages/survey-core/src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2277,6 +2277,7 @@ export class QuestionPanelDynamicModel extends Question
}
}
if (!qValue[index]) qValue[index] = {};
const oldVal = qValue[index][name];
if (!this.isValueEmpty(val)) {
qValue[index][name] = val;
} else {
Expand All @@ -2287,17 +2288,20 @@ export class QuestionPanelDynamicModel extends Question
name
);
}
const options = {
panel: (<QuestionPanelDynamicItem>item).panel,
name: name,
panelIndex: index,
panelData: qValue[index],
value: val,
oldValue: oldVal
};
if (this.survey) {
this.survey.dynamicPanelItemValueChanging(this, options);
}
this.value = qValue;
this.changingValueQuestion = null;
if (this.survey) {
var options = {
question: this,
panel: (<QuestionPanelDynamicItem>item).panel,
name: name,
itemIndex: index,
itemValue: qValue[index],
value: val,
};
this.survey.dynamicPanelItemValueChanged(this, options);
}
this.isSetPanelItemData[name]--;
Expand Down
11 changes: 10 additions & 1 deletion packages/survey-core/src/survey-events-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ export interface TimerPanelInfoTextEvent {
*/
text: string;
}
export interface DynamicPanelItemValueChangedEvent extends PanelDynamicQuestionEventMixin {
export interface DynamicPanelValueChangedEvent extends PanelDynamicQuestionEventMixin {
/**
* The panel's data object that includes all item values.
*/
Expand All @@ -899,6 +899,15 @@ export interface DynamicPanelItemValueChangedEvent extends PanelDynamicQuestionE
*/
panel: PanelModel;
}
export interface DynamicPanelValueChangingEvent extends DynamicPanelValueChangedEvent {
/**
* The item's old value.
*/
oldValue: any;
}

export interface DynamicPanelItemValueChangedEvent extends DynamicPanelValueChangedEvent {
}
export interface DynamicPanelCurrentIndexChangedEvent extends PanelDynamicQuestionEventMixin {
/**
* A panel for which the event is raised.
Expand Down
20 changes: 14 additions & 6 deletions packages/survey-core/src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ import {
AfterRenderPageEvent, AfterRenderQuestionEvent, AfterRenderQuestionInputEvent, AfterRenderPanelEvent, FocusInQuestionEvent, FocusInPanelEvent,
ShowingChoiceItemEvent, ChoicesLazyLoadEvent, GetChoiceDisplayValueEvent, MatrixRowAddedEvent, MatrixBeforeRowAddedEvent, MatrixRowRemovingEvent, MatrixRowRemovedEvent,
MatrixAllowRemoveRowEvent, MatrixDetailPanelVisibleChangedEvent, MatrixCellCreatingEvent, MatrixCellCreatedEvent, MatrixAfterCellRenderEvent, MatrixCellValueChangedEvent,
MatrixCellValueChangingEvent, MatrixCellValidateEvent, DynamicPanelModifiedEvent, DynamicPanelRemovingEvent, TimerPanelInfoTextEvent, DynamicPanelItemValueChangedEvent,
MatrixCellValueChangingEvent, MatrixCellValidateEvent, DynamicPanelModifiedEvent, DynamicPanelRemovingEvent, TimerPanelInfoTextEvent,
DynamicPanelItemValueChangedEvent, DynamicPanelValueChangedEvent, DynamicPanelValueChangingEvent,
DynamicPanelGetTabTitleEvent, DynamicPanelCurrentIndexChangedEvent, CheckAnswerCorrectEvent, DragDropAllowEvent, ScrollToTopEvent, GetQuestionTitleActionsEvent,
GetPanelTitleActionsEvent, GetPageTitleActionsEvent, GetPanelFooterActionsEvent, GetMatrixRowActionsEvent, GetExpressionDisplayValueEvent,
ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent, ChoicesSearchEvent,
Expand Down Expand Up @@ -232,7 +233,7 @@ export class SurveyModel extends SurveyElementCore
*
* For information on event handler parameters, refer to descriptions within the interface.
*
* To handle value changes in matrix cells or panels within a [Dynamic Panel](https://surveyjs.io/form-library/documentation/api-reference/dynamic-panel-model), use the [`onMatrixCellValueChanged`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onMatrixCellValueChanged) or [`onDynamicPanelItemValueChanged`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onDynamicPanelItemValueChanged) event.
* To handle value changes in matrix cells or panels within a [Dynamic Panel](https://surveyjs.io/form-library/documentation/api-reference/dynamic-panel-model), use the [`onMatrixCellValueChanged`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onMatrixCellValueChanged) or [`onDynamicPanelValueChanged`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#onDynamicPanelValueChanged) event.
* @see setValue
*/
public onValueChanged: EventBase<SurveyModel, ValueChangedEvent> = this.addEvent<SurveyModel, ValueChangedEvent>();
Expand Down Expand Up @@ -794,7 +795,12 @@ export class SurveyModel extends SurveyElementCore
/**
* An event that is raised after an item value is changed in a panel within a [Dynamic Panel](https://surveyjs.io/form-library/examples/questiontype-paneldynamic/) question.
*/
public onDynamicPanelItemValueChanged: EventBase<SurveyModel, DynamicPanelItemValueChangedEvent> = this.addEvent<SurveyModel, DynamicPanelItemValueChangedEvent>();
public onDynamicPanelValueChanged: EventBase<SurveyModel, DynamicPanelItemValueChangedEvent> = this.addEvent<SurveyModel, DynamicPanelValueChangedEvent>();
public onDynamicPanelItemValueChanged: EventBase<SurveyModel, DynamicPanelItemValueChangedEvent> = this.onDynamicPanelValueChanged;
/**
* An event that is raised after an item value is changing in a panel within a [Dynamic Panel](https://surveyjs.io/form-library/examples/questiontype-paneldynamic/) question.
*/
public onDynamicPanelValueChanging: EventBase<SurveyModel, DynamicPanelItemValueChangedEvent> = this.addEvent<SurveyModel, DynamicPanelValueChangingEvent>();

/**
* An event that is raised before a [Dynamic Panel](https://surveyjs.io/form-library/examples/questiontype-paneldynamic/) renders [tab titles](https://surveyjs.io/form-library/documentation/api-reference/dynamic-panel-model#templateTabTitle). Use this event to change individual tab titles.
Expand Down Expand Up @@ -5339,9 +5345,11 @@ export class SurveyModel extends SurveyElementCore
}
dynamicPanelItemValueChanged(question: IQuestion, options: any): void {
options.question = question;
options.panelIndex = options.itemIndex;
options.panelData = options.itemValue;
this.onDynamicPanelItemValueChanged.fire(this, options);
this.onDynamicPanelValueChanged.fire(this, options);
}
dynamicPanelItemValueChanging(question: IQuestion, options: any): void {
options.question = question;
this.onDynamicPanelValueChanging.fire(this, options);
}
dynamicPanelGetTabTitle(question: IQuestion, options: any): void {
options.question = question;
Expand Down
30 changes: 30 additions & 0 deletions packages/survey-core/tests/question_paneldynamic_tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { QuestionMatrixModel } from "../src/question_matrix";
import { defaultStandardCss } from "@legacy/defaultCss/cssstandard";
import { AnimationGroup, AnimationTab } from "../src/utils/animation";
import { SurveyElement } from "../src/survey-element";
import { DynamicPanelValueChangingEvent } from "../src/survey-events-api";

export default QUnit.module("Survey_QuestionPanelDynamic");

Expand Down Expand Up @@ -4386,6 +4387,35 @@ QUnit.test("Avoid stack-overflow", function(assert) {
);
});

QUnit.test("survey.onDynamicPanelValueChanging event", function(assert) {
const survey = new SurveyModel({ elements: [{
type: "paneldynamic",
name: "panel",
templateElements: [
{ type: "text", name: "q1", isRequired: true },
{ type: "text", name: "q2" },
{ type: "text", name: "q3" },
]
}] });
const opt = new Array<any>();
survey.onDynamicPanelValueChanging.add((sender, options: DynamicPanelValueChangingEvent) => {
opt.push({ name: options.name, value: options.value, oldValue: options.oldValue, panelIndex: options.panelIndex });
});

const question = <QuestionPanelDynamicModel>survey.getQuestionByName("panel");
question.panelCount = 2;
question.panels[0].getQuestionByName("q1").value = "1";
question.panels[1].getQuestionByName("q2").value = "2";
question.panels[0].getQuestionByName("q1").value = "3";
question.panels[1].getQuestionByName("q2").value = "4";
assert.deepEqual(opt,
[{ name: "q1", panelIndex: 0, value: "1", oldValue: undefined },
{ name: "q2", panelIndex: 1, value: "2", oldValue: undefined },
{ name: "q1", panelIndex: 0, value: "3", oldValue: "1" },
{ name: "q2", panelIndex: 1, value: "4", oldValue: "2" }],
"Check event calls");
});

QUnit.test("getPanelWrapperCss", function(assert) {
StylesManager.applyTheme("default");
var survey = new SurveyModel({
Expand Down

0 comments on commit 5bee3cd

Please sign in to comment.