diff --git a/src/base-interfaces.ts b/src/base-interfaces.ts index 1181e7bab0..b3cd6d312e 100644 --- a/src/base-interfaces.ts +++ b/src/base-interfaces.ts @@ -219,6 +219,7 @@ export interface ISurvey extends ITextProcessor, ISurveyErrorOwner { dynamicPanelRemoving(question: IQuestion, panelIndex: number, panel: IPanel): boolean; dynamicPanelItemValueChanged(question: IQuestion, options: any): any; dynamicPanelGetTabTitle(question: IQuestion, options: any): any; + dynamicPanelCurrentIndexChanged(question: IQuestion, options: any): void; dragAndDropAllow(options: DragDropAllowEvent): boolean; diff --git a/src/question_paneldynamic.ts b/src/question_paneldynamic.ts index 48b8f33698..c5c197d70c 100644 --- a/src/question_paneldynamic.ts +++ b/src/question_paneldynamic.ts @@ -555,7 +555,8 @@ export class QuestionPanelDynamicModel extends Question public set currentPanel(val: PanelModel) { if(this.isRenderModeList || this.useTemplatePanel) return; const curPanel = this.getPropertyValue("currentPanel"); - if(!!val && this.visiblePanels.indexOf(val) < 0 || val === curPanel) return; + const index = !!val ? this.visiblePanels.indexOf(val) : -1; + if(!!val && index < 0 || val === curPanel) return; if(curPanel) { curPanel.onHidingContent(); } @@ -563,6 +564,13 @@ export class QuestionPanelDynamicModel extends Question this.updateFooterActions(); this.updateTabToolbarItemsPressedState(); this.fireCallback(this.currentIndexChangedCallback); + if(index > -1 && this.survey) { + const options = { + panel: val, + visiblePanelIndex: index + }; + this.survey.dynamicPanelCurrentIndexChanged(this, options); + } } public onHidingContent(): void { super.onHidingContent(); diff --git a/src/survey-events-api.ts b/src/survey-events-api.ts index a1cf51c70e..bbd7c0b72e 100644 --- a/src/survey-events-api.ts +++ b/src/survey-events-api.ts @@ -810,15 +810,17 @@ export interface DynamicPanelItemValueChangedEvent extends PanelDynamicQuestionE */ panel: PanelModel; } -export interface DynamicPanelGetTabTitleEvent extends PanelDynamicQuestionEventMixin { +export interface DynamicPanelCurrentIndexChangedEvent extends PanelDynamicQuestionEventMixin { /** - * A panel whose tab title is being rendered. + * A panel for which the event is raised. */ panel: PanelModel; /** * The panel's index in the [`visiblePanels`](https://surveyjs.io/form-library/documentation/api-reference/dynamic-panel-model#visiblePanels) array of the Dynamic Panel. */ visiblePanelIndex: number; +} +export interface DynamicPanelGetTabTitleEvent extends DynamicPanelCurrentIndexChangedEvent { /** * A tab title. You can change this parameter's value. */ diff --git a/src/survey.ts b/src/survey.ts index 68db57185e..a0476877ac 100644 --- a/src/survey.ts +++ b/src/survey.ts @@ -61,9 +61,9 @@ import { ShowingChoiceItemEvent, ChoicesLazyLoadEvent, GetChoiceDisplayValueEvent, MatrixRowAddedEvent, MatrixBeforeRowAddedEvent, MatrixRowRemovingEvent, MatrixRowRemovedEvent, MatrixAllowRemoveRowEvent, MatrixCellCreatingEvent, MatrixCellCreatedEvent, MatrixAfterCellRenderEvent, MatrixCellValueChangedEvent, MatrixCellValueChangingEvent, MatrixCellValidateEvent, DynamicPanelModifiedEvent, DynamicPanelRemovingEvent, TimerPanelInfoTextEvent, DynamicPanelItemValueChangedEvent, DynamicPanelGetTabTitleEvent, - IsAnswerCorrectEvent, DragDropAllowEvent, ScrollingElementToTopEvent, GetQuestionTitleActionsEvent, GetPanelTitleActionsEvent, GetPageTitleActionsEvent, - GetPanelFooterActionsEvent, GetMatrixRowActionsEvent, ElementContentVisibilityChangedEvent, GetExpressionDisplayValueEvent, ServerValidateQuestionsEvent, - MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent + DynamicPanelCurrentIndexChangedEvent, IsAnswerCorrectEvent, DragDropAllowEvent, ScrollingElementToTopEvent, GetQuestionTitleActionsEvent, GetPanelTitleActionsEvent, + GetPageTitleActionsEvent, GetPanelFooterActionsEvent, GetMatrixRowActionsEvent, ElementContentVisibilityChangedEvent, GetExpressionDisplayValueEvent, + ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent } from "./survey-events-api"; import { QuestionMatrixDropdownModelBase } from "./question_matrixdropdownbase"; import { QuestionMatrixDynamicModel } from "./question_matrixdynamic"; @@ -745,6 +745,11 @@ export class SurveyModel extends SurveyElementCore */ public onGetDynamicPanelTabTitle: EventBase = this.addEvent(); + /** + * An event that is raised after the current panel is changed in a [Dynamic Panel](https://surveyjs.io/form-library/examples/questiontype-paneldynamic/) question. + */ + public onDynamicPanelCurrentIndexChanged: EventBase = this.addEvent(); + /** * An event that is raised to define whether a question answer is correct. Applies only to [quiz surveys](https://surveyjs.io/form-library/documentation/design-survey/create-a-quiz). */ @@ -4932,6 +4937,10 @@ export class SurveyModel extends SurveyElementCore options.question = question; this.onGetDynamicPanelTabTitle.fire(this, options); } + dynamicPanelCurrentIndexChanged(question: IQuestion, options: any): void { + options.question = question; + this.onDynamicPanelCurrentIndexChanged.fire(this, options); + } dragAndDropAllow(options: DragDropAllowEvent): boolean { this.onDragDropAllow.fire(this, options); return options.allow; diff --git a/tests/question_paneldynamic_tests.ts b/tests/question_paneldynamic_tests.ts index e5cdc532d8..83e3634973 100644 --- a/tests/question_paneldynamic_tests.ts +++ b/tests/question_paneldynamic_tests.ts @@ -5889,6 +5889,44 @@ QUnit.test("templateVisibleIf && currentPanelIndex", function (assert) { assert.equal(panel.visiblePanelCount, 1, "There is one panel"); assert.equal(panel.currentIndex, 0, "currentIndex #8"); }); +QUnit.test("survey.onDynamicPanelCurrentIndexChanged", function (assert) { + const survey = new SurveyModel(); + let questionName = ""; + let panelIndex = -2; + let panelIndexOf = -2; + survey.onDynamicPanelCurrentIndexChanged.add((_, options) => { + questionName = options.question.name; + panelIndex = options.visiblePanelIndex; + panelIndexOf = !!options.panel ? options.question.visiblePanels.indexOf(options.panel) : -1; + }); + survey.fromJSON({ + elements: [ + { type: "paneldynamic", + name: "panel", + templateElements: [ + { type: "text", name: "q1" }, + { type: "text", name: "q2" } + ], + panelCount: 3, + renderMode: "tab" + }], + }); + assert.equal(questionName, "panel", "question is correct"); + assert.equal(panelIndex, 0, "panelIndex #1"); + assert.equal(panelIndexOf, 0, "panelIndexOf #1"); + const panel = survey.getQuestionByName("panel"); + panel.currentIndex = 1; + assert.equal(panelIndex, 1, "panelIndex #2"); + assert.equal(panelIndexOf, 1, "panelIndexOf #2"); + panel.addPanel(); + assert.equal(panel.currentIndex, 3, "panel.panelIndex #3"); + assert.equal(panelIndex, 3, "panelIndex #3"); + assert.equal(panelIndexOf, 3, "panelIndexOf #3"); + panel.removePanel(3); + assert.equal(panel.currentIndex, 2, "panel.panelIndex #4"); + assert.equal(panelIndex, 2, "panelIndex #4"); + assert.equal(panelIndexOf, 2, "panelIndexOf #4"); +}); QUnit.test("templateVisibleIf & renderMode: tab, additionalTitleToolbar&templateTabTitle in JSON", function (assert) { const survey = new SurveyModel({ elements: [