Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#6019 Do not render content of the collapsed elements on designer surface #6035

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions functionalTests/designer/question-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,49 @@ test("Question adorner - collapse button in differen modes", async (t) => {
await ClientFunction(() => { window["creator"].expandCollapseButtonVisibility = "never"; })();
});

test("Question adorner - do not render content when initially collapsed", async (t) => {
const json = {
elements: [
{
type: "text",
name: "question1"
},
{
type: "panel",
name: "panel1"
}
]
};
await ClientFunction(() => { window["creator"].expandCollapseButtonVisibility = "always"; })();
await setJSON(json);
await t.hover(getToolboxItemByText("Single-Line Input"));
const qContent = Selector(".svc-question__content--text");
const qCollapseButton = Selector(".svc-question__content--text #collapse");
const pContent = Selector(".svc-question__content--panel");
const pCollapseButton = Selector(".svc-question__content--panel #collapse");
await t.expect(qCollapseButton.visible).ok();
await t.click(qCollapseButton);
await t.expect(pCollapseButton.visible).ok();
await t.click(pCollapseButton);

await t.click(Selector(".svc-tabbed-menu-item").withText("Preview"));
await t.click(Selector(".svc-tabbed-menu-item").withText("Designer"));

await t.expect(qContent.find(".sd-element").exists).notOk();
await t.click(qCollapseButton);
await t.expect(qContent.find(".sd-element").exists).ok();
await t.click(qCollapseButton);
await t.expect(qContent.find(".sd-element").exists).ok();

await t.expect(pContent.find(".sd-element").exists).notOk();
await t.click(pCollapseButton);
await t.expect(pContent.find(".sd-element").exists).ok();
await t.click(pCollapseButton);
await t.expect(pContent.find(".sd-element").exists).ok();

await ClientFunction(() => { window["creator"].expandCollapseButtonVisibility = "never"; })();
});

