From 9e712b412155a429840ec3b40b06a7995765050f Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 9 Jan 2024 08:58:04 +0200 Subject: [PATCH] Bug/7633 survey try navigate to page (#7634) * survey.onCurrentPageChanged event can be fired multiple times on clicking TOC or progress bar button fix #7633 * Fix unit test #7633 --- src/survey.ts | 18 +++++++++ src/surveyProgressButtons.ts | 10 +---- src/surveyToc.ts | 18 +-------- tests/surveyProgressButtonsTest.ts | 8 ++-- tests/surveyTOCTests.ts | 65 ++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 28 deletions(-) diff --git a/src/survey.ts b/src/survey.ts index 8f0894927e..b5ebd9ee3d 100644 --- a/src/survey.ts +++ b/src/survey.ts @@ -3131,6 +3131,24 @@ export class SurveyModel extends SurveyElementCore this.currentPageChanged(newPage, oldValue); } } + public tryNavigateToPage(page: PageModel): boolean { + if (this.isDesignMode) return false; + const index = this.visiblePages.indexOf(page); + if(index < 0) return false; + if(index === this.currentPageNo) return false; + if (index < this.currentPageNo) { + this.currentPageNo = index; + return true; + } + for (let i = this.currentPageNo; i < index; i++) { + const page = this.visiblePages[i]; + if(!page.validate(true, true)) return false; + page.passed = true; + } + this.currentPage = page; + return true; + } + private updateCurrentPage(): void { if (this.isCurrentPageAvailable) return; this.currentPage = this.firstVisiblePage; diff --git a/src/surveyProgressButtons.ts b/src/surveyProgressButtons.ts index b34d2b6238..d1876936b2 100644 --- a/src/surveyProgressButtons.ts +++ b/src/surveyProgressButtons.ts @@ -29,14 +29,6 @@ export class SurveyProgressButtonsModel { .toString(); } public clickListElement(index: number): void { - if (this.survey.isDesignMode) return; - if (index < this.survey.currentPageNo) { - this.survey.currentPageNo = index; - } - else if (index > this.survey.currentPageNo) { - for (let i: number = this.survey.currentPageNo; i < index; i++) { - if (!this.survey.nextPage()) break; - } - } + this.survey.tryNavigateToPage(this.survey.visiblePages[index]); } } diff --git a/src/surveyToc.ts b/src/surveyToc.ts index 627ccf9216..ae87c58177 100644 --- a/src/surveyToc.ts +++ b/src/surveyToc.ts @@ -7,21 +7,7 @@ import { PopupModel } from "./popup"; import { SurveyModel } from "./survey"; import { IsTouch } from "./utils/devices"; -export function tryNavigateToPage(survey: SurveyModel, page: PageModel) { - if (survey.isDesignMode) return; - const index = survey.visiblePages.indexOf(page); - if (index < survey.currentPageNo) { - survey.currentPageNo = index; - } - else if (index > survey.currentPageNo) { - for (let i = survey.currentPageNo; i < index; i++) { - if (!survey.nextPageUIClick()) return false; - } - } - return true; -} - -export function tryFocusPage(survey: SurveyModel, panel: PanelModelBase) { +export function tryFocusPage(survey: SurveyModel, panel: PanelModelBase): boolean { if (survey.isDesignMode) return true; panel.focusFirstQuestion(); return true; @@ -40,7 +26,7 @@ export function createTOCListModel(survey: SurveyModel, onAction?: () => void) { } !!onAction && onAction(); if (page instanceof PageModel) { - return tryNavigateToPage(survey, page); + return survey.tryNavigateToPage(page); } return tryFocusPage(survey, page); }, diff --git a/tests/surveyProgressButtonsTest.ts b/tests/surveyProgressButtonsTest.ts index fadb1f6db1..a8fc6a745a 100644 --- a/tests/surveyProgressButtonsTest.ts +++ b/tests/surveyProgressButtonsTest.ts @@ -4,7 +4,7 @@ import { SurveyProgressButtonsModel } from "../src/surveyProgressButtons"; export default QUnit.module("SurveyProgressButtons"); QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { - let json: any = { + const json: any = { "pages": [ { "name": "page1", @@ -35,8 +35,8 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { } ] }; - let survey: SurveyModel = new SurveyModel(json); - let progress: SurveyProgressButtonsModel = new SurveyProgressButtonsModel(survey); + const survey: SurveyModel = new SurveyModel(json); + const progress: SurveyProgressButtonsModel = new SurveyProgressButtonsModel(survey); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementCurrent, "1) Page 1 style is current"); @@ -46,6 +46,7 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { "", "1) Page 3 style is empty"); progress.clickListElement(2); + assert.equal(survey.currentPageNo, 2, "currentPageNo #1"); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementPassed, "2) Page 1 style is passed"); @@ -57,6 +58,7 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { "2) Page 3 style is current"); progress.clickListElement(0); + assert.equal(survey.currentPageNo, 0, "currentPageNo #2"); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementPassed + " " + survey.css.progressButtonsListElementCurrent, diff --git a/tests/surveyTOCTests.ts b/tests/surveyTOCTests.ts index 5f67c18a35..d54c5b15b4 100644 --- a/tests/surveyTOCTests.ts +++ b/tests/surveyTOCTests.ts @@ -325,3 +325,68 @@ QUnit.test("TOC shouldn't show search", function (assert) { const tocListModel = createTOCListModel(survey); assert.equal(tocListModel.searchEnabled, false, "Search in TOC should be disabled"); }); +QUnit.test("survey.tryNavigateToPage", function (assert) { + let json: any = { + "pages": [ + { + "name": "page1", + "elements": [ + { + "type": "text", + "name": "question1" + } + ] + }, + { + "name": "page2", + "elements": [ + { + "type": "text", + "name": "question2", + "isRequired": true + } + ] + }, + { + "name": "page3", + "elements": [ + { + "type": "text", + "name": "question3", + "isRequired": true + } + ] + }, + { + "name": "page4", + "elements": [ + { + "type": "text", + "name": "question4" + } + ] + } + ] + }; + const survey = new SurveyModel(json); + const pages = new Array(); + survey.onCurrentPageChanged.add((sender, options) => { + pages.push(options.newCurrentPage.name); + }); + assert.equal(survey.currentPageNo, 0, "currentPageNo #1"); + assert.equal(survey.tryNavigateToPage(survey.pages[3]), false, "navigate #1"); + assert.equal(survey.currentPageNo, 1, "currentPageNo #2"); + assert.equal(survey.tryNavigateToPage(survey.pages[2]), false, "navigate #2"); + assert.equal(survey.currentPageNo, 1, "currentPageNo #3"); + assert.equal(survey.tryNavigateToPage(survey.pages[0]), true, "navigate #3"); + assert.equal(survey.currentPageNo, 0, "currentPageNo #4"); + survey.setValue("question2", "val2"); + assert.equal(survey.tryNavigateToPage(survey.pages[3]), false, "navigate #4"); + assert.equal(survey.currentPageNo, 2, "currentPageNo #4"); + assert.equal(survey.tryNavigateToPage(survey.pages[0]), true, "navigate #5"); + assert.equal(survey.currentPageNo, 0, "currentPageNo #5"); + survey.setValue("question3", "val3"); + assert.equal(survey.tryNavigateToPage(survey.pages[3]), true, "navigate #6"); + assert.equal(survey.currentPageNo, 3, "currentPageNo #6"); + assert.deepEqual(pages, ["page2", "page1", "page3", "page1", "page4"], "Check onCurrentPageChanged"); +});