diff --git a/src/settings.ts b/src/settings.ts index fbf0f06008..23345aa653 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -546,6 +546,7 @@ export var settings = { notifications: { lifetime: 2000 }, + nextPageAutomaticDelay: 300, /** * Specifies the direction in which to lay out Checkbox and Radiogroup items. This setting affects the resulting UI when items are arranged in [more than one column](https://surveyjs.io/form-library/documentation/api-reference/checkbox-question-model#colCount). * diff --git a/src/survey.ts b/src/survey.ts index 71defdc07f..fa4c8496b8 100644 --- a/src/survey.ts +++ b/src/survey.ts @@ -29,7 +29,7 @@ import { ProcessValue } from "./conditionProcessValue"; import { dxSurveyService } from "./dxSurveyService"; import { surveyLocalization } from "./surveyStrings"; import { CustomError } from "./error"; -import { ILocalizableOwner, LocalizableString } from "./localizablestring"; +import { LocalizableString } from "./localizablestring"; import { StylesManager } from "./stylesmanager"; import { SurveyTimerModel, ISurveyTimerText } from "./surveyTimerModel"; import { IQuestionPlainData, Question } from "./question"; @@ -46,7 +46,7 @@ import { settings } from "./settings"; import { isContainerVisible, isMobile, mergeValues, scrollElementByChildId, navigateToUrl, getRenderedStyleSize, getRenderedSize, wrapUrlForBackgroundImage } from "./utils/utils"; import { SurveyError } from "./survey-error"; import { IAction, Action } from "./actions/action"; -import { ActionContainer, defaultActionBarCss } from "./actions/container"; +import { ActionContainer } from "./actions/container"; import { CssClassBuilder } from "./utils/cssClassBuilder"; import { QuestionPanelDynamicModel } from "./question_paneldynamic"; import { Notifier } from "./notifier"; @@ -72,6 +72,7 @@ import { QuestionMultipleTextModel } from "./question_multipletext"; import { ITheme, ImageFit, ImageAttachment } from "./themes"; import { PopupModel } from "./popup"; import { Cover } from "./cover"; +import { surveyTimerFunctions } from "./surveytimer"; /** * The `SurveyModel` object contains properties and methods that allow you to control the survey and access its elements. @@ -6330,22 +6331,20 @@ export class SurveyModel extends SurveyElementCore for (var i = 0; i < questions.length; i++) { if (questions[i].hasInput && questions[i].isEmpty()) return; } - if (!this.checkIsCurrentPageHasErrors(false)) { + if(this.isLastPage && (this.goNextPageAutomatic !== true || !this.allowCompleteSurveyAutomatic)) return; + if(this.checkIsCurrentPageHasErrors(false)) return; + const goNextPage = () => { if (!this.isLastPage) { this.nextPage(); } else { - if ( - this.goNextPageAutomatic === true && - this.allowCompleteSurveyAutomatic - ) { - if (this.isShowPreviewBeforeComplete) { - this.showPreview(); - } else { - this.completeLastPage(); - } + if (this.isShowPreviewBeforeComplete) { + this.showPreview(); + } else { + this.completeLastPage(); } } - } + }; + surveyTimerFunctions.safeTimeOut(goNextPage, settings.nextPageAutomaticDelay); } /** * Returns a comment value from a question with a specified `name`. diff --git a/src/surveytimer.ts b/src/surveytimer.ts index f7523768f8..193e089845 100644 --- a/src/surveytimer.ts +++ b/src/surveytimer.ts @@ -1,14 +1,21 @@ import { Event } from "./base"; export var surveyTimerFunctions = { - setTimeout: function (func: () => any): number { - if (typeof window === "undefined") return 0; - return window.setTimeout(func, 1000); + setTimeout: (func: () => any): number => { + return surveyTimerFunctions.safeTimeOut(func, 1000); }, - clearTimeout: function (timerId: number) { + clearTimeout: (timerId: number): void => { if (typeof window === "undefined") return; window.clearTimeout(timerId); }, + safeTimeOut: (func:() => any, delay: number): number => { + if (typeof window === "undefined" || delay <= 0) { + func(); + return 0; + } else { + return window.setTimeout(func, delay); + } + } }; export class SurveyTimer { diff --git a/tests/ko/survey_kotests.ts b/tests/ko/survey_kotests.ts index 02c4726c6d..14dab93777 100644 --- a/tests/ko/survey_kotests.ts +++ b/tests/ko/survey_kotests.ts @@ -24,9 +24,12 @@ import { QuestionBoolean } from "../../src/knockout/koquestion_boolean"; import * as ko from "knockout"; import { ItemValue } from "../../src/itemvalue"; import { StylesManager } from "../../src/stylesmanager"; +import { settings } from "../../src/settings"; export default QUnit.module("koTests"); +settings.nextPageAutomaticDelay = 0; + QUnit.test("koOtherVisible for one choice items", function (assert) { var survey = new Survey(); var question = new QuestionCheckbox("q"); diff --git a/tests/surveyShowPreviewTests.ts b/tests/surveyShowPreviewTests.ts index bb66b8ea2b..316d134faf 100644 --- a/tests/surveyShowPreviewTests.ts +++ b/tests/surveyShowPreviewTests.ts @@ -6,6 +6,8 @@ import { settings } from "../src/settings"; export default QUnit.module("SurveyShowPreviewTests"); +settings.nextPageAutomaticDelay = 0; + QUnit.test("Complete and Preview button visibility", function(assert) { var survey = new SurveyModel({ elements: [{ type: "text", name: "q1" }] }); assert.equal(survey.currentPageNo, 0, "Init current page"); diff --git a/tests/surveyquestiontests.ts b/tests/surveyquestiontests.ts index 18b972340e..23af51b093 100644 --- a/tests/surveyquestiontests.ts +++ b/tests/surveyquestiontests.ts @@ -38,9 +38,12 @@ import { Helpers } from "../src/helpers"; import { CustomWidgetCollection } from "../src/questionCustomWidgets"; import { ConsoleWarnings } from "../src/console-warnings"; import { StylesManager } from "../src/stylesmanager"; +import { surveyTimerFunctions } from "../src/surveytimer"; export default QUnit.module("Survey_Questions"); +settings.nextPageAutomaticDelay = 0; + class QuestionMatrixRandomModel extends QuestionMatrixModel { constructor(name: string) { super(name); @@ -827,41 +830,79 @@ QUnit.test("Multiple Text Question: support goNextPageAutomatic", function ( "Both text inputs are set" ); }); - -QUnit.test( - "Radiogroup Question: support goNextPageAutomatic + hasOther", - function (assert) { - var json = { - pages: [ - { - elements: [ - { - type: "radiogroup", - name: "q1", - hasOther: true, - items: [1, 2, 3], - }, - ], - }, - { - elements: [ - { - type: "text", - name: "q2", - }, - ], - }, - ], - goNextPageAutomatic: true, - }; - var survey = new SurveyModel(json); - var question = survey.getQuestionByName("q1"); - question.value = "other"; - assert.equal(survey.currentPageNo, 0, "Stay on the first page"); - question.comment = "123"; - assert.equal(survey.currentPageNo, 1, "Go to the second page"); - } -); +QUnit.test("Use timer to go next page", function (assert) { + settings.nextPageAutomaticDelay = 250; + const json = { + pages: [ + { + elements: [ + { + type: "radiogroup", + name: "q1", + choices: ["a", "b", "c"], + }, + ], + }, + { + elements: [ + { + type: "text", + name: "q2", + }, + ], + }, + ], + goNextPageAutomatic: true, + }; + const prevFunc = surveyTimerFunctions.safeTimeOut; + let checkDelay: number = 0; + surveyTimerFunctions.safeTimeOut = (func:() => any, delay: number): number => { + checkDelay = delay; + func(); + return 0; + }; + const survey = new SurveyModel(json); + assert.equal(survey.goNextPageAutomatic, true, "The property set correctly"); + const question = survey.getQuestionByName("q1"); + question.onMouseDown(); + assert.equal(question.supportGoNextPageAutomatic(), true, "questio support go next page automatic"); + question.value = 1; + assert.equal(survey.currentPageNo, 1, "Go to the second page"); + assert.equal(checkDelay, 250, "setTimeout function is called"); + surveyTimerFunctions.safeTimeOut = prevFunc; + settings.nextPageAutomaticDelay = 0; +}); +QUnit.test("Radiogroup Question: support goNextPageAutomatic + hasOther", function (assert) { + var json = { + pages: [ + { + elements: [ + { + type: "radiogroup", + name: "q1", + hasOther: true, + choices: [1, 2, 3], + }, + ], + }, + { + elements: [ + { + type: "text", + name: "q2", + }, + ], + }, + ], + goNextPageAutomatic: true, + }; + const survey = new SurveyModel(json); + const question = survey.getQuestionByName("q1"); + question.value = "other"; + assert.equal(survey.currentPageNo, 0, "Stay on the first page"); + question.comment = "123"; + assert.equal(survey.currentPageNo, 1, "Go to the second page"); +}); QUnit.test( "Radiogroup Question: support goNextPageAutomatic + hasOther + textUpdateMode = onTyping", @@ -874,7 +915,7 @@ QUnit.test( type: "radiogroup", name: "q1", hasOther: true, - items: [1, 2, 3], + choices: [1, 2, 3], }, ], }, diff --git a/tests/surveytests.ts b/tests/surveytests.ts index 1787209a36..ab84edf211 100644 --- a/tests/surveytests.ts +++ b/tests/surveytests.ts @@ -66,6 +66,8 @@ import { StylesManager } from "../src/stylesmanager"; export default QUnit.module("Survey"); +settings.nextPageAutomaticDelay = 0; + QUnit.test("set data property", function (assert) { var survey = new SurveyModel(); assert.deepEqual(survey.data, {}, "there is no data");