test("Question adorner - collapse button visibility inside panels", async (t) => {
await t.resizeWindow(1920, 1080);
const json = {
Expand Down
67 changes: 34 additions & 33 deletions packages/survey-creator-angular/src/panel.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
(mouseover)="adorner.hover($event, $event.currentTarget)" (mouseleave)="adorner.hover($event, $event.currentTarget)"
[attr.data-sv-drop-target-survey-element]="adorner.element.name || null" #container>
<div *ngIf="adorner.showHiddenTitle" [class]="adorner.cssCollapsedHiddenHeader">
<div [class]="adorner.cssCollapsedHiddenTitle">
<sv-ng-string *ngIf="!!model.hasTitle" [model]="model.locTitle"></sv-ng-string>
<span *ngIf="!model.hasTitle" class="svc-fake-title">{{model.name}}</span>
<sv-ng-element-title *ngIf="!!model.hasTitle" [element]="model"></sv-ng-element-title>
<div *ngIf="!model.hasTitle" [class]="adorner.cssCollapsedHiddenTitle">
<span class="svc-fake-title">{{model.name}}</span>
</div>
</div>
<div [class]="adorner.css()" [key2click]="{ disableTabStop: true }"
Expand All @@ -22,43 +22,44 @@
<sv-action-bar [model]="adorner.topActionContainer" [handleClick]="false"></sv-action-bar>
</div>
</div>
<ng-template [component]="{ name: componentName, data: componentData }"></ng-template>

<div *ngIf="adorner.isEmptyElement" class="svc-panel__placeholder_frame-wrapper">
<div class="svc-panel__placeholder_frame">
<div class="svc-panel__placeholder">{{ adorner.placeholderText }}</div>
<div *ngIf="adorner.showAddQuestionButton" class="svc-panel__add-new-question svc-action-button" [key2click]
(click)="addNewQuestion($event)">
<svg class="svc-panel__add-new-question-icon" [iconName]="('icon-add_24x24')" [size]="24"
sv-ng-svg-icon></svg>
<span class="svc-add-new-item-button__text">
{{ adorner.addNewQuestionText }}
</span>
<ng-container *ngIf="adorner.needToRenderContent">
<ng-template [component]="{ name: componentName, data: componentData }"></ng-template>
<div *ngIf="adorner.isEmptyElement" class="svc-panel__placeholder_frame-wrapper">
<div class="svc-panel__placeholder_frame">
<div class="svc-panel__placeholder">{{ adorner.placeholderText }}</div>
<div *ngIf="adorner.showAddQuestionButton" class="svc-panel__add-new-question svc-action-button" [key2click]
(click)="addNewQuestion($event)">
<svg class="svc-panel__add-new-question-icon" [iconName]="('icon-add_24x24')" [size]="24"
sv-ng-svg-icon></svg>
<span class="svc-add-new-item-button__text">
{{ adorner.addNewQuestionText }}
</span>
</div>
</div>
</div>
</div>

<ng-template *ngIf="adornerComponent && adorner.element.isInteractiveDesignElement"
[component]="{ name: adornerComponent, data: { adorner: adorner, question: model } }">
</ng-template>
<ng-template *ngIf="adornerComponent && adorner.element.isInteractiveDesignElement"
[component]="{ name: adornerComponent, data: { adorner: adorner, question: model } }">
</ng-template>

<div *ngIf="!adorner.isEmptyElement && adorner.showAddQuestionButton"
class="svc-panel__add-new-question-container">
<div class="svc-panel__question-type-selector-popup"> <sv-ng-popup
[popupModel]="adorner.questionTypeSelectorModel.popupModel"></sv-ng-popup>
</div>
<div *ngIf="!adorner.isEmptyElement && adorner.showAddQuestionButton"
class="svc-panel__add-new-question-container">
<div class="svc-panel__question-type-selector-popup"> <sv-ng-popup
[popupModel]="adorner.questionTypeSelectorModel.popupModel"></sv-ng-popup>
</div>

<div class="svc-panel__add-new-question-wrapper">
<ng-template
[component]="{ name: 'svc-add-new-question-btn', data: { model: { data: adorner }, buttonClass: 'svc-action-button', renderPopup: false } }">
</ng-template>
<div class="svc-panel__add-new-question-wrapper">
<ng-template
[component]="{ name: 'svc-add-new-question-btn', data: { model: { data: adorner }, buttonClass: 'svc-action-button', renderPopup: false } }">
</ng-template>
</div>
</div>
</div>

<div *ngIf="adorner.element.isInteractiveDesignElement" class="svc-question__content-actions"
(focusin)="adorner.select(adorner, $event)">
<sv-action-bar [model]="adorner.actionContainer" [handleClick]="false"></sv-action-bar>
</div>
<div *ngIf="adorner.element.isInteractiveDesignElement" class="svc-question__content-actions"
(focusin)="adorner.select(adorner, $event)">
<sv-action-bar [model]="adorner.actionContainer" [handleClick]="false"></sv-action-bar>
</div>
</ng-container>
</div>
</div>
</ng-template>
8 changes: 5 additions & 3 deletions packages/survey-creator-angular/src/question.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
(mouseover)="adorner.hover($event, $event.currentTarget)" (mouseleave)="adorner.hover($event, $event.currentTarget)"
[attr.data-sv-drop-target-survey-element]="adorner.element.name || null" #container>
<div *ngIf="adorner.showHiddenTitle" [class]="adorner.cssCollapsedHiddenHeader">
<div [class]="adorner.cssCollapsedHiddenTitle">
<sv-ng-string *ngIf="!!model.hasTitle" [model]="model.locTitle"></sv-ng-string>
<span *ngIf="!model.hasTitle" class="svc-fake-title">{{model.name}}</span>
<sv-ng-element-title *ngIf="!!model.hasTitle" [element]="model"></sv-ng-element-title>
<div *ngIf="!model.hasTitle" [class]="adorner.cssCollapsedHiddenTitle">
<span class="svc-fake-title">{{model.name}}</span>
</div>
</div>
<div [class]="adorner.css()" [key2click]="{ disableTabStop: true }" (click)="adorner.select(adorner, $event)">
Expand All @@ -20,6 +20,7 @@
<sv-action-bar [model]="adorner.topActionContainer" [handleClick]="false"></sv-action-bar>
</div>
</div>
<ng-container *ngIf="adorner.needToRenderContent">
<ng-template [component]="{ name: componentName, data: componentData }"></ng-template>
<div *ngIf="adorner.isEmptyElement && !showPlaceholderComponent" class="svc-panel__placeholder_frame-wrapper">
<div class="svc-panel__placeholder_frame">
Expand All @@ -37,6 +38,7 @@
<div class="svc-question__content-actions" (focusin)="adorner.select(adorner, $event)">
<sv-action-bar [model]="adorner.actionContainer" [handleClick]="false"></sv-action-bar>
</div>
</ng-container>
</div>
</div>
</ng-template>
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ export class SurveyElementAdornerBase<T extends SurveyElement = SurveyElement> e
protected get dragInsideCollapsedContainer(): boolean {
return this.collapsed && this.creator.dragDropSurveyElements.insideContainer;
}

@property({ defaultValue: true }) needToRenderContent: boolean;
@property({ defaultValue: true }) allowExpandCollapse: boolean;
@property({
onSet: (val, target: SurveyElementAdornerBase<T>) => {
target.renderedCollapsed = val;
if (!val) target.needToRenderContent = true;
if (target.creator.designerStateManager && !target.creator.designerStateManager.isSuspended && target.surveyElement) {
target.creator.designerStateManager.getElementState(target.surveyElement).collapsed = val;
}
Expand Down Expand Up @@ -293,6 +294,7 @@ export class SurveyElementAdornerBase<T extends SurveyElement = SurveyElement> e
const state = this.creator.designerStateManager?.getElementState(this.surveyElement);
this.collapsed = state.collapsed;
}
this.needToRenderContent = !this.collapsed;
}

protected detachElement(surveyElement: T): void {
Expand Down
2 changes: 1 addition & 1 deletion packages/survey-creator-core/src/components/question.scss
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,7 @@ svc-question,
transition: opacity 150ms;
}
}
.svc-element__header--lazy,
.svc-element__header--hidden.sd-question__header--location--left {
.svc-string-editor,
sv-ng-string > .svc-string-editor {
Expand All @@ -774,7 +775,6 @@ svc-question,
content: none;
}
}

}

.svc-question__adorner {
Expand Down
9 changes: 7 additions & 2 deletions packages/survey-creator-core/src/components/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,12 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase {
return (this.element)?.getPropertyValue("isMessagePanelVisible");
}
get cssCollapsedHiddenHeader(): string {
return (this.element as PanelModel | Question).cssHeader + " svc-element__header--hidden";
const css = new CssClassBuilder()
.append((this.element as PanelModel | Question).cssHeader)
.append("svc-element__header--hidden")
.append("svc-element__header--lazy", !this.needToRenderContent)
.toString();
return css;
}
get cssCollapsedHiddenTitle(): string {
return this.element.cssTitle + " svc-element__title--hidden";
Expand Down Expand Up @@ -350,7 +355,7 @@ export class QuestionAdornerViewModel extends SurveyElementAdornerBase {
}

public get showHiddenTitle() {
return (!this.element.hasTitle || this.isTitleLeft) && this.element.isInteractiveDesignElement;
return (!this.element.hasTitle || this.isTitleLeft || !this.needToRenderContent) && this.element.isInteractiveDesignElement;
}
public get placeholderText(): string {
if (this.surveyElement instanceof QuestionHtmlModel) {
Expand Down
15 changes: 8 additions & 7 deletions packages/survey-creator-knockout/src/adorners/panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
data-bind="css: rootCss(), attr: { 'data-sv-drop-target-survey-element': element.name || null }, event: { dblclick: (d, e) => dblclick(e), mouseover: function(m, e) { hover(e, $element); }, mouseleave: function(m, e) { hover(e, $element); } }">
<!-- ko if: $data.showHiddenTitle -->
<div data-bind="css: $data.cssCollapsedHiddenHeader">
<div data-bind="css: $data.cssCollapsedHiddenTitle">
<!-- ko if: !!$data.element.hasTitle -->
<!-- ko template: { name: 'survey-string', data: $data.element.locTitle } --><!-- /ko -->
<!-- ko if: !!$data.element.hasTitle -->
<!-- ko component: { name: 'survey-element-title', params: { element: $data.element } } --><!-- /ko -->
<!-- /ko -->
<!-- ko ifnot: !!$data.element.hasTitle -->
<span class="svc-fake-title" data-bind="text: element.name"></span>
<!-- /ko -->
</div>
<div data-bind="css: $data.cssCollapsedHiddenTitle">
<span class="svc-fake-title" data-bind="text: element.name"></span>
</div>
<!-- /ko -->
</div>
<!-- /ko -->
<div
Expand All @@ -28,6 +28,7 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: $data.needToRenderContent -->
<!-- ko component: { name: 'sv-template-renderer', params: { componentData: null, templateData: templateData } } -->
<!-- /ko -->
<!-- ko if: koIsEmptyElement() -->
Expand Down Expand Up @@ -62,12 +63,12 @@
</div>
</div>
<!-- /ko -->

<!-- ko if: $data.element.isInteractiveDesignElement -->
<div class="svc-question__content-actions" data-bind="event: {focusin: koSelect}">
<!-- ko component: { name: 'sv-action-bar', params: { model: actionContainer, handleClick: false } } -->
<!-- /ko -->
</div>
<!-- /ko -->
<!-- /ko -->
</div>
</div>
17 changes: 10 additions & 7 deletions packages/survey-creator-knockout/src/adorners/question.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
data-bind="css: rootCss(), attr: { 'data-sv-drop-target-survey-element': element.name || null }, event: { dblclick: (d, e) => dblclick(e), mouseover: function(m, e) { hover(e, $element); }, mouseleave: function(m, e) { hover(e, $element); } }">
<!-- ko if: $data.showHiddenTitle -->
<div data-bind="css: $data.cssCollapsedHiddenHeader">
<div data-bind="css: $data.cssCollapsedHiddenTitle">
<!-- ko if: !!$data.element.hasTitle -->
<!-- ko template: { name: 'survey-string', data: $data.element.locTitle } --><!-- /ko -->
<!-- ko if: !!$data.element.hasTitle -->
<!-- ko component: { name: 'survey-element-title', params: { element: $data.element } } -->
<!-- /ko -->
<!-- ko ifnot: !!$data.element.hasTitle -->
<span class="svc-fake-title" data-bind="text: element.name"></span>
<!-- /ko -->
</div>
<!-- /ko -->
<!-- ko ifnot: !!$data.element.hasTitle -->
<div data-bind="css: $data.cssCollapsedHiddenTitle">
<span class="svc-fake-title" data-bind="text: element.name"></span>
</div>
<!-- /ko -->
</div>
<!-- /ko -->
<div data-bind="click: koSelect, key2click: { disableTabStop: true }, clickBubble: false, css: css()">
Expand All @@ -28,6 +29,7 @@
</div>
</div>
<!-- /ko -->
<!-- ko if: $data.needToRenderContent -->
<!-- ko component: { name: 'sv-template-renderer', params: { componentData: null, templateData: templateData } } -->
<!-- /ko -->
<!-- ko if: koIsEmptyElement() && !$data.placeholderComponentData -->
Expand Down Expand Up @@ -57,5 +59,6 @@
<!-- ko component: { name: 'sv-action-bar', params: { model: actionContainer, handleClick: false } } -->
<!-- /ko -->
</div>
<!-- /ko -->
</div>
</div>
27 changes: 16 additions & 11 deletions packages/survey-creator-react/src/adorners/Question.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
attachKey2click,
SvgIcon,
Popup,
SurveyElementBase
SurveyElementBase,
TitleElement
} from "survey-react-ui";
import { CreatorModelElement } from "../ModelElement";

Expand Down Expand Up @@ -76,7 +77,7 @@ export class QuestionAdornerComponent extends CreatorModelElement<
return true;
}
protected renderContent(allowInteractions: boolean): JSX.Element {
var content = this.renderElementContent();
var content = this.model.needToRenderContent ? this.renderElementContent() : null;
//if (!allowInteractions) return <>{content}{this.renderFooter()}</>;
return attachKey2click(
<div
Expand All @@ -89,7 +90,7 @@ export class QuestionAdornerComponent extends CreatorModelElement<
<div className="svc-question__drop-indicator svc-question__drop-indicator--bottom"></div>
{allowInteractions ? this.renderHeader() : null}
{content}
{this.renderFooter()}
{this.model.needToRenderContent ? this.renderFooter() : null}
</div>,
undefined, { disableTabStop: this.disableTabStop() });
}
Expand All @@ -110,14 +111,18 @@ export class QuestionAdornerComponent extends CreatorModelElement<
if (!this.model.showHiddenTitle) return null;
const element = this.model.element as Question | PanelModel;
return (
<div className={this.model.cssCollapsedHiddenHeader} >
<div
ref={node => node && (!this.model.renderedCollapsed ?
node.setAttribute("inert", "") : node.removeAttribute("inert")
)}
className={this.model.cssCollapsedHiddenTitle} >
{element.hasTitle ? SurveyElementBase.renderLocString(element.locTitle, null, "q_title") : <span className="svc-fake-title">{element.name}</span>}
</div>
<div
ref={node => node && (!this.model.renderedCollapsed ?
node.setAttribute("inert", "") : node.removeAttribute("inert")
)} className={this.model.cssCollapsedHiddenHeader} >
{(
element.hasTitle ?
<TitleElement element={element}></TitleElement> :
<div
className={this.model.cssCollapsedHiddenTitle} >
<span className="svc-fake-title">{element.name}</span>
</div>
)}
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import { SurveyCreatorModel } from 'survey-creator-core';
const creator = new SurveyCreatorModel({ pageEditMode: "bypage" });
creator.expandCollapseButtonVisibility = "onhover";
import { SurveyCreatorComponent } from "survey-creator-vue";
</script>
<template>
Expand Down
Loading