diff --git a/packages/survey-core/src/base-interfaces.ts b/packages/survey-core/src/base-interfaces.ts index b5099affc5..590018070e 100644 --- a/packages/survey-core/src/base-interfaces.ts +++ b/packages/survey-core/src/base-interfaces.ts @@ -116,6 +116,7 @@ export interface ISurvey extends ITextProcessor, ISurveyErrorOwner { updateNavigationElements(): void; currentSingleElement: IElement; supportsNestedSingleInput(question: IQuestion): boolean; + updateNestedSingleQuestions(question: IQuestion, nestedQuestions: Array): void; areEmptyElementsHidden: boolean; isLoadingFromJson: boolean; isUpdateValueTextOnTyping: boolean; diff --git a/packages/survey-core/src/question.ts b/packages/survey-core/src/question.ts index 6752483b55..02d700b54b 100644 --- a/packages/survey-core/src/question.ts +++ b/packages/survey-core/src/question.ts @@ -1085,7 +1085,12 @@ export class Question extends SurveyElement } public getSingleInputAddText(): string { const q = this.currentSingleInputQuestion; - return !!q && !!q.singleInputSummary ? q.getSingleInputAddTextCore() : undefined; + if (!q) return undefined; + if (!!q.singleInputSummary) return q.getSingleInputAddTextCore(); + const qs = this.getSingleInputQuestions(); + const len = Array.isArray(qs) ? qs.length : 0; + if (len > 0 && qs[len - 1] === q) return this.getSingleInputAddTextCore(); + return undefined; } public singleInputAddItem(checkErrors?: boolean): void { if (!checkErrors || this.validateSingleInput()) { @@ -1206,6 +1211,9 @@ export class Question extends SurveyElement const question = this.getPropertyValue("singleInputQuestion"); if (question === this) return [this]; const res = this.getSingleInputQuestionsCore(question, !question || !this.isSingleInputSummaryShown); + if (this.survey) { + this.survey.updateNestedSingleQuestions(this, res); + } res.forEach(q => { if (q !== this)this.onSingleInputQuestionAdded(q); }); return res; } diff --git a/packages/survey-core/src/survey-events-api.ts b/packages/survey-core/src/survey-events-api.ts index ff6cb8369c..058e00fbe8 100644 --- a/packages/survey-core/src/survey-events-api.ts +++ b/packages/survey-core/src/survey-events-api.ts @@ -1,6 +1,6 @@ import { IAction } from "./actions/action"; import { Base } from "./base"; -import { IDropdownMenuOptions, IElement, IPanel, ISurveyElement, IValueItemCustomPropValues } from "./base-interfaces"; +import { IDropdownMenuOptions, IElement, IPanel, IQuestion, ISurveyElement, IValueItemCustomPropValues } from "./base-interfaces"; import { ItemValue } from "./itemvalue"; import { PageModel } from "./page"; import { PanelModel, PanelModelBase } from "./panel"; @@ -1102,6 +1102,9 @@ export interface GetExpressionDisplayValueEvent extends GetQuestionDisplayValueE export interface CheckSingleInputPerPageModeEvent extends QuestionEventMixin { enabled: boolean; } +export interface GetLoopQuestionsEvent extends QuestionEventMixin { + nestedQuestions: Array; +} export interface MultipleTextItemAddedEvent extends QuestionEventMixin { /** diff --git a/packages/survey-core/src/survey.ts b/packages/survey-core/src/survey.ts index 0cbc80caf9..ff835342af 100644 --- a/packages/survey-core/src/survey.ts +++ b/packages/survey-core/src/survey.ts @@ -67,14 +67,9 @@ import { DynamicPanelItemValueChangedEvent, DynamicPanelValueChangedEvent, DynamicPanelValueChangingEvent, DynamicPanelGetTabTitleEvent, DynamicPanelCurrentIndexChangedEvent, CheckAnswerCorrectEvent, DragDropAllowEvent, ScrollToTopEvent, GetQuestionTitleActionsEvent, GetPanelTitleActionsEvent, GetPageTitleActionsEvent, GetPanelFooterActionsEvent, GetMatrixRowActionsEvent, GetExpressionDisplayValueEvent, CheckSingleInputPerPageModeEvent, - ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, PopupVisibleChangedEvent, ChoicesSearchEvent, - OpenFileChooserEvent, OpenDropdownMenuEvent, ResizeEvent, - GetTitleActionsEventMixin, ProgressTextEvent, ScrollingElementToTopEvent, IsAnswerCorrectEvent, - LoadChoicesFromServerEvent, - ProcessTextValueEvent, - CreateCustomChoiceItemEvent, - MatrixRowDragOverEvent, - ExpressionRunningEvent + GetLoopQuestionsEvent, ServerValidateQuestionsEvent, MultipleTextItemAddedEvent, MatrixColumnAddedEvent, GetQuestionDisplayValueEvent, + PopupVisibleChangedEvent, ChoicesSearchEvent, OpenFileChooserEvent, OpenDropdownMenuEvent, ResizeEvent, GetTitleActionsEventMixin, ProgressTextEvent, ScrollingElementToTopEvent, + IsAnswerCorrectEvent, LoadChoicesFromServerEvent, ProcessTextValueEvent, CreateCustomChoiceItemEvent, MatrixRowDragOverEvent, ExpressionRunningEvent } from "./survey-events-api"; import { QuestionMatrixDropdownModelBase } from "./question_matrixdropdownbase"; import { QuestionMatrixDynamicModel } from "./question_matrixdynamic"; @@ -977,6 +972,7 @@ export class SurveyModel extends SurveyElementCore public onGetExpressionDisplayValue: EventBase = this.addEvent(); public onCheckSingleInputPerPageMode: EventBase = this.addEvent(); + public onGetLoopQuestions: EventBase = this.addEvent(); /** * An event that is raised after the visibility of a popup is changed. @@ -4938,6 +4934,10 @@ export class SurveyModel extends SurveyElementCore this.onCheckSingleInputPerPageMode.fire(this, options); return options.enabled; } + public updateNestedSingleQuestions(question: IQuestion, nestedQuestions: Array): void { + const options: any = { question: question, nestedQuestions: nestedQuestions }; + this.onGetLoopQuestions.fire(this, options); + } private changeCurrentSingleElementOnVisibilityChanged(): void { const el = this.currentSingleElement; if (!el || el.isVisible) return; diff --git a/packages/survey-core/tests/inputPerPageTests.ts b/packages/survey-core/tests/inputPerPageTests.ts index 1b1b8a89f3..b081cc81d6 100644 --- a/packages/survey-core/tests/inputPerPageTests.ts +++ b/packages/survey-core/tests/inputPerPageTests.ts @@ -2396,4 +2396,37 @@ QUnit.skip("singleInput bradscrum navigation for 3 level dynamic panels", assert assert.equal(actions[0].title, "Panel 2", "actions[0] title, #3"); assert.equal(actions[1].title, "Panel 2", "actions[1] title, #3"); actions[0].action(); -}); \ No newline at end of file +}); +QUnit.test("Do not show summary page on request, Issue#10435", assert => { + const survey = new SurveyModel(); + survey.onGetLoopQuestions.add((_, opt) => { + const question = opt.nestedQuestions; + for (let i = question.length - 1; i >= 0; i--) { + if (question[i] === opt.question) { + question.splice(i, 1); + } + } + }); + survey.fromJSON({ + elements: [ + { type: "paneldynamic", name: "panel", panelCount: 1, templateElements: [ + { type: "text", name: "q1" }, + { type: "text", name: "q2" }] + }, + { type: "text", name: "q3" } + ], + questionsOnPageMode: "inputPerPage" + }); + const addBtn = survey.navigationBar.getActionById("sv-singleinput-add"); + const panel = survey.getQuestionByName("panel"); + assert.equal(survey.currentSingleQuestion.name, "panel", "currentSingleQuestion is panel, #1"); + assert.equal(panel.singleInputQuestion.name, "q1", "singleInputQuestion is q1, #1"); + assert.equal(addBtn.visible, false, "addBtn.visible, #1"); + survey.performNext(); + assert.equal(panel.getSingleInputAddText(), "Add new", "getSingleInputAddText, #2"); + assert.equal(panel.singleInputQuestion.name, "q2", "singleInputQuestion is q2, #2"); + assert.equal(addBtn.visible, true, "addBtn.visible, #2"); + survey.performNext(); + assert.equal(survey.currentSingleQuestion.name, "q3", "currentSingleQuestion is q3, #3"); + assert.equal(addBtn.visible, false, "addBtn.visible, #3"); +});