Skip to content

Commit

Permalink
background image add scroll position property (#6485)
Browse files Browse the repository at this point in the history
* work for #6252 Survey background image add scroll position property

* work for #6252 not render div with background image settings if  background image not set

* rename backgroundImagePosition ->  backgroundImageAttachment

* work for #6552 fix tests

* work fro #6252, resolve #6294 Data saving message vertical alignment can be out of view

* work for #6252 fix f-tests

* work for #6252 update background image markup test

* work for #6252 fix "Check survey notifier info type" f-test

---------

Co-authored-by: OlgaLarina <olga.larina.dev@gmail.com>
  • Loading branch information
OlgaLarina and OlgaLarina committed Jul 7, 2023
1 parent 415a78c commit 74c08e8
Show file tree
Hide file tree
Showing 18 changed files with 77 additions and 42 deletions.
3 changes: 2 additions & 1 deletion packages/survey-angular-ui/src/survey-content.component.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<ng-template #template>
<div #surveyContainer *ngIf="!!model" [class]="model.getRootCss()" [style]="model.themeVariables">
<form onsubmit="return false;" [style.backgroundColor]="model.renderBackgroundOpacity">
<div *ngIf="!!model.renderBackgroundImage" [class]="model.css.rootBackgroundImage" [style]="model.backgroundImageStyle"></div>
<form onsubmit="return false;">
<div class="sv_custom_header" [hidden]="model.hasLogo"></div>
<div [class]="model.css.container">
<div *ngIf="model.renderedHasHeader" [class]="model.css.header" [survey]="model" sv-ng-survey-header></div>
Expand Down
2 changes: 1 addition & 1 deletion src/common-styles/sv-save-data.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import "../defaultV2-theme/variables.scss";

.sv-save-data_root {
position: absolute;
position: fixed;
left: 50%;
bottom: calcSize(3);
background: $background;
Expand Down
1 change: 1 addition & 0 deletions src/defaultCss/defaultV2Css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export var defaultV2Css = {
root: "sd-root-modern",
rootMobile: "sd-root-modern--mobile",
rootReadOnly: "sd-root--readonly",
rootBackgroundImage: "sd-root_background-image",
container: "sd-container-modern",
header: "sd-title sd-container-modern__title",
bodyContainer: "sv-components-row",
Expand Down
7 changes: 7 additions & 0 deletions src/defaultV2-theme/blocks/sd-body.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,10 @@
padding-top: 180px;
box-sizing: border-box;
}
.sd-root_background-image {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
6 changes: 6 additions & 0 deletions src/defaultV2-theme/defaultV2.fontless.scss
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ body {
width: 100%;
font-family: var(--font-family, $font-family);
background-color: $background-dim;
position: relative;

form {
z-index: 1;
position: relative;
}

* {
scrollbar-width: thin;
Expand Down
5 changes: 4 additions & 1 deletion src/knockout/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

<script type="text/html" id="survey-content-template">
<div data-bind="css: rootCss, elementStyle: themeVariables">
<form onsubmit="return false;" data-bind="style: { backgroundColor: renderBackgroundOpacity }">
<!-- ko if: !!renderBackgroundImage -->
<div data-bind="css: css.rootBackgroundImage, style: backgroundImageStyle"></div>
<!-- /ko -->
<form onsubmit="return false;">
<div class="sv_custom_header" data-bind="visible: !hasLogo"></div>
<div data-bind="css: containerCss">
<!-- ko template: { name: koTitleTemplate, afterRender: koAfterRenderHeader } -->
Expand Down
7 changes: 3 additions & 4 deletions src/react/reactSurvey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class Survey extends SurveyElementBase<any, any>
} else {
renderResult = this.renderSurvey();
}
const backgroundImage = !!this.survey.renderBackgroundImage ? <div className={this.css.rootBackgroundImage} style={this.survey.backgroundImageStyle}></div> : null;
const header: JSX.Element = <SurveyHeader survey={this.survey}></SurveyHeader>;
const onSubmit = function (event: React.FormEvent<HTMLFormElement>) {
event.preventDefault();
Expand All @@ -103,13 +104,11 @@ export class Survey extends SurveyElementBase<any, any>
}
const rootCss = this.survey.getRootCss();
const cssClasses = this.rootNodeClassName ? this.rootNodeClassName + " " + rootCss : rootCss;
const formStyle = {
backgroundColor: this.survey.renderBackgroundOpacity
};

return (
<div id={this.rootNodeId} ref={this.rootRef} className={cssClasses} style={this.survey.themeVariables}>
<form onSubmit={onSubmit} style={formStyle}>
{backgroundImage}
<form onSubmit={onSubmit}>
{customHeader}
<div className={this.css.container}>
{header}
Expand Down
28 changes: 13 additions & 15 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { QuestionMatrixDropdownModelBase } from "./question_matrixdropdownbase";
import { QuestionMatrixDynamicModel } from "./question_matrixdynamic";
import { QuestionFileModel } from "./question_file";
import { QuestionMultipleTextModel } from "./question_multipletext";
import { ITheme } from "./themes";
import { ITheme, ImageFit, ImageAttachment } from "./themes";
import { PopupModel } from "./popup";

/**
Expand Down Expand Up @@ -1946,12 +1946,9 @@ export class SurveyModel extends SurveyElementCore

@property({ defaultValue: {} }) private cssVariables: {[index: string]: string} = {};
public get themeVariables() {
const result = Object.assign({}, this.cssVariables);
result.backgroundImage = this.renderBackgroundImage;
result.backgroundSize = this.backgroundImageFit;
return result;
return Object.assign({}, this.cssVariables);
}
@property() backgroundImagePosition: string;

@property() _isMobile = false;
public setIsMobile(newVal = true) {
if (this.isMobile !== newVal) {
Expand Down Expand Up @@ -2007,7 +2004,8 @@ export class SurveyModel extends SurveyElementCore
const path = this.getLocalizableString("backgroundImage").renderedHtml;
this.renderBackgroundImage = !!path ? ["url(", path, ")"].join("") : "";
}
@property() backgroundImageFit: string;
@property() backgroundImageFit: ImageFit;
@property() backgroundImageAttachment: ImageAttachment;
/**
* A value from 0 to 1 that specifies how transparent the [background image](https://surveyjs.io/form-library/documentation/api-reference/survey-data-model#backgroundImage) should be: 0 makes the image completely transparent, and 1 makes it opaque.
*/
Expand All @@ -2017,14 +2015,13 @@ export class SurveyModel extends SurveyElementCore
public set backgroundOpacity(val: number) {
this.setPropertyValue("backgroundOpacity", val);
}
public get renderBackgroundOpacity(): string {
const backgroundOpacityProperty = this.getPropertyByName("backgroundOpacity");
if(backgroundOpacityProperty.isDefaultValue(this.backgroundOpacity)) {
return "";
}

const alpha = 1 - this.backgroundOpacity;
return ["rgba(255, 255, 255, ", alpha, ")"].join("");
public get backgroundImageStyle() {
return {
opacity: this.backgroundOpacity,
backgroundImage: this.renderBackgroundImage,
backgroundSize: this.backgroundImageFit,
backgroundAttachment: this.backgroundImageAttachment
};
}
/**
* HTML content displayed on the [complete page](https://surveyjs.io/form-library/documentation/design-survey/create-a-multi-page-survey#complete-page).
Expand Down Expand Up @@ -7313,6 +7310,7 @@ Serializer.addClass("survey", [
{ name: "width", visibleIf: (obj: any) => { return obj.widthMode === "static"; } },
{ name: "backgroundImage", serializationProperty: "locBackgroundImage", visible: false },
{ name: "backgroundImageFit", default: "cover", choices: ["auto", "contain", "cover"], visible: false },
{ name: "backgroundImageAttachment", default: "scroll", choices: ["scroll", "fixed"], visible: false },
{ name: "backgroundOpacity:number", minValue: 0, maxValue: 1, default: 1, visible: false },
{ name: "showBrandInfo:boolean", default: false, visible: false }
]);
6 changes: 4 additions & 2 deletions src/themes.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export type ImageFit = "auto" | "contain" |"cover";
export type ImageAttachment = "fixed" | "scroll";

export interface ITheme {
cssVariables?: {[index: string]: string};
backgroundImage?: string;
backgroundImageFit?: string;
backgroundImagePosition?: string;
backgroundImageFit?: ImageFit;
backgroundImageAttachment?: ImageAttachment;
backgroundOpacity?: number;
isCompact?: boolean;
}
2 changes: 1 addition & 1 deletion src/vue/components/notifier.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div v-bind:class="model.css" v-show="model.isDisplayed"
<div v-bind:class="model.css" v-if="model.isDisplayed"
:style="{ visibility: model.active ? 'visible' : 'hidden' }" role="alert" aria-live="polite">
<span>{{ model.message }}</span>
<sv-action-bar :model="model.actionBar"></sv-action-bar>
Expand Down
5 changes: 2 additions & 3 deletions src/vue/survey.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
<div :class="survey.getRootCss()"
:style="vueSurvey.themeVariables"
>
<form onsubmit="return false;"
:style="{ backgroundColor: vueSurvey.renderBackgroundOpacity }"
>
<div v-if="vueSurvey.renderBackgroundImage" :class="css.rootBackgroundImage" :style="vueSurvey.backgroundImageStyle"></div>
<form onsubmit="return false;">
<div v-if="!vueSurvey.hasLogo" class="sv_custom_header"></div>
<div :class="css.container">
<survey-header :survey="vueSurvey" />
Expand Down
20 changes: 20 additions & 0 deletions tests/markup/etalon_survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,25 @@ registerMarkupTests(
return el.outerHTML;
},
snapshot: "survey-theme-variables"
}, {
name: "Test Survey backgroundImage",
json: {
backgroundImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABQCAYAAAC6aDOxAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAATkSURBVHgB5ZxNUhNBFIBf9xBBccFWQulwAvEAUuEEFidQTyCsXIonUE+gN9AbEEOVW3DnjlhGXRo3EBKm2+7AxEmnf2aGzLxX8G0IMxNIPV5/3fNeDwCE+XX78Q4gw4EovUZrQwA8AWRIBuj3UivmDfGRAfQBGZIBklzsS4AYGDsCZMgFqLe8+XYcHIVk0AVkFoAQP+9s7oGEF+n3USK7gAyZDNJSVl9eZY9JSLqADAMCaClPvJOhedJB/3wkMsgWHAW6oDXoAcpKOYuUEn2K16BK2pTyFBx/itegZZBNylm4wJ/iNSgZdCnlj9JzjWT4U7wGJYMcUp6+ZhR9BwLUHiCXlE1GyzdwiHmlPE1/vd8mMYvVlkEhKWdRUzyJGUxTSwblkXIWCmWOlFoCJFRwIId3JhAoc6RUPsS0lNWXjSLvoVDmSKk0QLqmzPxStg4lCmWOlMoCpKUsGXvjvEDAnusUhTJHSiUBSmvK7ivkh+ESf6derNjOrg6+kFgkaioJkLiYsWLrSQnd4a1otzFySpuMoDVzD5BXyjo4km/pRaDg9gBRKXOkzDVAISknjO+uD9pd/XrhXDywXkSkzJEytwDlkfL9k/anzG+ObZepAJPKoLksFMMrZfmhOTh4PX2MbegxZ7n2+mVQHinPHpbWGUwVyq6Xg/JK2XLO+p7BUvQVCHGltoqWss87CfDtKe9cooekyrpjII6U8LZ0BhWWcobzhQI3rngcrZ12dktJupyU/6Nmqhgoc6GGbf2yVAaVkXIWJh1rICLIc76drtcKByhQvug7pTwFK1T+qBOWwM7aqD1ZahQKUHClDPx5Gnnvh2D2m1RstJRXzzrvssdyz2JayqwhDp0XKCk3B53XQJTjldbK4lAcejoqR82TziPzYC5Jh6TMpPy06pEyBRojsef15qWUTXINsZCUzxaj50AY3W7yqSErZZNggOYjZTx+3G21wNNuMqVs4g3QvKSMhVZDJMR713mblE2ckr72UlZqaJ521kM/xyrpGyLlLciBdYjdZCmbzAwxLWWWb4NBrahadXvt9CD4V9dS5kLsOy8oqIapDMrR6EMjT78+j5SLenMSoGD5Apsc/XrvxiylBl2+gIKMJV109wUGoWL+eGOWvLqUTcYBKrz7AgHm2TMU2pg1lvKo3HqNl9l9gUGSRH9tx4Mbs5SUfSvlECQeRUjRi7tbQ/HHds72WILrEYYULeUy3slC6nGohXNnJlszoAopm5AKkHQU0mz9eu9u2StI2YTU82K6Xy9tg97YcVallE1oPXHo6tcD66avq5ayCakMCvXrQ+u1sZTnXGGg5aBAv74OKZvQyiBPv74XVbNSDhEBEcbDh8kdy6l+lKi7RICXrvcqKW89GLa/QQWQGWKBfn1tUjYhEyBPv97ZZCxTvigKoQAV7Ncr74wWeeVlX0KzWIF+vW9j1pyhk0EF+vVcymd1tZvIBEjdb+XLICXle4ODz1ATlBaKwQyqQ8omJALUW26Fs6cmKZvQ+NcUIf/UKGUTEgGKEvHQd75OKc/8bqAA96yia5ayCY0hJllsP16/lE1oZBCT8cwxJCmb0AiQeR+GKGUT9ADpVg8YayBMKZugB2im1YMsZRP0AGXXQBSkbIIeoMkaiIiUTQhImsWUpGyCHiBV5ogpSZkcvaXNp0CYf3BxyTNPele9AAAAAElFTkSuQmCC",
backgroundImageFit: "cover",
backgroundImageAttachment: "fixed",
backgroundOpacity: 0.4,
questions: [
{
"type": "html",
"name": "q1",
"html": "<div></div>"
}
]
},
event: "onAfterRenderSurvey",
getSnapshot: el => {
return el.children[0].outerHTML;
},
snapshot: "survey-theme-backgroundImage"
}
]);
3 changes: 3 additions & 0 deletions tests/markup/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ export function testQuestionMarkup(assert: any, test: MarkupTestDescriptor, plat
const newEl = document.createElement("div");
newEl.innerHTML = clearExtraElements(htmlElement.innerHTML);
let str = newEl.children[0].innerHTML;
if(newEl.getElementsByTagName("form").length) {
str = newEl.getElementsByTagName("form")[0].innerHTML;
}
if(!!test.getSnapshot) {
str = test.getSnapshot(htmlElement);
}
Expand Down
2 changes: 2 additions & 0 deletions tests/markup/snapshots/survey-theme-backgroundImage.snap.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div style="background-attachment:fixed; background-image:url(&quot;data:image/png; background-size:cover; base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABQCAYAAAC6aDOxAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAATkSURBVHgB5ZxNUhNBFIBf9xBBccFWQulwAvEAUuEEFidQTyCsXIonUE+gN9AbEEOVW3DnjlhGXRo3EBKm2+7AxEmnf2aGzLxX8G0IMxNIPV5/3fNeDwCE+XX78Q4gw4EovUZrQwA8AWRIBuj3UivmDfGRAfQBGZIBklzsS4AYGDsCZMgFqLe8+XYcHIVk0AVkFoAQP+9s7oGEF+n3USK7gAyZDNJSVl9eZY9JSLqADAMCaClPvJOhedJB/3wkMsgWHAW6oDXoAcpKOYuUEn2K16BK2pTyFBx/itegZZBNylm4wJ/iNSgZdCnlj9JzjWT4U7wGJYMcUp6+ZhR9BwLUHiCXlE1GyzdwiHmlPE1/vd8mMYvVlkEhKWdRUzyJGUxTSwblkXIWCmWOlFoCJFRwIId3JhAoc6RUPsS0lNWXjSLvoVDmSKk0QLqmzPxStg4lCmWOlMoCpKUsGXvjvEDAnusUhTJHSiUBSmvK7ivkh+ESf6derNjOrg6+kFgkaioJkLiYsWLrSQnd4a1otzFySpuMoDVzD5BXyjo4km/pRaDg9gBRKXOkzDVAISknjO+uD9pd/XrhXDywXkSkzJEytwDlkfL9k/anzG+ObZepAJPKoLksFMMrZfmhOTh4PX2MbegxZ7n2+mVQHinPHpbWGUwVyq6Xg/JK2XLO+p7BUvQVCHGltoqWss87CfDtKe9cooekyrpjII6U8LZ0BhWWcobzhQI3rngcrZ12dktJupyU/6Nmqhgoc6GGbf2yVAaVkXIWJh1rICLIc76drtcKByhQvug7pTwFK1T+qBOWwM7aqD1ZahQKUHClDPx5Gnnvh2D2m1RstJRXzzrvssdyz2JayqwhDp0XKCk3B53XQJTjldbK4lAcejoqR82TziPzYC5Jh6TMpPy06pEyBRojsef15qWUTXINsZCUzxaj50AY3W7yqSErZZNggOYjZTx+3G21wNNuMqVs4g3QvKSMhVZDJMR713mblE2ckr72UlZqaJ521kM/xyrpGyLlLciBdYjdZCmbzAwxLWWWb4NBrahadXvt9CD4V9dS5kLsOy8oqIapDMrR6EMjT78+j5SLenMSoGD5Apsc/XrvxiylBl2+gIKMJV109wUGoWL+eGOWvLqUTcYBKrz7AgHm2TMU2pg1lvKo3HqNl9l9gUGSRH9tx4Mbs5SUfSvlECQeRUjRi7tbQ/HHds72WILrEYYULeUy3slC6nGohXNnJlszoAopm5AKkHQU0mz9eu9u2StI2YTU82K6Xy9tg97YcVallE1oPXHo6tcD66avq5ayCakMCvXrQ+u1sZTnXGGg5aBAv74OKZvQyiBPv74XVbNSDhEBEcbDh8kdy6l+lKi7RICXrvcqKW89GLa/QQWQGWKBfn1tUjYhEyBPv97ZZCxTvigKoQAV7Ncr74wWeeVlX0KzWIF+vW9j1pyhk0EF+vVcymd1tZvIBEjdb+XLICXle4ODz1ATlBaKwQyqQ8omJALUW26Fs6cmKZvQ+NcUIf/UKGUTEgGKEvHQd75OKc/8bqAA96yia5ayCY0hJllsP16/lE1oZBCT8cwxJCmb0AiQeR+GKGUT9ADpVg8YayBMKZugB2im1YMsZRP0AGXXQBSkbIIeoMkaiIiUTQhImsWUpGyCHiBV5ogpSZkcvaXNp0CYf3BxyTNPele9AAAAAElFTkSuQmCC&quot;); opacity:0.4;">
</div>
2 changes: 1 addition & 1 deletion tests/markup/snapshots/survey-theme-variables.snap.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
<div class="sv_default_css sv_main" style="--sjs-test:val; background-size:cover;">
<div class="sv_default_css sv_main" style="--sjs-test:val;">
</div>
10 changes: 0 additions & 10 deletions tests/surveytests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17048,16 +17048,6 @@ QUnit.test("backgroundImage", assert => {
assert.equal(survey.renderBackgroundImage, ["url(", imageUrl, ")"].join(""), "renderBackgroundImage");
});

QUnit.test("backgroundOpacity", assert => {
const survey = new SurveyModel({
"backgroundOpacity": 0.6,
});
assert.equal(survey.backgroundOpacity, 0.6, "backgroundOpacity");
assert.equal(survey.renderBackgroundOpacity, "rgba(255, 255, 255, 0.4)", "renderBackgroundOpacity");

survey.backgroundOpacity = 1;
assert.equal(survey.renderBackgroundOpacity, "", "renderBackgroundOpacity empty");
});
QUnit.test("If localizable string has isLocalizable set to false then it should have only one value", assert => {
const titleProp = Serializer.findProperty("survey", "title");
titleProp.isLocalizable = false;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions visualRegressionTests/tests/defaultV2/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,6 @@ frameworks.forEach(framework => {
document.querySelector("[data-name='libertyordeath']")?.scrollIntoView(true);
}
})();
//t.debug();
await takeElementScreenshot("survey-progress-top-freeze.png", Selector("body"), t, comparer);
});
}
Expand Down Expand Up @@ -667,13 +666,14 @@ frameworks.forEach(framework => {
};
test("Check survey notifier info type", async (t) => {
await wrapVisualTest(t, async (t, comparer) => {
await ClientFunction(() => { (<any>window).Survey.settings.notifications.lifetime = 5000; })();
await ClientFunction(() => { (<any>window).Survey.settings.notifications.lifetime = 10000; })();
await t.resizeWindow(1920, 900);
await initSurvey(framework, notifierJson, { onComplete: (_sender, options) => {
options.isCompleteOnTrigger = false;
options.showDataSaving();
let fail = true;

new Promise((resolve, reject) => { setTimeout(fail ? reject : resolve, 5000); }).then(
new Promise((resolve, reject) => { setTimeout(fail ? reject : resolve, 10000); }).then(
() => { options.showDataSavingSuccess(); },
() => { options.showDataSavingError(); }
);
Expand All @@ -687,6 +687,7 @@ frameworks.forEach(framework => {

test("Check survey notifier error type", async (t) => {
await wrapVisualTest(t, async (t, comparer) => {
await t.resizeWindow(1920, 900);
await initSurvey(framework, notifierJson, { onComplete: (_sender, options) => {
options.isCompleteOnTrigger = false;
options.showDataSaving();
Expand All @@ -704,6 +705,8 @@ frameworks.forEach(framework => {
});

test("Check survey notifier success type", async (t) => {
await ClientFunction(() => { (<any>window).Survey.settings.notifications.lifetime = 10000; })();
await t.resizeWindow(1920, 900);
await wrapVisualTest(t, async (t, comparer) => {
await initSurvey(framework, notifierJson, { onComplete: (_sender, options) => {
options.isCompleteOnTrigger = false;
Expand All @@ -718,6 +721,7 @@ frameworks.forEach(framework => {
await setData({ nps_score: 4 });
await t.click("input[value=\"Complete\"]");
await takeElementScreenshot("save-data-success.png", Selector(".sv-save-data_root.sv-save-data_success"), t, comparer);
await ClientFunction(() => { (<any>window).Survey.settings.notifications.lifetime = 2000; })();
});
});
test("TOC survey navigation", async (t) => {
Expand Down

0 comments on commit 74c08e8

Please sign in to comment.