diff --git a/packages/survey-angular-ui/src/components/progress/buttons/progress.component.html b/packages/survey-angular-ui/src/components/progress/buttons/progress.component.html index 4b63d91365..1f9856e34a 100644 --- a/packages/survey-angular-ui/src/components/progress/buttons/progress.component.html +++ b/packages/survey-angular-ui/src/components/progress/buttons/progress.component.html @@ -1,25 +1,30 @@ -
-
+
+
+
{{ model.headerText }}
+
+
-
    + [class]="survey.css.progressButtonsListContainer" #progressButtonsListContainer> +
    • -
      +
      +
      {{ page.renderedNavigationTitle }}
      -
      {{ page.locNavigationDescription.renderedHtml }} @@ -28,9 +33,12 @@
+
+
{{ model.footerText }}
+
\ No newline at end of file diff --git a/packages/survey-angular-ui/src/components/progress/buttons/progress.component.ts b/packages/survey-angular-ui/src/components/progress/buttons/progress.component.ts index a7b2fa6515..a359bf190c 100644 --- a/packages/survey-angular-ui/src/components/progress/buttons/progress.component.ts +++ b/packages/survey-angular-ui/src/components/progress/buttons/progress.component.ts @@ -1,62 +1,56 @@ import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from "@angular/core"; +import { SurveyModel, ProgressButtons, ProgressButtonsResponsivityManager, IProgressButtonsViewModel } from "survey-core"; import { AngularComponentFactory } from "../../../component-factory"; -import { SurveyModel, SurveyProgressButtonsModel } from "survey-core"; @Component({ selector: "sv-ng-progress-buttons", templateUrl: "./progress.component.html" }) -export class ProgressButtonsComponent implements OnDestroy, AfterViewInit, OnChanges, OnInit { - @Input() model!: SurveyModel; +export class ProgressButtonsComponent implements OnDestroy, AfterViewInit, OnChanges, OnInit, IProgressButtonsViewModel { + @Input() model!: ProgressButtons; + @Input() survey!: SurveyModel; + @Input() container!: string; @ViewChild("progressButtonsListContainer") progressButtonsListContainer!: ElementRef; - private progressButtonsModel!: SurveyProgressButtonsModel; - private hasScroller: boolean = false; - private updateScroller: any = undefined; + public hasScroller: boolean = false; + public canShowHeader: boolean = false; + public canShowFooter: boolean = false; + public canShowItemTitles: boolean = true; + private respManager?: ProgressButtonsResponsivityManager; constructor(private changeDetectorRef: ChangeDetectorRef) { } - private createProgressButtonsModel() { - this.progressButtonsModel = new SurveyProgressButtonsModel(this.model); + onResize(canShowItemTitles: boolean): void { + this.canShowItemTitles = canShowItemTitles; + this.canShowHeader = !this.canShowItemTitles; + this.changeDetectorRef.detectChanges(); } - ngOnInit(): void { - this.createProgressButtonsModel(); - } - ngOnChanges(changes: SimpleChanges): void { - this.createProgressButtonsModel(); - } - public isListElementClickable(index: number): boolean { - return this.progressButtonsModel.isListElementClickable(index); + onUpdateScroller(hasScroller: boolean): void { + this.hasScroller = hasScroller; + this.changeDetectorRef.detectChanges(); } - public getListElementCss(index: number): string { - return this.progressButtonsModel.getListElementCss(index); + onUpdateSettings(): void { + this.canShowItemTitles = this.model.showItemTitles; + this.canShowFooter = !this.model.showItemTitles; + this.changeDetectorRef.detectChanges(); } - public clickListElement(index: number): void { - this.progressButtonsModel.clickListElement(index); + ngOnInit(): void { } - public getScrollButtonCss(isLeftScroll: boolean): string { - return this.progressButtonsModel.getScrollButtonCss(this.hasScroller, isLeftScroll); + ngOnChanges(changes: SimpleChanges): void { } public clickScrollButton( isLeftScroll: boolean ): void { - if(this.progressButtonsListContainer) { + if (this.progressButtonsListContainer) { this.progressButtonsListContainer.nativeElement.scrollLeft += (isLeftScroll ? -1 : 1) * 70; } } public ngAfterViewInit(): void { - this.progressButtonsModel = new SurveyProgressButtonsModel(this.model); - this.updateScroller = setInterval(() => { - if(!!this.progressButtonsListContainer?.nativeElement) { - const listContainerElement = this.progressButtonsListContainer.nativeElement; - this.hasScroller = listContainerElement.scrollWidth > listContainerElement.offsetWidth; - this.changeDetectorRef.detectChanges(); - } - }, 100); + if (!!this.progressButtonsListContainer?.nativeElement) { + const element = this.progressButtonsListContainer.nativeElement; + this.respManager = new ProgressButtonsResponsivityManager(this.model, element, this); + } } public ngOnDestroy(): void { - if (typeof this.updateScroller !== "undefined") { - clearInterval(this.updateScroller); - this.updateScroller = undefined; - } + this.respManager?.dispose(); } } AngularComponentFactory.Instance.registerComponent("sv-progress-buttons", ProgressButtonsComponent); diff --git a/packages/survey-vue3-ui/src/components/Container.vue b/packages/survey-vue3-ui/src/components/Container.vue index b731bc21f9..3176c32c40 100644 --- a/packages/survey-vue3-ui/src/components/Container.vue +++ b/packages/survey-vue3-ui/src/components/Container.vue @@ -15,6 +15,7 @@ diff --git a/packages/survey-vue3-ui/src/components/progress/ProgressButtons.vue b/packages/survey-vue3-ui/src/components/progress/ProgressButtons.vue index 43ba6ba318..815e0f7ce7 100644 --- a/packages/survey-vue3-ui/src/components/progress/ProgressButtons.vue +++ b/packages/survey-vue3-ui/src/components/progress/ProgressButtons.vue @@ -1,8 +1,11 @@ diff --git a/packages/survey-vue3-ui/src/index.ts b/packages/survey-vue3-ui/src/index.ts index 3650a4ed3d..24871ac0dd 100644 --- a/packages/survey-vue3-ui/src/index.ts +++ b/packages/survey-vue3-ui/src/index.ts @@ -89,7 +89,7 @@ import PopupPointer from "./components/popup/PopupPointer.vue"; import Container from "./components/Container.vue"; import Progress from "./components/progress/Progress.vue"; -import ProgressButtons from "./components/progress/ProgressButtons.vue"; +import ProgressButtonsComponent from "./components/progress/ProgressButtons.vue"; import ProgressToc from "./components/progress/ProgressToc.vue"; import SurveyVue from "./Survey.vue"; import Notifier from "./Notifier.vue"; @@ -214,7 +214,7 @@ function registerComponents(app: App) { app.component("sv-components-container", Container); - app.component("sv-progress-buttons", ProgressButtons); + app.component("sv-progress-buttons", ProgressButtonsComponent); app.component("sv-navigation-toc", ProgressToc); app.component("sv-progress-pages", Progress); app.component("sv-progress-questions", Progress); diff --git a/src/defaultCss/defaultV2Css.ts b/src/defaultCss/defaultV2Css.ts index 9d63b94a43..cbde866405 100644 --- a/src/defaultCss/defaultV2Css.ts +++ b/src/defaultCss/defaultV2Css.ts @@ -130,8 +130,13 @@ export var defaultV2Css = { progressBottom: "sd-body__progress--bottom", progressBar: "sd-progress__bar", progressText: "sd-progress__text", + progressButtonsRoot: "sd-progress-buttons", + progressButtonsNumbered: "sd-progress-buttons--numbered", progressButtonsContainerCenter: "sd-progress-buttons__container-center", progressButtonsContainer: "sd-progress-buttons__container", + progressButtonsConnector: "sd-progress-buttons__connector", + progressButtonsHeader: "sd-progress-buttons__header", + progressButtonsFooter: "sd-progress-buttons__footer", progressButtonsImageButtonLeft: "sd-progress-buttons__image-button-left", progressButtonsImageButtonRight: "sd-progress-buttons__image-button-right", progressButtonsImageButtonHidden: "sd-progress-buttons__image-button--hidden", diff --git a/src/defaultV2-theme/blocks/sd-progress-buttons.scss b/src/defaultV2-theme/blocks/sd-progress-buttons.scss index 5755c2be46..39f8b2996f 100644 --- a/src/defaultV2-theme/blocks/sd-progress-buttons.scss +++ b/src/defaultV2-theme/blocks/sd-progress-buttons.scss @@ -10,59 +10,200 @@ visibility: hidden; } -.sd-progress-buttons__list { +.sd-progress-buttons__page-description { + display: none; +} + +.sd-progress-buttons { + padding: calcSize(4) calcSize(5) calcSize(2) calcSize(5); display: flex; - list-style-type: none; - margin: 0; - padding: 0; + flex-direction: column; } -.sd-progress-buttons__list li { - text-align: center; +.sd-progress-buttons__list-container { + display: flex; + overflow: hidden; +} + +.sd-progress-buttons__connector { + display: none; +} + +.sd-progress-buttons__list { + display: inline-flex; + flex-direction: row; flex-grow: 1; - text-decoration: none; - border-top: 2px solid $border-light; - padding-top: calcSize(2); - padding-bottom: calcSize(4); - cursor: pointer; + margin: 0 auto; + padding: 0; - &:hover { - .sd-progress-buttons__page-title { - text-decoration-line: underline; + li { + display: flex; + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0; + position: relative; + flex-wrap: nowrap; + text-align: center; + flex-direction: column; + + &:not(:first-child)>.sd-progress-buttons__connector { + display: block; + content: ""; + width: 100%; + height: calcSize(0.25); + background-color: $navigation; + position: absolute; + bottom: calcSize(0.875); + right: 50%; + } + + &:after { + display: flex; + content: attr(data-page-number); + width: calcSize(0); + height: calcSize(0); + margin: calcSize(0.5); + border: calcSize(0.5) solid transparent; + background-color: $navigation; + border-radius: 50%; + cursor: pointer; + align-self: center; + z-index: 1; + font-size: calcFontSize(0.75); + font-weight: 600; + line-height: calcLineHeight(1); + justify-content: center; + color: $background-dim; + } + } + + .sd-progress-buttons__list-element--passed { + &:not(:first-child)>.sd-progress-buttons__connector { + background-color: $primary; + } + + &:after { + background-color: $primary; + } + } + + .sd-progress-buttons__list-element--current { + &:not(:first-child)>.sd-progress-buttons__connector { + background-color: $primary; } + + &:after { + border-color: $primary; + background-color: $primary-foreground; + color: $primary; + padding: calcSize(0.5); + margin: 0; + } + } +} + +.sd-progress-buttons__page-title { + display: flex; + justify-content: center; + align-items: center; + font-size: calcFontSize(0.75); + font-weight: 600; + line-height: calcLineHeight(1); + flex-grow: 1; + text-align: center; + padding: 0 calcSize(2); + margin-bottom: calcSize(2); +} + +.sd-progress-buttons__header { + .sd-progress-buttons__page-title { + margin-bottom: calcSize(1); } } -.sd-progress-buttons__list .sd-progress-buttons__list-element--current, -.sd-progress-buttons__list .sd-progress-buttons__list-element--passed { - border-top: 2px solid $primary; +.sd-progress-buttons__footer { + .sd-progress-buttons__page-title { + margin-top: calcSize(1); + margin-bottom: 0; + justify-content: flex-end; + padding: 0; + color: $foreground-dim-light; + } } -.sd-progress-buttons__list-element--nonclickable { +.sd-progress-buttons--bottom { + padding: calcSize(2) calcSize(5) calcSize(4) calcSize(5); + flex-direction: column-reverse; + + .sd-progress-buttons__list { + li { + flex-direction: column-reverse; + + &:not(:first-child)>.sd-progress-buttons__connector { + top: calcSize(0.875); + } + } + } + .sd-progress-buttons__page-title { - color: $foreground-light; + margin-top: calcSize(2); + margin-bottom: 0; + } + + .sd-progress-buttons__header { + .sd-progress-buttons__page-title { + margin-top: calcSize(1); + margin-bottom: 0; + } + } + + .sd-progress-buttons__footer { + .sd-progress-buttons__page-title { + margin-top: 0; + margin-bottom: calcSize(1); + } } } -.sd-progress-buttons__list-element--current { +.sd-progress-buttons--numbered { + .sd-progress-buttons__list { + li { + &:not(:first-child)>.sd-progress-buttons__connector { + bottom: calcSize(1.875); + } - .sd-progress-buttons__page-title, - .sd-progress-buttons__page-description { - color: $primary; + &:after { + width: calcSize(2); + height: calcSize(2); + } + } } } -.sd-progress-buttons__page-title { - width: 100%; - font-size: calcFontSize(1); - font-weight: 600; - line-height: calcLineHeight(1.5); +.sd-root-modern--mobile, +.sd-progress-buttons--no-titles { + .sd-progress-buttons__list { + justify-content: space-between; + width: 100%; + + li { + flex-grow: 0; + } + } } -.sd-progress-buttons__page-description { - width: 100%; - font-size: calcFontSize(0.75); - line-height: calcLineHeight(1); - font-weight: 600; - color: $foreground-light; +.sd-progress-buttons--bottom.sd-progress-buttons--numbered { + .sd-progress-buttons__list { + li { + &:not(:first-child)>.sd-progress-buttons__connector { + top: calcSize(1.875); + } + } + } +} + +.sd-root-modern--mobile { + .sd-progress-buttons { + padding: calcSize(2) calcSize(3); + } } \ No newline at end of file diff --git a/src/defaultV2-theme/variables.scss b/src/defaultV2-theme/variables.scss index 05624008a0..86d2ccdfbf 100644 --- a/src/defaultV2-theme/variables.scss +++ b/src/defaultV2-theme/variables.scss @@ -36,6 +36,7 @@ $header-backcolor: var(--sjs-header-backcolor, #{$primary}); $border: var(--sjs-border-default, var(--border, #d6d6d6)); $border-light: var(--sjs-border-light, var(--border-light, #eaeaea)); $border-inside: var(--sjs-border-inside, var(--border-inside, rgba(0, 0, 0, 0.16))); +$navigation: var(--sjs-navigation-default, #bcbcbc); $shadow-small: var(--sjs-shadow-small, 0px 1px 2px 0px rgba(0, 0, 0, 0.15)); $shadow-medium: var(--sjs-shadow-medium, 0px 2px 6px 0px rgba(0, 0, 0, 0.1)); @@ -111,6 +112,7 @@ $font-editorfont-size: var(--sjs-internal-font-editorfont-size); $sd-panel-normal-min-width: 496px; $sd-panel-medium-min-width: 176px; + @mixin useEditorFontSize { --sjs-internal-font-editorfont-size: var(--sjs-mobile-font-editorfont-size, #{$font-default-editorfont-size}); } diff --git a/src/entries/chunks/model.ts b/src/entries/chunks/model.ts index b26cab47f0..ce0112945e 100644 --- a/src/entries/chunks/model.ts +++ b/src/entries/chunks/model.ts @@ -41,7 +41,7 @@ function _slk(k: any, lh: any, rd: any) { if (!v) return; let index = v.indexOf(";"); if (index < 0) return; - if(!checkPrefix(v.substring(0, index))) return; + if (!checkPrefix(v.substring(0, index))) return; v = v.substring(index + 1); v.split(",").forEach(s => { let i = s.indexOf("="); @@ -51,17 +51,17 @@ function _slk(k: any, lh: any, rd: any) { }); } function checkPrefix(prefix: string): boolean { - if(!prefix) return true; + if (!prefix) return true; const s = "domains:"; const index = prefix.indexOf(s); - if(index < 0) return true; + if (index < 0) return true; const ds = prefix.substring(index + s.length).toLowerCase().split(","); - if(!Array.isArray(ds) || ds.length === 0) return true; - if(typeof window !== "undefined" && !!window.location && !!window.location.hostname) { + if (!Array.isArray(ds) || ds.length === 0) return true; + if (typeof window !== "undefined" && !!window.location && !!window.location.hostname) { const hn = window.location.hostname.toLowerCase(); ds.push("localhost"); - for(let i = 0; i < ds.length; i ++) { - if(hn.indexOf(ds[i]) > -1) return true; + for (let i = 0; i < ds.length; i++) { + if (hn.indexOf(ds[i]) > -1) return true; } return false; } @@ -215,7 +215,7 @@ export { SurveyTimer } from "../../surveytimer"; export { SurveyTimerModel } from "../../surveyTimerModel"; export * from "../../surveyToc"; export { SurveyProgressModel } from "../../surveyProgress"; -export { SurveyProgressButtonsModel } from "../../surveyProgressButtons"; +export { ProgressButtons, ProgressButtonsResponsivityManager, IProgressButtonsViewModel } from "../../progress-buttons"; export * from "../../themes"; export { SurveyModel } from "../../survey"; export * from "../../survey-events-api"; diff --git a/src/entries/react-ui-model.ts b/src/entries/react-ui-model.ts index 66e1464d48..01197bbdb6 100644 --- a/src/entries/react-ui-model.ts +++ b/src/entries/react-ui-model.ts @@ -63,9 +63,9 @@ export { SurveyQuestionMatrixDropdownCell, SurveyQuestionMatrixDropdownBase } fr export { SurveyQuestionMatrixDropdown } from "../react/reactquestion_matrixdropdown"; export { SurveyQuestionMatrixDynamic, SurveyQuestionMatrixDynamicAddButton } from "../react/reactquestion_matrixdynamic"; export { SurveyQuestionPanelDynamic } from "../react/reactquestion_paneldynamic"; -export { SurveyProgress } from "../react/reactSurveyProgress"; -export { SurveyProgressButtons } from "../react/reactSurveyProgressButtons"; -export { SurveyProgressToc } from "../react/reactSurveyProgressToc"; +export { SurveyProgress } from "../react/progress"; +export { SurveyProgressButtons } from "../react/progressButtons"; +export { SurveyProgressToc } from "../react/progressToc"; export { SurveyQuestionRating } from "../react/reactquestion_rating"; export { SurveyQuestionRatingDropdown } from "../react/rating-dropdown"; export { SurveyQuestionExpression } from "../react/reactquestion_expression"; diff --git a/src/entries/vue-ui-model.ts b/src/entries/vue-ui-model.ts index e29df9016f..5625db1894 100644 --- a/src/entries/vue-ui-model.ts +++ b/src/entries/vue-ui-model.ts @@ -54,7 +54,7 @@ export { PanelDynamic } from "../vue/paneldynamic.vue"; export { PanelDynamicProgress } from "../vue/paneldynamicprogress.vue"; export { PanelDynamicProgressV2 } from "../vue/paneldynamicprogressV2.vue"; export { Progress } from "../vue/progress.vue"; -export { ProgressButtons } from "../vue/progressButtons.vue"; +export { ProgressButtonsComponent } from "../vue/progressButtons.vue"; export { ProgressToc } from "../vue/progressToc.vue"; export { TimerPanel } from "../vue/timerpanel.vue"; export { Panel } from "../vue/panel.vue"; diff --git a/src/knockout/components/progress/buttons.html b/src/knockout/components/progress/buttons.html index 5708166087..99e9f984c8 100644 --- a/src/knockout/components/progress/buttons.html +++ b/src/knockout/components/progress/buttons.html @@ -1,14 +1,27 @@ -
+
+ +
+
+
+
    -
  • +
  • +
    +
    +
+ +
+
+
+
\ No newline at end of file diff --git a/src/knockout/components/progress/buttons.ts b/src/knockout/components/progress/buttons.ts index d908f838b1..91d67f5060 100644 --- a/src/knockout/components/progress/buttons.ts +++ b/src/knockout/components/progress/buttons.ts @@ -1,39 +1,29 @@ import * as ko from "knockout"; -import { SurveyModel, SurveyProgressButtonsModel } from "survey-core"; +import { ProgressButtons, ProgressButtonsResponsivityManager, IProgressButtonsViewModel } from "survey-core"; const template: any = require("html-loader?interpolate!val-loader!./buttons.html"); -export class ProgressButtonsViewModel { - private progressButtonsModel: SurveyProgressButtonsModel; - private scrollButtonCssKo: any = undefined; - private hasScroller: any = ko.observable(false); - private updateScroller: any = undefined; - constructor(private survey: SurveyModel, element: any) { - this.progressButtonsModel = new SurveyProgressButtonsModel(survey); - this.updateScroller = setInterval(() => { - const listContainerElement: HTMLElement = element.querySelector( - "." + survey.css.progressButtonsListContainer - ); - if (!!listContainerElement) { - this.hasScroller( - listContainerElement.scrollWidth > listContainerElement.offsetWidth - ); - } - }, 100); +export class ProgressButtonsViewModel implements IProgressButtonsViewModel { + private respManager: ProgressButtonsResponsivityManager; + private hasScroller = ko.observable(false); + public canShowHeader = ko.observable(false); + public canShowFooter = ko.observable(false); + public canShowItemTitles = ko.observable(true); + constructor(private model: ProgressButtons, private element: HTMLElement, public container: string = "center") { + this.respManager = new ProgressButtonsResponsivityManager(model, element, this); } - public isListElementClickable(index: any): boolean { - return this.progressButtonsModel.isListElementClickable(index()); + onResize(canShowItemTitles: boolean): void { + this.canShowItemTitles(canShowItemTitles); + this.canShowHeader(!this.canShowItemTitles()); } - public getListElementCss(index: any): string { - return this.progressButtonsModel.getListElementCss(index()); + onUpdateScroller(hasScroller: boolean): void { + this.hasScroller(hasScroller); } - public clickListElement(index: any): void { - this.progressButtonsModel.clickListElement(index()); + onUpdateSettings(): void { + this.canShowItemTitles(this.model.showItemTitles); + this.canShowFooter(!this.model.showItemTitles); } public getScrollButtonCss(isLeftScroll: boolean): any { - this.scrollButtonCssKo = ko.computed(() => { - return this.progressButtonsModel.getScrollButtonCss(this.hasScroller(), isLeftScroll); - }, this); - return this.scrollButtonCssKo; + return this.model.getScrollButtonCss(this.hasScroller(), isLeftScroll); } public clickScrollButton( listContainerElement: Element, @@ -42,14 +32,7 @@ export class ProgressButtonsViewModel { listContainerElement.scrollLeft += (isLeftScroll ? -1 : 1) * 70; } public dispose(): void { - if (typeof this.updateScroller !== "undefined") { - clearInterval(this.updateScroller); - this.updateScroller = undefined; - } - if (typeof this.scrollButtonCssKo !== "undefined") { - this.scrollButtonCssKo.dispose(); - this.scrollButtonCssKo = undefined; - } + this.respManager.dispose(); } } @@ -58,7 +41,8 @@ ko.components.register("sv-progress-buttons", { createViewModel: (params: any, componentInfo: any) => { return new ProgressButtonsViewModel( params.model, - componentInfo.element.nextElementSibling + componentInfo.element.nextElementSibling, + params.container ); }, }, diff --git a/src/page.ts b/src/page.ts index 1d8c2ea0a5..f45e7a000d 100644 --- a/src/page.ts +++ b/src/page.ts @@ -47,7 +47,7 @@ export class PageModel extends PanelModelBase implements IPage { return this.survey && (this.survey).showPageTitles; } /** - * A caption displayed on a navigation button in the TOC or progress bar. Applies when [`showTOC`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showTOC) is `true` or when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar) and [`progressBarType`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarType) is set to `"buttons"`. + * A caption displayed on a navigation button in the TOC or progress bar. Applies when [`showTOC`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showTOC) is `true` or when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar), [`progressBarType`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarType) is set to `"pages"`, and [`progressBarShowPageTitles`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarShowPageTitles) is `true`. * * If navigation titles are unspecified, the navigation buttons display page [titles](https://surveyjs.io/form-library/documentation/api-reference/page-model#title) or [names](https://surveyjs.io/form-library/documentation/pagemodel#name). */ @@ -61,7 +61,7 @@ export class PageModel extends PanelModelBase implements IPage { return this.getLocalizableString("navigationTitle"); } /** - * Explanatory text displayed under a navigation button in the progress bar. Applies when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar) and `SurveyModel`'s [`progressBarType`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarType) property is set to `"buttons"`. + * Explanatory text displayed under a navigation button in the progress bar. Applies when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar), `SurveyModel`'s [`progressBarType`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarType) is set to `"pages"`, and [`progressBarShowPageTitles`](https://surveyjs.io/form-library/documentation/surveymodel#progressBarShowPageTitles) is `true`. */ public get navigationDescription(): string { return this.getLocalizableStringText("navigationDescription"); diff --git a/src/progress-buttons.ts b/src/progress-buttons.ts new file mode 100644 index 0000000000..2871d6d4a3 --- /dev/null +++ b/src/progress-buttons.ts @@ -0,0 +1,172 @@ +import { Base, EventBase } from "./base"; +import { surveyCss } from "./defaultCss/defaultV2Css"; +import { PageModel } from "./page"; +import { SurveyModel } from "./survey"; +import { CssClassBuilder } from "./utils/cssClassBuilder"; + +export class ProgressButtons extends Base { + constructor(public survey: SurveyModel) { + super(); + } + public isListElementClickable(index: number | any): boolean { + if (!this.survey.onServerValidateQuestions || + (>this.survey.onServerValidateQuestions).isEmpty || + this.survey.checkErrorsMode === "onComplete") { + return true; + } + return index <= this.survey.currentPageNo + 1; + } + public getRootCss(container: string = "center"): string { + let result = this.survey.css.progressButtonsContainerCenter; + if (this.survey.css.progressButtonsRoot) { + result += " " + this.survey.css.progressButtonsRoot + " " + this.survey.css.progressButtonsRoot + "--" + (["footer", "contentBottom"].indexOf(container) !== -1 ? "bottom" : "top"); + result += " " + this.survey.css.progressButtonsRoot + "--" + (this.showItemTitles ? "with-titles" : "no-titles"); + } + if (this.showItemNumbers && this.survey.css.progressButtonsNumbered) { + result += " " + this.survey.css.progressButtonsNumbered; + } + return result; + } + public getListElementCss(index: number | any): string { + if (index >= this.survey.visiblePages.length) return; + return new CssClassBuilder() + .append(this.survey.css.progressButtonsListElementPassed, this.survey.visiblePages[index].passed) + .append(this.survey.css.progressButtonsListElementCurrent, this.survey.currentPageNo === index) + .append(this.survey.css.progressButtonsListElementNonClickable, !this.isListElementClickable(index)) + .toString(); + } + public getScrollButtonCss(hasScroller: boolean, isLeftScroll: boolean): string { + return new CssClassBuilder() + .append(this.survey.css.progressButtonsImageButtonLeft, isLeftScroll) + .append(this.survey.css.progressButtonsImageButtonRight, !isLeftScroll) + .append(this.survey.css.progressButtonsImageButtonHidden, !hasScroller) + .toString(); + } + public clickListElement(element: number | PageModel): void { + if (!(element instanceof PageModel)) { + element = this.survey.visiblePages[element]; + } + this.survey.tryNavigateToPage(element); + } + public isListContainerHasScroller(element: HTMLElement): boolean { + const listContainerElement: HTMLElement = element.querySelector("." + this.survey.css.progressButtonsListContainer); + if (!!listContainerElement) { + return listContainerElement.scrollWidth > listContainerElement.offsetWidth; + } + return false; + } + public isCanShowItemTitles(element: HTMLElement): boolean { + const listContainerElement = element.querySelector("ul"); + if (!listContainerElement || listContainerElement.children.length < 2) return true; + if (listContainerElement.clientWidth > listContainerElement.parentElement.clientWidth) { + return false; + } + const expectedElementWidth = listContainerElement.children[0].clientWidth; + for (let i = 0; i < listContainerElement.children.length; i++) { + if (Math.abs(listContainerElement.children[i].clientWidth - expectedElementWidth) > 5) { + return false; + } + } + return true; + } + public clearConnectorsWidth(element: HTMLElement): void { + const listContainerElements = element.querySelectorAll(".sd-progress-buttons__connector"); + for (let i = 0; i < listContainerElements.length; i++) { + (listContainerElements[i] as HTMLDivElement).style.width = ""; + } + } + public adjustConnectors(element: HTMLElement): void { + const listContainerElement = element.querySelector("ul"); + if (!listContainerElement) return; + const listContainerElements = element.querySelectorAll(".sd-progress-buttons__connector"); + const connectorWidth = listContainerElement.clientWidth / (listContainerElement.children.length - 1) - 4; + for (let i = 0; i < listContainerElements.length; i++) { + (listContainerElements[i] as HTMLDivElement).style.width = connectorWidth + "px"; + } + } + public get showItemNumbers(): boolean { + if (surveyCss.currentType !== "defaultV2") { + return false; + } + return this.survey.progressBarShowPageNumbers; + } + public get showItemTitles(): boolean { + if (surveyCss.currentType !== "defaultV2") { + return true; + } + return this.survey.progressBarShowPageTitles; + } + public getItemNumber(page: PageModel): string { + let result = ""; + if (this.showItemNumbers) { + result += this.survey.visiblePages.indexOf(page) + 1; + } + return result; + } + public get headerText(): string { + return this.survey.currentPage ? this.survey.currentPage.renderedNavigationTitle : ""; + } + public get footerText(): string { + return this.survey.progressText; + } + public onResize: EventBase = this.addEvent(); + public processResponsiveness(width: number): void { + this.onResize.fire(this, { width }); + } +} + +export interface IProgressButtonsViewModel { + container: string; + onResize(canShowItemTitles: boolean): void; + onUpdateScroller(hasScroller: boolean): void; + onUpdateSettings(): void; +} + +export class ProgressButtonsResponsivityManager { + private criticalProperties = ["progressBarType", "progressBarShowPageTitles"]; + private timer: any; + private prevWidth: number; + private canShowItemTitles = true; + constructor(private model: ProgressButtons, private element: HTMLElement, private viewModel: IProgressButtonsViewModel) { + this.model.survey.registerFunctionOnPropertiesValueChanged(this.criticalProperties, () => this.forceUpdate(), "ProgressButtonsResponsivityManager" + this.viewModel.container); + this.model.onResize.add(this.processResponsiveness); + this.forceUpdate(); + } + private forceUpdate() { + this.viewModel.onUpdateSettings(); + this.processResponsiveness(this.model, {} as any); + } + private processResponsiveness = (model: ProgressButtons, options: { width: number }) => { + this.viewModel.onUpdateScroller(model.isListContainerHasScroller(this.element)); + if (!model.showItemTitles) { + this.model.adjustConnectors(this.element); + return; + } + if (model.survey.isMobile) { + this.prevWidth = options.width; + this.canShowItemTitles = false; + this.model.adjustConnectors(this.element); + this.viewModel.onResize(this.canShowItemTitles); + return; + } + this.model.clearConnectorsWidth(this.element); + if (this.timer !== undefined) { + clearTimeout(this.timer); + } + this.timer = setTimeout(() => { + if (this.prevWidth === undefined || this.prevWidth < options.width && !this.canShowItemTitles || this.prevWidth > options.width && this.canShowItemTitles) { + this.prevWidth = options.width; + this.canShowItemTitles = model.isCanShowItemTitles(this.element); + this.viewModel.onResize(this.canShowItemTitles); + this.timer = undefined; + } + }, 10); + } + dispose(): void { + clearTimeout(this.timer); + this.model.onResize.remove(this.processResponsiveness); + this.model.survey.unRegisterFunctionOnPropertiesValueChanged(this.criticalProperties, "ProgressButtonsResponsivityManager" + this.viewModel.container); + this.element = undefined; + this.model = undefined; + } +} \ No newline at end of file diff --git a/src/react/reactSurveyProgress.tsx b/src/react/progress.tsx similarity index 100% rename from src/react/reactSurveyProgress.tsx rename to src/react/progress.tsx diff --git a/src/react/progressButtons.tsx b/src/react/progressButtons.tsx new file mode 100644 index 0000000000..fe0decc904 --- /dev/null +++ b/src/react/progressButtons.tsx @@ -0,0 +1,125 @@ +import * as React from "react"; +import { ProgressButtons, PageModel, ProgressButtonsResponsivityManager, IProgressButtonsViewModel } from "survey-core"; +import { SurveyNavigationBase } from "./reactSurveyNavigationBase"; +import { ReactElementFactory } from "./element-factory"; + +export class SurveyProgressButtons extends SurveyNavigationBase implements IProgressButtonsViewModel { + private respManager: ProgressButtonsResponsivityManager; + private listContainerRef: React.RefObject; + constructor(props: any) { + super(props); + this.listContainerRef = React.createRef(); + } + protected get model(): ProgressButtons { + return this.props.model; + } + get container(): string { + return this.props.container; + } + onResize(canShowItemTitles: boolean): void { + this.setState({ canShowItemTitles }); + this.setState({ canShowHeader: !canShowItemTitles }); + } + onUpdateScroller(hasScroller: boolean): void { + this.setState({ hasScroller }); + } + onUpdateSettings(): void { + this.setState({ canShowItemTitles: this.model.showItemTitles }); + this.setState({ canShowFooter: !this.model.showItemTitles }); + } + render(): JSX.Element { + return ( +
+ {this.state.canShowHeader ?
+
{this.model.headerText}
+
: null} +
+
+ this.clickScrollButton(this.listContainerRef.current, true) + } + >
+
+
    + {this.getListElements()} +
+
+
+ this.clickScrollButton(this.listContainerRef.current, false) + } + >
+
+ {this.state.canShowFooter ?
+
{this.model.footerText}
+
: null} +
+ ); + } + protected getListElements(): JSX.Element[] { + let buttons: JSX.Element[] = []; + this.survey.visiblePages.forEach((page: PageModel, index: number) => { + buttons.push(this.renderListElement(page, index)); + }); + return buttons; + } + protected renderListElement(page: PageModel, index: number): JSX.Element { + return ( +
  • this.model.clickListElement(page) + : undefined + } + data-page-number={this.model.getItemNumber(page)} + > +
    + {this.state.canShowItemTitles ? <> +
    + {page.renderedNavigationTitle} +
    +
    + {page.navigationDescription} +
    + : null} +
  • + ); + } + protected clickScrollButton( + listContainerElement: Element | null, + isLeftScroll: boolean + ): void { + if (!!listContainerElement) { + listContainerElement.scrollLeft += (isLeftScroll ? -1 : 1) * 70; + } + } + componentDidMount() { + super.componentDidMount(); + setTimeout(() => { + this.respManager = new ProgressButtonsResponsivityManager(this.model, this.listContainerRef.current as any, this); + }, 10); + } + componentWillUnmount() { + this.respManager.dispose(); + super.componentWillUnmount(); + } +} + +ReactElementFactory.Instance.registerElement("sv-progress-buttons", (props) => { + return React.createElement(SurveyProgressButtons, props); +}); diff --git a/src/react/reactSurveyProgressToc.tsx b/src/react/progressToc.tsx similarity index 87% rename from src/react/reactSurveyProgressToc.tsx rename to src/react/progressToc.tsx index a41076fd18..1c6d357f36 100644 --- a/src/react/reactSurveyProgressToc.tsx +++ b/src/react/progressToc.tsx @@ -10,10 +10,10 @@ export class SurveyProgressToc extends SurveyNavigationBase { render(): JSX.Element { const tocModel = this.props.model; let content: JSX.Element; - if(tocModel.isMobile) { + if (tocModel.isMobile) { content =
    - - + +
    ; } else { content = ; diff --git a/src/react/reactSurveyProgressButtons.tsx b/src/react/reactSurveyProgressButtons.tsx deleted file mode 100644 index 30bf6d39c9..0000000000 --- a/src/react/reactSurveyProgressButtons.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import * as React from "react"; -import { SurveyProgressButtonsModel, PageModel } from "survey-core"; -import { SurveyNavigationBase } from "./reactSurveyNavigationBase"; -import { ReactElementFactory } from "./element-factory"; - -export class SurveyProgressButtons extends SurveyNavigationBase { - private progressButtonsModel: SurveyProgressButtonsModel; - private updateScroller: any = undefined; - private listContainerRef: React.RefObject; - constructor(props: any) { - super(props); - this.progressButtonsModel = new SurveyProgressButtonsModel(this.survey); - this.listContainerRef = React.createRef(); - } - render(): JSX.Element { - return ( -
    -
    -
    - this.clickScrollButton(this.listContainerRef.current, true) - } - >
    -
    -
      - {this.getListElements()} -
    -
    -
    - this.clickScrollButton(this.listContainerRef.current, false) - } - >
    -
    -
    - ); - } - protected getListElements(): JSX.Element[] { - let buttons: JSX.Element[] = []; - this.survey.visiblePages.forEach((page: PageModel, index: number) => { - buttons.push(this.renderListElement(page, index)); - }); - return buttons; - } - protected renderListElement(page: PageModel, index: number): JSX.Element { - return ( -
  • this.clickListElement(index) - : undefined - } - > -
    - {page.renderedNavigationTitle} -
    -
    - {page.navigationDescription} -
    -
  • - ); - } - protected isListElementClickable(index: number): boolean { - return this.progressButtonsModel.isListElementClickable(index); - } - protected getListElementCss(index: number): string { - return this.progressButtonsModel.getListElementCss(index); - } - protected clickListElement(index: number): void { - this.progressButtonsModel.clickListElement(index); - } - protected getScrollButtonCss(isLeftScroll: boolean): string { - return this.progressButtonsModel.getScrollButtonCss(this.state.hasScroller, isLeftScroll); - } - protected clickScrollButton( - listContainerElement: Element | null, - isLeftScroll: boolean - ): void { - if(!!listContainerElement) { - listContainerElement.scrollLeft += (isLeftScroll ? -1 : 1) * 70; - } - } - componentDidMount() { - this.updateScroller = setInterval(() => { - if(!!this.listContainerRef.current) { - this.setState({ hasScroller: this.listContainerRef.current.scrollWidth > this.listContainerRef.current.offsetWidth, }); - } - }, 100); - } - componentWillUnmount() { - if (typeof this.updateScroller !== "undefined") { - clearInterval(this.updateScroller); - this.updateScroller = undefined; - } - } -} - -ReactElementFactory.Instance.registerElement("sv-progress-buttons", (props) => { - return React.createElement(SurveyProgressButtons, props); -}); diff --git a/src/settings.ts b/src/settings.ts index 817bc044fe..4a1940a640 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -129,7 +129,7 @@ export var settings = { * ``` */ web: { - onBeforeRequestChoices: (sender: any, options: { request: XMLHttpRequest }): void => {}, + onBeforeRequestChoices: (sender: any, options: { request: XMLHttpRequest }): void => { }, encodeUrlParams: true, cacheLoadedChoices: true, disableQuestionWhileLoadingChoices: false, @@ -691,5 +691,6 @@ export var settings = { "email", "impp", ] - } + }, + legacyProgressBarView: false }; \ No newline at end of file diff --git a/src/survey.ts b/src/survey.ts index 4285ddd33f..63d1ae615b 100644 --- a/src/survey.ts +++ b/src/survey.ts @@ -76,6 +76,7 @@ import { Cover } from "./header"; import { surveyTimerFunctions } from "./surveytimer"; import { QuestionSignaturePadModel } from "./question_signaturepad"; import { SurveyTaskManagerModel } from "./surveyTaskManager"; +import { ProgressButtons } from "./progress-buttons"; import { TOCModel } from "./surveyToc"; /** @@ -972,6 +973,8 @@ export class SurveyModel extends SurveyElementCore } }); + this.progressBarValue = new ProgressButtons(this); + this.layoutElements.push({ id: "timerpanel", template: "survey-timerpanel", @@ -981,7 +984,8 @@ export class SurveyModel extends SurveyElementCore this.layoutElements.push({ id: "progress-buttons", component: "sv-progress-buttons", - data: this + data: this.progressBar, + processResponsiveness: width => this.progressBar.processResponsiveness && this.progressBar.processResponsiveness(width) }); this.layoutElements.push({ id: "progress-questions", @@ -1009,7 +1013,7 @@ export class SurveyModel extends SurveyElementCore data: new TOCModel(this) }); this.layoutElements.push({ - id: "navigationbuttons", + id: "buttons-navigation", component: "sv-action-bar", data: this.navigationBar }); @@ -1870,7 +1874,7 @@ export class SurveyModel extends SurveyElementCore return this.locale; } public locStrsChanged(): void { - if(this.isClearingUnsedValues) return; + if (this.isClearingUnsedValues) return; super.locStrsChanged(); if (!this.currentPage) return; if (this.isDesignMode) { @@ -2588,15 +2592,23 @@ export class SurveyModel extends SurveyElementCore this.setPropertyValue("showQuestionNumbers", value); this.updateVisibleIndexes(); } + private progressBarValue: any; + public get progressBar(): any { + return this.progressBarValue; + } /** * Controls the visibility of the progress bar and specifies its position. * * Possible values: * * - `"off"` (default) - Hides the progress bar. - * - `"top"` - Displays the progress bar above survey content. + * - `"aboveHeader"` - Displays the progress bar above the survey header. + * - `"belowHeader"` - Displays the progress bar below the survey header. * - `"bottom"` - Displays the progress bar below survey content. - * - `"both"` - Displays the progress bar above and below survey content. + * - `"topBottom"` - Displays the progress bar above and below survey content. + * - `"auto"` - Automatically selects between `"aboveHeader"` and `"belowHeader"`. + * - `"top"` - *(Obsolete)* Use the `"aboveHeader"` or `"belowHeader"` property value instead. + * - `"both"` - *(Obsolete)* Use the `"topBottom"` property value instead. * * [View Demo](https://surveyjs.io/form-library/examples/navigation-default/ (linkStyle)) * @see progressBarType @@ -2617,7 +2629,9 @@ export class SurveyModel extends SurveyElementCore * - `"questions"` - The number of answered questions. * - `"requiredQuestions"` - The number of answered [required questions](https://surveyjs.io/form-library/documentation/api-reference/question#isRequired). * - `"correctQuestions"` - The number of correct questions in a [quiz](https://surveyjs.io/form-library/documentation/design-survey/create-a-quiz). - * - `"buttons"` - Adds jump links to the progress bar. + * - `"buttons"` - *(Obsolete)* Use the `"pages"` property value with the [`progressBarShowPageTitles`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarShowPageTitles) property set to `true` instead. + * + * > When `progressBarType` is set to `"pages"`, you can also enable the [`progressBarShowPageNumbers`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarShowPageNumbers) and [`progressBarShowPageTitles`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarShowPageTitles) properties if you want to display page numbers and titles in the progress bar. * * [View Demo](https://surveyjs.io/form-library/examples/navigation-buttons/ (linkStyle)) * @see progressValue @@ -2628,15 +2642,46 @@ export class SurveyModel extends SurveyElementCore public set progressBarType(newValue: string) { if (newValue === "correctquestion") newValue = "correctQuestion"; if (newValue === "requiredquestion") newValue = "requiredQuestion"; + // if (newValue === "buttons") { + // newValue = "pages"; + // this.progressBarShowPageTitles = true; + // } this.setPropertyValue("progressBarType", newValue); } + private get progressBarComponentName(): string { + let actualProgressBarType = this.progressBarType; + if (!settings.legacyProgressBarView && surveyCss.currentType === "defaultV2") { + if (isStrCiEqual(actualProgressBarType, "pages")) { + actualProgressBarType = "buttons"; + } + } + return "progress-" + actualProgressBarType; + } + /** + * Specifies whether the progress bar displays page titles. Applies only when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar) and [`progressBarType`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarType) is `"pages"`. + * + * Default value: `false` + * @see progressBarShowPageNumbers + */ + @property({ + getDefaultValue: (self: SurveyModel) => { + return self.progressBarType === "buttons"; + }, + }) progressBarShowPageTitles: boolean; + /** + * Specifies whether the progress bar displays page numbers. Applies only when the [progress bar is visible](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#showProgressBar) and [`progressBarType`](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#progressBarType) is `"pages"`. + * + * Default value: `false` + * @see progressBarShowPageTitles + */ + @property() progressBarShowPageNumbers: boolean; public get isShowProgressBarOnTop(): boolean { if (!this.canShowProresBar()) return false; - return this.showProgressBar === "top" || this.showProgressBar === "both"; + return ["auto", "aboveheader", "belowheader", "topbottom", "top", "both"].indexOf(this.showProgressBar) !== -1; } public get isShowProgressBarOnBottom(): boolean { if (!this.canShowProresBar()) return false; - return this.showProgressBar === "bottom" || this.showProgressBar === "both"; + return this.showProgressBar === "bottom" || this.showProgressBar === "both" || this.showProgressBar === "topbottom"; } public getProgressTypeComponent(): string { return "sv-progress-" + this.progressBarType.toLowerCase(); @@ -7383,7 +7428,7 @@ export class SurveyModel extends SurveyElementCore * * This method accepts an object with the following layout element properties: * - * - `id`: `string` | `"timerpanel"` | `"progress-buttons"` | `"progress-questions"` | `"progress-pages"` | `"progress-correctquestions"` | `"progress-requiredquestions"` | `"toc-navigation"` | `"navigationbuttons"`\ + * - `id`: `string` | `"timerpanel"` | `"progress-buttons"` | `"progress-questions"` | `"progress-pages"` | `"progress-correctquestions"` | `"progress-requiredquestions"` | `"toc-navigation"` | `"buttons-navigation"`\ * A layout element identifier. You can use possible values to access and relocate or customize predefined layout elements. * * - `container`: `"header"` | `"footer"` | `"left"` | `"right"` | `"contentTop"` | `"contentBottom"`\ @@ -7431,10 +7476,13 @@ export class SurveyModel extends SurveyElementCore containerLayoutElements.push(layoutElement); } } - } else if (this.state === "running" && isStrCiEqual(layoutElement.id, "progress-" + this.progressBarType)) { + } else if (this.state === "running" && isStrCiEqual(layoutElement.id, this.progressBarComponentName)) { const headerLayoutElement = this.findLayoutElement("advanced-header"); const advHeader = headerLayoutElement && headerLayoutElement.data as Cover; let isBelowHeader = !advHeader || advHeader.hasBackground; + if (isStrCiEqual(this.showProgressBar, "aboveHeader")) { + isBelowHeader = false; + } if (container === "header" && !isBelowHeader) { layoutElement.index = -150; if (this.isShowProgressBarOnTop && !this.isShowStartingPage) { @@ -7454,7 +7502,7 @@ export class SurveyModel extends SurveyElementCore containerLayoutElements.push(layoutElement); } } - } else if (isStrCiEqual(layoutElement.id, "navigationbuttons")) { + } else if (isStrCiEqual(layoutElement.id, "buttons-navigation")) { if (container === "contentTop") { if (["top", "both"].indexOf(this.isNavigationButtonsShowing) !== -1) { containerLayoutElements.push(layoutElement); @@ -7706,7 +7754,7 @@ Serializer.addClass("survey", [ { name: "showProgressBar", default: "off", - choices: ["off", "top", "bottom", "both"], + choices: ["off", "auto", "aboveHeader", "belowHeader", "bottom", "topBottom"], }, { name: "progressBarType", @@ -7716,9 +7764,10 @@ Serializer.addClass("survey", [ "questions", "requiredQuestions", "correctQuestions", - "buttons", ], }, + { name: "progressBarShowPageTitles:switch" }, + { name: "progressBarShowPageNumbers:switch", default: false }, { name: "showTOC:switch", default: false diff --git a/src/surveyProgressButtons.ts b/src/surveyProgressButtons.ts deleted file mode 100644 index d1876936b2..0000000000 --- a/src/surveyProgressButtons.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { EventBase } from "./base"; -import { SurveyModel } from "./survey"; -import { CssClassBuilder } from "./utils/cssClassBuilder"; - -export class SurveyProgressButtonsModel { - constructor(private survey: SurveyModel) { - } - public isListElementClickable(index: number): boolean { - if (!this.survey.onServerValidateQuestions || - (>this.survey.onServerValidateQuestions).isEmpty || - this.survey.checkErrorsMode === "onComplete") { - return true; - } - return index <= this.survey.currentPageNo + 1; - } - public getListElementCss(index: number): string { - if (index >= this.survey.visiblePages.length) return; - return new CssClassBuilder() - .append(this.survey.css.progressButtonsListElementPassed, this.survey.visiblePages[index].passed) - .append(this.survey.css.progressButtonsListElementCurrent, this.survey.currentPageNo === index) - .append(this.survey.css.progressButtonsListElementNonClickable, !this.isListElementClickable(index)) - .toString(); - } - public getScrollButtonCss(hasScroller: boolean, isLeftScroll: boolean): string { - return new CssClassBuilder() - .append(this.survey.css.progressButtonsImageButtonLeft, isLeftScroll) - .append(this.survey.css.progressButtonsImageButtonRight, !isLeftScroll) - .append(this.survey.css.progressButtonsImageButtonHidden, !hasScroller) - .toString(); - } - public clickListElement(index: number): void { - this.survey.tryNavigateToPage(this.survey.visiblePages[index]); - } -} diff --git a/src/vue/progressButtons.vue b/src/vue/progressButtons.vue index 7315281c6a..0ab698c96a 100644 --- a/src/vue/progressButtons.vue +++ b/src/vue/progressButtons.vue @@ -1,8 +1,11 @@ diff --git a/tests/ko/survey_kotests.ts b/tests/ko/survey_kotests.ts index be97b57a0f..fad8c71242 100644 --- a/tests/ko/survey_kotests.ts +++ b/tests/ko/survey_kotests.ts @@ -25,6 +25,7 @@ import * as ko from "knockout"; import { ItemValue } from "../../src/itemvalue"; import { StylesManager } from "../../src/stylesmanager"; import { settings } from "../../src/settings"; +import { ProgressButtons } from "../../src/progress-buttons"; export default QUnit.module("koTests"); @@ -1899,23 +1900,26 @@ QUnit.test("ProgressButtonsViewModel component scroll button", function ( StylesManager.applyTheme("default"); let survey: Survey = new Survey(json); let progress: ProgressButtonsViewModel = new ProgressButtonsViewModel( - survey, + new ProgressButtons(survey as any), { querySelector: function () { return undefined; }, - } + querySelectorAll: function () { + return [] as any; + }, + } as any ); progress.dispose(); assert.equal( - progress.getScrollButtonCss(true)(), + progress.getScrollButtonCss(true), survey.css.progressButtonsImageButtonLeft + " " + survey.css.progressButtonsImageButtonHidden, "1) Scroll button left style is hidden" ); assert.equal( - progress.getScrollButtonCss(false)(), + progress.getScrollButtonCss(false), survey.css.progressButtonsImageButtonRight + " " + survey.css.progressButtonsImageButtonHidden, @@ -1924,12 +1928,12 @@ QUnit.test("ProgressButtonsViewModel component scroll button", function ( progress["hasScroller"](true); assert.equal( - progress.getScrollButtonCss(true)(), + progress.getScrollButtonCss(true), survey.css.progressButtonsImageButtonLeft, "2) Scroll button left style is visible" ); assert.equal( - progress.getScrollButtonCss(false)(), + progress.getScrollButtonCss(false), survey.css.progressButtonsImageButtonRight, "2) Scroll button right style is visible" ); diff --git a/tests/surveyProgressButtonsTest.ts b/tests/surveyProgressButtonsTest.ts index a8fc6a745a..803521344c 100644 --- a/tests/surveyProgressButtonsTest.ts +++ b/tests/surveyProgressButtonsTest.ts @@ -1,9 +1,9 @@ import { SurveyModel } from "../src/survey"; -import { SurveyProgressButtonsModel } from "../src/surveyProgressButtons"; +import { ProgressButtons } from "../src/progress-buttons"; -export default QUnit.module("SurveyProgressButtons"); +export default QUnit.module("ProgressButtons"); -QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { +QUnit.test("ProgressButtons list elements", function (assert) { const json: any = { "pages": [ { @@ -36,7 +36,7 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { ] }; const survey: SurveyModel = new SurveyModel(json); - const progress: SurveyProgressButtonsModel = new SurveyProgressButtonsModel(survey); + const progress: ProgressButtons = new ProgressButtons(survey); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementCurrent, "1) Page 1 style is current"); @@ -61,7 +61,7 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { assert.equal(survey.currentPageNo, 0, "currentPageNo #2"); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementPassed + " " + - survey.css.progressButtonsListElementCurrent, + survey.css.progressButtonsListElementCurrent, "3) Page 1 style is passed and current"); assert.equal(progress.getListElementCss(1), survey.css.progressButtonsListElementPassed, @@ -69,7 +69,7 @@ QUnit.test("SurveyProgressButtonsModel list elements", function(assert) { assert.equal(progress.getListElementCss(2), "", "3) Page 3 style is empty"); }); -QUnit.test("SurveyProgressButtonsModel list elements non clickable", function(assert) { +QUnit.test("ProgressButtons list elements non clickable", function (assert) { let json: any = { "pages": [ { @@ -103,7 +103,7 @@ QUnit.test("SurveyProgressButtonsModel list elements non clickable", function(as }; let survey: SurveyModel = new SurveyModel(json); survey.onServerValidateQuestions.add((_: any, options: any) => options.complete()); - let progress: SurveyProgressButtonsModel = new SurveyProgressButtonsModel(survey); + let progress: ProgressButtons = new ProgressButtons(survey); assert.equal(progress.getListElementCss(0), survey.css.progressButtonsListElementCurrent, "1) Page 1 style is current"); diff --git a/tests/surveytests.ts b/tests/surveytests.ts index f8ec6815fa..c065ab38d0 100644 --- a/tests/surveytests.ts +++ b/tests/surveytests.ts @@ -16964,7 +16964,7 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "default contentBottom"); assert.deepEqual(getContainerContent("left"), [], "default left"); assert.deepEqual(getContainerContent("right"), [], "default right"); @@ -16974,7 +16974,7 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("footer"), [], "nav top footer"); assert.deepEqual(getContainerContent("contentTop"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav top contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [], "nav top contentBottom"); assert.deepEqual(getContainerContent("left"), [], "nav top left"); @@ -16985,11 +16985,11 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("footer"), [], "nav both footer"); assert.deepEqual(getContainerContent("contentTop"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav both contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav both contentBottom"); assert.deepEqual(getContainerContent("left"), [], "nav both left"); assert.deepEqual(getContainerContent("right"), [], "nav both right"); @@ -16999,11 +16999,11 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("footer"), [], "nav left footer"); assert.deepEqual(getContainerContent("contentTop"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav left contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav left contentBottom"); assert.deepEqual(getContainerContent("left"), [{ "component": "sv-navigation-toc", @@ -17016,11 +17016,11 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("footer"), [], "nav right footer"); assert.deepEqual(getContainerContent("contentTop"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav right contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "nav right contentBottom"); assert.deepEqual(getContainerContent("left"), [], "nav right left"); assert.deepEqual(getContainerContent("right"), [{ @@ -17039,7 +17039,166 @@ QUnit.test("getContainerContent - navigation", function (assert) { assert.deepEqual(getContainerContent("right"), [], "nav none right"); }); +QUnit.test("getContainerContent - progress (legacyProgressBarView)", function (assert) { + const json = { + showNavigationButtons: "none", + pages: [ + { + "elements": [ + { + required: true, + "type": "rating", + "name": "satisfaction", + }, + { + required: true, + "type": "rating", + "name": "recommend friends", + } + ] + }, + { + "elements": [ + { + "type": "radiogroup", + "name": "price to competitors", + }, + { + "type": "radiogroup", + "name": "price", + }, + ] + }, + ] + }; + + try { + settings.legacyProgressBarView = true; + + let survey = new SurveyModel(json); + const getContainerContent = getContainerContentFunction(survey); + + assert.equal(survey.showNavigationButtons, "none"); + assert.equal(survey.progressBarType, "pages"); + assert.equal(survey.showProgressBar, "off"); + + assert.deepEqual(getContainerContent("header"), [], "default header"); + assert.deepEqual(getContainerContent("footer"), [], "default footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "default contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "default left"); + assert.deepEqual(getContainerContent("right"), [], "default right"); + + survey.showProgressBar = "top"; + assert.deepEqual(getContainerContent("header"), [], "progress top header"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-pages", + "id": "progress-pages" + }], "progress top center"); + assert.deepEqual(getContainerContent("footer"), [], "progress top footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress top contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress top contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress top left"); + assert.deepEqual(getContainerContent("right"), [], "progress top right"); + + survey.showProgressBar = "bottom"; + assert.deepEqual(getContainerContent("header"), [], "progress bottom header"); + assert.deepEqual(getContainerContent("footer"), [{ + "component": "sv-progress-pages", + "id": "progress-pages" + }], "progress bottom footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress bottom contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress bottom contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress bottom left"); + assert.deepEqual(getContainerContent("right"), [], "progress bottom right"); + + survey.showProgressBar = "both"; + assert.deepEqual(getContainerContent("header"), [], "progress both header"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-pages", + "id": "progress-pages" + }], "progress both center"); + assert.deepEqual(getContainerContent("footer"), [{ + "component": "sv-progress-pages", + "id": "progress-pages" + }], "progress both footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress both contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress both contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress both left"); + assert.deepEqual(getContainerContent("right"), [], "progress both right"); + + survey.progressBarType = "questions"; + assert.deepEqual(getContainerContent("header"), [], "progress questions both header"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-questions", + "id": "progress-questions" + }], "progress questions both header"); + assert.deepEqual(getContainerContent("footer"), [{ + "component": "sv-progress-questions", + "id": "progress-questions" + }], "progress questions both footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress questions both contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress questions both contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress questions both left"); + assert.deepEqual(getContainerContent("right"), [], "progress questions both right"); + + survey.showTOC = true; + assert.deepEqual(getContainerContent("header"), [], "progress toc both header"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-questions", + "id": "progress-questions" + }], "progress toc both center"); + assert.deepEqual(getContainerContent("footer"), [{ + "component": "sv-progress-questions", + "id": "progress-questions" + }], "progress toc both footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress toc both contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress toc both contentBottom"); + assert.deepEqual(getContainerContent("left"), [{ + "component": "sv-navigation-toc", + "id": "toc-navigation" + }], "progress toc both left"); + assert.deepEqual(getContainerContent("right"), [], "progress toc both right"); + + survey.showProgressBar = "off"; + survey.tocLocation = "left"; + assert.deepEqual(getContainerContent("header"), [], "progress toc left header"); + assert.deepEqual(getContainerContent("footer"), [], "progress toc left footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress toc left contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress toc left contentBottom"); + assert.deepEqual(getContainerContent("left"), [{ + "component": "sv-navigation-toc", + "id": "toc-navigation" + }], "progress toc left left"); + assert.deepEqual(getContainerContent("right"), [], "progress toc left right"); + + survey.tocLocation = "right"; + assert.deepEqual(getContainerContent("header"), [], "progress toc right header"); + assert.deepEqual(getContainerContent("footer"), [], "progress toc right footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress toc right contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress toc right contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress toc right left"); + assert.deepEqual(getContainerContent("right"), [{ + "component": "sv-navigation-toc", + "id": "toc-navigation" + }], "progress toc right right"); + + survey.showTOC = false; + assert.deepEqual(getContainerContent("header"), [], "default header"); + assert.deepEqual(getContainerContent("footer"), [], "default footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "default contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "default left"); + assert.deepEqual(getContainerContent("right"), [], "default right"); + + } + finally { + settings.legacyProgressBarView = false; + } +}); + QUnit.test("getContainerContent - progress", function (assert) { + surveyCss.currentType = "defaultV2"; const json = { showNavigationButtons: "none", pages: [ @@ -17073,11 +17232,7 @@ QUnit.test("getContainerContent - progress", function (assert) { }; let survey = new SurveyModel(json); - function getContainerContent(container: LayoutElementContainer) { - let result = survey.getContainerContent(container); - result.forEach(item => delete item["data"]); - return result; - } + const getContainerContent = getContainerContentFunction(survey); assert.equal(survey.showNavigationButtons, "none"); assert.equal(survey.progressBarType, "pages"); @@ -17093,8 +17248,8 @@ QUnit.test("getContainerContent - progress", function (assert) { survey.showProgressBar = "top"; assert.deepEqual(getContainerContent("header"), [], "progress top header"); assert.deepEqual(getContainerContent("center"), [{ - "component": "sv-progress-pages", - "id": "progress-pages" + "component": "sv-progress-buttons", + "id": "progress-buttons" }], "progress top center"); assert.deepEqual(getContainerContent("footer"), [], "progress top footer"); assert.deepEqual(getContainerContent("contentTop"), [], "progress top contentTop"); @@ -17105,8 +17260,8 @@ QUnit.test("getContainerContent - progress", function (assert) { survey.showProgressBar = "bottom"; assert.deepEqual(getContainerContent("header"), [], "progress bottom header"); assert.deepEqual(getContainerContent("footer"), [{ - "component": "sv-progress-pages", - "id": "progress-pages" + "component": "sv-progress-buttons", + "id": "progress-buttons" }], "progress bottom footer"); assert.deepEqual(getContainerContent("contentTop"), [], "progress bottom contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [], "progress bottom contentBottom"); @@ -17116,12 +17271,12 @@ QUnit.test("getContainerContent - progress", function (assert) { survey.showProgressBar = "both"; assert.deepEqual(getContainerContent("header"), [], "progress both header"); assert.deepEqual(getContainerContent("center"), [{ - "component": "sv-progress-pages", - "id": "progress-pages" + "component": "sv-progress-buttons", + "id": "progress-buttons" }], "progress both center"); assert.deepEqual(getContainerContent("footer"), [{ - "component": "sv-progress-pages", - "id": "progress-pages" + "component": "sv-progress-buttons", + "id": "progress-buttons" }], "progress both footer"); assert.deepEqual(getContainerContent("contentTop"), [], "progress both contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [], "progress both contentBottom"); @@ -17229,7 +17384,7 @@ QUnit.test("getContainerContent - do not show TOC on preview", function (assert) assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [{ "component": "sv-navigation-toc", @@ -17245,7 +17400,7 @@ QUnit.test("getContainerContent - do not show TOC on preview", function (assert) assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], "do not show toc left"); assert.deepEqual(getContainerContent("right"), [], ""); @@ -17295,7 +17450,7 @@ QUnit.test("getContainerContent - do not show TOC on start page", function (asse assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], "empty on the start page"); @@ -17305,7 +17460,7 @@ QUnit.test("getContainerContent - do not show TOC on start page", function (asse assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [{ "component": "sv-navigation-toc", @@ -17347,11 +17502,7 @@ QUnit.test("getContainerContent - do not show buttons progress on completed page }; let survey = new SurveyModel(json); - function getContainerContent(container: LayoutElementContainer) { - let result = survey.getContainerContent(container); - result.forEach(item => delete item["data"]); - return result; - } + const getContainerContent = getContainerContentFunction(survey); assert.deepEqual(getContainerContent("header"), [], ""); assert.deepEqual(getContainerContent("footer"), [], ""); @@ -17362,7 +17513,7 @@ QUnit.test("getContainerContent - do not show buttons progress on completed page assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], ""); assert.deepEqual(getContainerContent("right"), [], ""); @@ -17374,7 +17525,7 @@ QUnit.test("getContainerContent - do not show buttons progress on completed page assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], ""); assert.deepEqual(getContainerContent("right"), [], ""); @@ -17414,7 +17565,7 @@ QUnit.test("getContainerContent - do not advanced header on completed page", fun assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], ""); assert.deepEqual(getContainerContent("right"), [], ""); @@ -17426,7 +17577,7 @@ QUnit.test("getContainerContent - do not advanced header on completed page", fun assert.deepEqual(getContainerContent("contentTop"), [], ""); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], ""); assert.deepEqual(getContainerContent("left"), [], ""); assert.deepEqual(getContainerContent("right"), [], ""); @@ -17713,7 +17864,7 @@ QUnit.test("getContainerContent - navigation with page.navigationButtonsVisibili assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "default contentBottom"); assert.deepEqual(getContainerContent("left"), [], "default left"); assert.deepEqual(getContainerContent("right"), [], "default right"); @@ -17724,7 +17875,7 @@ QUnit.test("getContainerContent - navigation with page.navigationButtonsVisibili assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "default contentBottom"); assert.deepEqual(getContainerContent("left"), [], "default left"); assert.deepEqual(getContainerContent("right"), [], "default right"); @@ -18529,7 +18680,113 @@ QUnit.test("emptySurveyText, make it writable, #7456", function (assert) { assert.equal(survey.emptySurveyText, defaultText, "#3"); }); +QUnit.test("getContainerContent - progress + advanced header (legacyProgressBarView)", function (assert) { + const json = { + title: "My Survey", + showNavigationButtons: "none", + pages: [ + { + "elements": [ + { + required: true, + "type": "rating", + "name": "satisfaction", + }, + { + required: true, + "type": "rating", + "name": "recommend friends", + } + ] + }, + { + "elements": [ + { + "type": "radiogroup", + "name": "price to competitors", + }, + { + "type": "radiogroup", + "name": "price", + }, + ] + }, + ] + }; + + try { + settings.legacyProgressBarView = true; + + let survey = new SurveyModel(json); + survey.headerView = "advanced"; + const getContainerContent = getContainerContentFunction(survey); + + assert.equal(survey.showNavigationButtons, "none"); + assert.equal(survey.progressBarType, "pages"); + assert.equal(survey.showProgressBar, "off"); + + assert.deepEqual(getContainerContent("header"), [{ + "component": "sv-header", + "container": "header", + "id": "advanced-header", + "index": -100 + }], "default header"); + assert.deepEqual(getContainerContent("center"), [], "default center"); + assert.deepEqual(getContainerContent("footer"), [], "default footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "default contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "default left"); + assert.deepEqual(getContainerContent("right"), [], "default right"); + + survey.showProgressBar = "top"; + assert.deepEqual(getContainerContent("header"), [{ + "component": "sv-header", + "container": "header", + "id": "advanced-header", + "index": -100 + }], "progress top header alone"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-pages", + "id": "progress-pages" + }], "progress top center alone"); + assert.deepEqual(getContainerContent("footer"), [], "progress top footer alone"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress top contentTop alone"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress top contentBottom alone"); + assert.deepEqual(getContainerContent("left"), [], "progress top left alone"); + assert.deepEqual(getContainerContent("right"), [], "progress top right alone"); + + survey.applyTheme({ + header: {}, + cssVariables: { + "--sjs-header-backcolor": "transparent" + } + } as any); + assert.deepEqual(getContainerContent("header"), [{ + "component": "sv-progress-pages", + "id": "progress-pages", + "index": -150 + }, { + "component": "sv-header", + "container": "header", + "id": "advanced-header", + "index": -100 + }], "progress top header"); + assert.deepEqual(getContainerContent("center"), [], "progress top center"); + assert.deepEqual(getContainerContent("footer"), [], "progress top footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "progress top contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "progress top contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "progress top left"); + assert.deepEqual(getContainerContent("right"), [], "progress top right"); + + } + finally { + settings.legacyProgressBarView = false; + } + +}); + QUnit.test("getContainerContent - progress + advanced header", function (assert) { + surveyCss.currentType = "defaultV2"; const json = { title: "My Survey", showNavigationButtons: "none", @@ -18592,8 +18849,8 @@ QUnit.test("getContainerContent - progress + advanced header", function (assert) "index": -100 }], "progress top header alone"); assert.deepEqual(getContainerContent("center"), [{ - "component": "sv-progress-pages", - "id": "progress-pages" + "component": "sv-progress-buttons", + "id": "progress-buttons" }], "progress top center alone"); assert.deepEqual(getContainerContent("footer"), [], "progress top footer alone"); assert.deepEqual(getContainerContent("contentTop"), [], "progress top contentTop alone"); @@ -18608,8 +18865,8 @@ QUnit.test("getContainerContent - progress + advanced header", function (assert) } } as any); assert.deepEqual(getContainerContent("header"), [{ - "component": "sv-progress-pages", - "id": "progress-pages", + "component": "sv-progress-buttons", + "id": "progress-buttons", "index": -150 }, { "component": "sv-header", @@ -18664,7 +18921,7 @@ QUnit.test("getContainerContent - do not show timer panel in display mode", func assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "default contentBottom"); assert.deepEqual(getContainerContent("left"), [], "default left"); assert.deepEqual(getContainerContent("right"), [], "default right"); @@ -18676,7 +18933,7 @@ QUnit.test("getContainerContent - do not show timer panel in display mode", func assert.deepEqual(getContainerContent("contentTop"), [], "default contentTop"); assert.deepEqual(getContainerContent("contentBottom"), [{ "component": "sv-action-bar", - "id": "navigationbuttons" + "id": "buttons-navigation" }], "default contentBottom"); assert.deepEqual(getContainerContent("left"), [], "default left"); assert.deepEqual(getContainerContent("right"), [], "default right"); @@ -18765,6 +19022,128 @@ QUnit.test("element.wasREndered", function (assert) { assert.equal(panel2.wasRendered, true, "panel2 wasRendered, #2"); assert.equal(q6.wasRendered, true, "q6 wasRendered, #2"); }); + +QUnit.test("getContainerContent - progress settings", function (assert) { + surveyCss.currentType = "defaultV2"; + const json = { + showNavigationButtons: "none", + pages: [ + { + "elements": [ + { + required: true, + "type": "rating", + "name": "satisfaction", + }, + { + required: true, + "type": "rating", + "name": "recommend friends", + } + ] + }, + { + "elements": [ + { + "type": "radiogroup", + "name": "price to competitors", + }, + { + "type": "radiogroup", + "name": "price", + }, + ] + }, + ] + }; + + let survey = new SurveyModel(json); + const getContainerContent = getContainerContentFunction(survey); + + assert.equal(settings.legacyProgressBarView, false, "show buttons progress for pages by default"); + assert.equal(survey.showProgressBar, "off", "default show progress bar"); + assert.equal(survey.progressBarType, "pages", "default progress bar type"); + assert.equal(survey.progressBarShowPageNumbers, false, "don't show page numbers in progress by default"); + assert.equal(survey.progressBarShowPageTitles, false, "don't show page titles in progress by default"); + + assert.deepEqual(getContainerContent("header"), [], "empty header"); + assert.deepEqual(getContainerContent("footer"), [], "empty footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "empty contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "empty contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "empty left"); + assert.deepEqual(getContainerContent("right"), [], "empty right"); + assert.deepEqual(getContainerContent("center"), [], "empty center"); + + survey.showProgressBar = "auto"; + assert.deepEqual(getContainerContent("header"), [], "auto pages header"); + assert.deepEqual(getContainerContent("footer"), [], "auto pages footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "auto pages contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "auto pages contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "auto pages left"); + assert.deepEqual(getContainerContent("right"), [], "auto pages right"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons" + }], "auto pages center"); + + survey.progressBarType = "buttons"; + + assert.equal(survey.progressBarShowPageTitles, true, "show page titles in progress for buttons"); + + assert.deepEqual(getContainerContent("header"), [], "auto buttons header"); + assert.deepEqual(getContainerContent("footer"), [], "auto buttons footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "auto buttons contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "auto buttons contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "auto buttons left"); + assert.deepEqual(getContainerContent("right"), [], "auto buttons right"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons" + }], "auto buttons center"); + + survey.progressBarType = "pages"; + + survey.showProgressBar = "aboveHeader"; + assert.deepEqual(getContainerContent("header"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons", + "index": -150 + }], "aboveHeader pages header"); + assert.deepEqual(getContainerContent("footer"), [], "aboveHeader pages footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "aboveHeader pages contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "aboveHeader pages contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "aboveHeader pages left"); + assert.deepEqual(getContainerContent("right"), [], "aboveHeader pages right"); + assert.deepEqual(getContainerContent("center"), [], "aboveHeader pages center"); + + survey.showProgressBar = "belowHeader"; + assert.deepEqual(getContainerContent("header"), [], "belowHeader pages header"); + assert.deepEqual(getContainerContent("footer"), [], "belowHeader pages footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "belowHeader pages contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "belowHeader pages contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "belowHeader pages left"); + assert.deepEqual(getContainerContent("right"), [], "belowHeader pages right"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons" + }], "belowHeader pages center"); + + survey.showProgressBar = "topBottom"; + assert.deepEqual(getContainerContent("header"), [], "topBottom pages header"); + assert.deepEqual(getContainerContent("footer"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons" + }], "topBottom pages footer"); + assert.deepEqual(getContainerContent("contentTop"), [], "topBottom pages contentTop"); + assert.deepEqual(getContainerContent("contentBottom"), [], "topBottom pages contentBottom"); + assert.deepEqual(getContainerContent("left"), [], "topBottom pages left"); + assert.deepEqual(getContainerContent("right"), [], "topBottom pages right"); + assert.deepEqual(getContainerContent("center"), [{ + "component": "sv-progress-buttons", + "id": "progress-buttons" + }], "topBottom pages center"); +}); + QUnit.test("survey.runExpressions(), #7694", function (assert) { function func1(params: any[]): any { return 1; diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-custom-navigation.png b/visualRegressionTests/tests/defaultV2/etalons/survey-custom-navigation.png index 8d21f0cc58..ed8088ffdf 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-custom-navigation.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-custom-navigation.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom-brand.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom-brand.png index 53eabc4bc0..d3598c84d7 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom-brand.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom-brand.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom.png index 63633bd1de..53d49bfa49 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-bottom.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-and-toc.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-and-toc.png index 7153e30d1e..695384dd23 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-and-toc.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-and-toc.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons-mobile.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons-mobile.png new file mode 100644 index 0000000000..0cccc025bc Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons-mobile.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons.png new file mode 100644 index 0000000000..76cc857e79 Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-bottom-buttons.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons-mobile.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons-mobile.png new file mode 100644 index 0000000000..4cf9d9aad3 Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons-mobile.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons.png index 570c8bf3e0..8f24a09d0f 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-buttons.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons-mobile.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons-mobile.png new file mode 100644 index 0000000000..f3c0f1885b Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons-mobile.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons.png new file mode 100644 index 0000000000..73057de02e Binary files /dev/null and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top-numbered-buttons.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top.png b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top.png index bb4a6c0019..621d0f14f9 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-progress-bar-top.png differ diff --git a/visualRegressionTests/tests/defaultV2/etalons/survey-without-tilte-and-with-progress.png b/visualRegressionTests/tests/defaultV2/etalons/survey-without-tilte-and-with-progress.png index 1e94d22070..b0c13be360 100644 Binary files a/visualRegressionTests/tests/defaultV2/etalons/survey-without-tilte-and-with-progress.png and b/visualRegressionTests/tests/defaultV2/etalons/survey-without-tilte-and-with-progress.png differ diff --git a/visualRegressionTests/tests/defaultV2/progress.ts b/visualRegressionTests/tests/defaultV2/progress.ts new file mode 100644 index 0000000000..b0c79946fd --- /dev/null +++ b/visualRegressionTests/tests/defaultV2/progress.ts @@ -0,0 +1,293 @@ +import { Selector, ClientFunction } from "testcafe"; +import { setData } from "../../../testCafe/helper"; +import { url, frameworks, initSurvey, url_test, takeElementScreenshot, wrapVisualTest, resetFocusToBody, resetHoverToBody } from "../../helper"; +import { backgroundImage } from "../../constants"; + +const title = "Survey Progress Screenshot"; +const theme = "defaultV2"; + +const applyTheme = ClientFunction(theme => { + (window).Survey.StylesManager.applyTheme(theme); +}); + +const testedPages = [{ + name: "page1", + title: "Test", + elements: [ + { + name: "q1", + type: "text" + } + ] +}]; + +const json = { + focusFirstQuestionAutomatic: true, + "title": "Minimum data reporting form – for suspected and probable cases of COVID-19", + "pages": [{ + "name": "page1", + "navigationTitle": "Sign In", + "navigationDescription": "... to continue purchasing.", + "elements": [ + { + "name": "q1", + type: "text" + } + ] + }, { + "name": "page2", + "navigationTitle": "Shipping information", + "title": "Shipping", + "navigationDescription": "Enter shipping information.", + "elements": [ + { + "type": "radiogroup", + "name": "q1", + "title": "Select a shipping method.", + "choices": ["FedEx", "DHL", "USP", "In-Store Pickup"] + }, + ] + }, { + "name": "page3", + "navigationTitle": "Payment method", + "navigationDescription": "Select a payment method.", + "elements": [ + { + "name": "q1", + type: "text" + } + ] + }, { + "name": "page4", + "navigationTitle": "Gift Options", + "navigationDescription": "Choose your gift.", + "elements": [ + { + "name": "q1", + type: "text" + } + ] + }, { + "name": "page5", + "navigationTitle": "Place Order", + "navigationDescription": "Finish your purchasing.", + "elements": [{ + "name": "q1", + type: "text" + }] + }], + "showProgressBar": "top", + "progressBarType": "buttons" +}; + +fixture`${title}`.page`${url}`; + +frameworks.forEach(framework => { + fixture`${framework} ${title} ${theme}` + .page`${url_test}${theme}/${framework}` + .beforeEach(async t => { + await applyTheme(theme); + }); + + test("Check survey with progress top", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.progressBarType = "pages"; + (window).survey.currentPageNo = 1; + })(); + await takeElementScreenshot("survey-progress-bar-top.png", Selector(".sd-container-modern"), t, comparer); // title + progress + }); + }); + test("Check survey with progress bottom", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.showProgressBar = "bottom"; + (window).survey.progressBarType = "pages"; + (window).survey.currentPageNo = 1; + })(); + await takeElementScreenshot("survey-progress-bar-bottom.png", Selector(".sd-container-modern"), t, comparer); // title + progress + }); + }); + test("Check survey with progress bottom with brand info and fit to container", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1800, 900); + await initSurvey(framework, json); + await ClientFunction(() => { + const container = (window).document.getElementById("surveyElement"); + container.style.position = "fixed"; + container.style.top = 0; + container.style.bottom = 0; + container.style.left = 0; + container.style.right = 0; + (window).survey.showBrandInfo = true; + (window).survey.fitToContainer = true; + (window).survey.showProgressBar = "bottom"; + (window).survey.progressBarType = "pages"; + (window).survey.currentPageNo = 1; + })(); + await takeElementScreenshot("survey-progress-bar-bottom-brand.png", Selector("#surveyElement"), t, comparer); // title + progress + }); + }); + test("Check survey with progress top buttons", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await t.click(Selector("li").nth(1)); + await takeElementScreenshot("survey-progress-bar-top-buttons.png", Selector(".sd-container-modern"), t, comparer); + await t.resizeWindow(500, 1080); + await takeElementScreenshot("survey-progress-bar-top-buttons-mobile.png", Selector(".sd-container-modern"), t, comparer); + }); + }); + test("Check survey with progress top buttons with numbers", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.progressBarShowPageNumbers = true; + })(); + await t.click(Selector("li").nth(1)); + await takeElementScreenshot("survey-progress-bar-top-numbered-buttons.png", Selector(".sd-container-modern"), t, comparer); + await t.resizeWindow(500, 1080); + await takeElementScreenshot("survey-progress-bar-top-numbered-buttons-mobile.png", Selector(".sd-container-modern"), t, comparer); + }); + }); + test("Check survey with progress top and bottom buttons", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.showProgressBar = "topBottom"; + })(); + await t.click(Selector("li").nth(1)); + await takeElementScreenshot("survey-progress-bar-top-bottom-buttons.png", Selector(".sd-container-modern"), t, comparer); + await t.resizeWindow(500, 1080); + await takeElementScreenshot("survey-progress-bar-top-bottom-buttons-mobile.png", Selector(".sd-container-modern"), t, comparer); + }); + }); + test("Check survey with progress top and TOC", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.showTOC = true; + (window).survey.progressBarType = "pages"; + (window).survey.currentPageNo = 1; + })(); + await takeElementScreenshot("survey-progress-bar-top-and-toc.png", Selector(".sd-container-modern"), t, comparer); // title + progress + }); + }); + test("Check survey without title and with progress", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, { + focusFirstQuestionAutomatic: true, + pages: testedPages, + showProgressBar: "top" + }); + await takeElementScreenshot("survey-without-tilte-and-with-progress.png", Selector(".sd-container-modern"), t, comparer); // progress + }); + }); + test("Check survey without title and progress", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, { + focusFirstQuestionAutomatic: true, + pages: testedPages + }); + await takeElementScreenshot("survey-without-tilte-and-progress.png", Selector(".sd-container-modern"), t, comparer); // without title and progress + }); + }); + test("Check survey with title and without progress", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, { + focusFirstQuestionAutomatic: true, + title: "Test", + pages: testedPages + }); + await takeElementScreenshot("survey-with-tilte-and-without-progress.png", Selector(".sd-container-modern"), t, comparer); // title + }); + }); + test("Check survey progress bar freezes on top", async (t) => { + if (framework in ["knockout", "react", "angular"]) { // TODO: reanimate Vue after Vue3 supported + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1500, 720); + const json = { + "title": "American History", + "showProgressBar": "top", + "pages": [ + { + "elements": [ + { + "type": "radiogroup", + "name": "civilwar", + "title": "When was the American Civil War?", + "choices": [ + "1796-1803", + "1810-1814", + "1861-1865", + "1939-1945" + ], + "correctAnswer": "1861-1865" + }, + { + "type": "radiogroup", + "name": "libertyordeath", + "title": "Whose quote is this: \"Give me liberty, or give me death\"?", + "choices": [ + "John Hancock", + "James Madison", + "Patrick Henry", + "Samuel Adams" + ], + "correctAnswer": "Patrick Henry" + }, + { + "type": "radiogroup", + "name": "magnacarta", + "title": "What is Magna Carta?", + "choices": [ + "The foundation of the British parliamentary system", + "The Great Seal of the monarchs of England", + "The French Declaration of the Rights of Man", + "The charter signed by the Pilgrims on the Mayflower" + ], + "correctAnswer": "The foundation of the British parliamentary system" + } + ] + } + ] + }; + await initSurvey(framework, json); + await ClientFunction(() => { + const surveyElement = document.getElementById("surveyElement"); + if (surveyElement) { + surveyElement.style.height = "90vh"; + surveyElement.style.overflowY = "auto"; + document.querySelector("[data-name='libertyordeath']")?.scrollIntoView(true); + } + })(); + await takeElementScreenshot("survey-progress-top-freeze.png", Selector("body"), t, comparer); + }); + } + }); + test("Check survey with custom navigation", async (t) => { + await wrapVisualTest(t, async (t, comparer) => { + await t.resizeWindow(1920, 1080); + await initSurvey(framework, json); + await ClientFunction(() => { + (window).survey.progressBarType = "pages"; + (window).survey.currentPageNo = 1; + (window).survey.addNavigationItem({ + title: "Save", + action: () => { } + }); + })(); + await takeElementScreenshot("survey-custom-navigation.png", Selector(".sd-container-modern"), t, comparer); + }); + }); +}); \ No newline at end of file diff --git a/visualRegressionTests/tests/defaultV2/survey.ts b/visualRegressionTests/tests/defaultV2/survey.ts index cdfd599f42..dcfe6217ff 100644 --- a/visualRegressionTests/tests/defaultV2/survey.ts +++ b/visualRegressionTests/tests/defaultV2/survey.ts @@ -183,84 +183,6 @@ frameworks.forEach(framework => { await takeElementScreenshot("survey-advanced-header-mobile-background.png", Selector(".sd-root-modern"), t, comparer); }); }); - test("Check survey with progress top", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, json); - await ClientFunction(() => { - (window).survey.progressBarType = "pages"; - (window).survey.currentPageNo = 1; - })(); - await takeElementScreenshot("survey-progress-bar-top.png", Selector(".sd-container-modern"), t, comparer); // title + progress - }); - }); - test("Check survey with progress bottom", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, json); - await ClientFunction(() => { - (window).survey.showProgressBar = "bottom"; - (window).survey.progressBarType = "pages"; - (window).survey.currentPageNo = 1; - })(); - await takeElementScreenshot("survey-progress-bar-bottom.png", Selector(".sd-container-modern"), t, comparer); // title + progress - }); - }); - test("Check survey with progress bottom with brand info and fit to container", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1800, 900); - await initSurvey(framework, json); - await ClientFunction(() => { - const container = (window).document.getElementById("surveyElement"); - container.style.position = "fixed"; - container.style.top = 0; - container.style.bottom = 0; - container.style.left = 0; - container.style.right = 0; - (window).survey.showBrandInfo = true; - (window).survey.fitToContainer = true; - (window).survey.showProgressBar = "bottom"; - (window).survey.progressBarType = "pages"; - (window).survey.currentPageNo = 1; - })(); - await takeElementScreenshot("survey-progress-bar-bottom-brand.png", Selector("#surveyElement"), t, comparer); // title + progress - }); - }); - test("Check survey with progress top buttons", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, json); - await t.click(Selector("li").nth(1)); - await takeElementScreenshot("survey-progress-bar-top-buttons.png", Selector(".sd-container-modern"), t, comparer); - }); - }); - test("Check survey with custom navigation", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, json); - await ClientFunction(() => { - (window).survey.progressBarType = "pages"; - (window).survey.currentPageNo = 1; - (window).survey.addNavigationItem({ - title: "Save", - action: () => { } - }); - })(); - await takeElementScreenshot("survey-custom-navigation.png", Selector(".sd-container-modern"), t, comparer); - }); - }); - test("Check survey with progress top and TOC", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, json); - await ClientFunction(() => { - (window).survey.showTOC = true; - (window).survey.progressBarType = "pages"; - (window).survey.currentPageNo = 1; - })(); - await takeElementScreenshot("survey-progress-bar-top-and-toc.png", Selector(".sd-container-modern"), t, comparer); // title + progress - }); - }); const testedPages = [{ name: "page1", @@ -273,38 +195,6 @@ frameworks.forEach(framework => { ] }]; - test("Check survey without title and with progress", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, { - focusFirstQuestionAutomatic: true, - pages: testedPages, - showProgressBar: "top" - }); - await takeElementScreenshot("survey-without-tilte-and-with-progress.png", Selector(".sd-container-modern"), t, comparer); // progress - }); - }); - test("Check survey without title and progress", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, { - focusFirstQuestionAutomatic: true, - pages: testedPages - }); - await takeElementScreenshot("survey-without-tilte-and-progress.png", Selector(".sd-container-modern"), t, comparer); // without title and progress - }); - }); - test("Check survey with title and without progress", async (t) => { - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1920, 1080); - await initSurvey(framework, { - focusFirstQuestionAutomatic: true, - title: "Test", - pages: testedPages - }); - await takeElementScreenshot("survey-with-tilte-and-without-progress.png", Selector(".sd-container-modern"), t, comparer); // title - }); - }); test("Check survey with width", async (t) => { await wrapVisualTest(t, async (t, comparer) => { await t.resizeWindow(1920, 1080); @@ -666,69 +556,6 @@ frameworks.forEach(framework => { await takeElementScreenshot("survey-timer-without-progress.png", Selector("body"), t, comparer); }); }); - test("Check survey progress bar freezes on top", async (t) => { - if (framework in ["knockout", "react", "angular"]) { // TODO: reanimate Vue after Vue3 supported - await wrapVisualTest(t, async (t, comparer) => { - await t.resizeWindow(1500, 720); - const json = { - "title": "American History", - "showProgressBar": "top", - "pages": [ - { - "elements": [ - { - "type": "radiogroup", - "name": "civilwar", - "title": "When was the American Civil War?", - "choices": [ - "1796-1803", - "1810-1814", - "1861-1865", - "1939-1945" - ], - "correctAnswer": "1861-1865" - }, - { - "type": "radiogroup", - "name": "libertyordeath", - "title": "Whose quote is this: \"Give me liberty, or give me death\"?", - "choices": [ - "John Hancock", - "James Madison", - "Patrick Henry", - "Samuel Adams" - ], - "correctAnswer": "Patrick Henry" - }, - { - "type": "radiogroup", - "name": "magnacarta", - "title": "What is Magna Carta?", - "choices": [ - "The foundation of the British parliamentary system", - "The Great Seal of the monarchs of England", - "The French Declaration of the Rights of Man", - "The charter signed by the Pilgrims on the Mayflower" - ], - "correctAnswer": "The foundation of the British parliamentary system" - } - ] - } - ] - }; - await initSurvey(framework, json); - await ClientFunction(() => { - const surveyElement = document.getElementById("surveyElement"); - if (surveyElement) { - surveyElement.style.height = "90vh"; - surveyElement.style.overflowY = "auto"; - document.querySelector("[data-name='libertyordeath']")?.scrollIntoView(true); - } - })(); - await takeElementScreenshot("survey-progress-top-freeze.png", Selector("body"), t, comparer); - }); - } - }); const notifierJson = { "pages": [ @@ -1533,4 +1360,3 @@ frameworks.forEach(framework => { }); }); }); -