Skip to content

Commit

Permalink
Allow to set mobile flag in design mode for some questions (#6934)
Browse files Browse the repository at this point in the history
* Work for #6875: support isMobile mode for some questions in design mode

* Work for #6875: fix small screen styles for multipletext question

* Fix markup tests

* Try to fix vr tests
  • Loading branch information
dk981234 committed Sep 13, 2023
1 parent c440fad commit 16033e9
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<table [class]="model.cssClasses.root" #contentElement>
<table [class]="model.getQuestionRootCss()" #contentElement>
<tbody>
<ng-container *ngFor="let row of model.getRows(); index as rowIndex; trackBy: trackRowBy">
<sv-ng-multipletext-row [model]="row" [question]="model"></sv-ng-multipletext-row>
Expand Down
2 changes: 1 addition & 1 deletion packages/survey-vue3-ui/src/Multipletext.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<table :class="question.cssClasses.root" ref="root">
<table :class="question.getQuestionRootCss()" ref="root">
<tbody>
<template
v-for="(row, rowIndex) in question.getRows()"
Expand Down
5 changes: 5 additions & 0 deletions src/defaultCss/defaultV2Css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ export var defaultV2Css = {
},
checkbox: {
root: "sd-selectbase",
rootMobile: "sd-selectbase--mobile",
rootRow: "sd-selectbase--row",
rootMultiColumn: "sd-selectbase--multi-column",
item: "sd-item sd-checkbox sd-selectbase__item",
Expand All @@ -243,6 +244,7 @@ export var defaultV2Css = {
},
radiogroup: {
root: "sd-selectbase",
rootMobile: "sd-selectbase--mobile",
rootRow: "sd-selectbase--row",
rootMultiColumn: "sd-selectbase--multi-column",
item: "sd-item sd-radio sd-selectbase__item",
Expand Down Expand Up @@ -314,8 +316,11 @@ export var defaultV2Css = {
},
multipletext: {
root: "sd-multipletext",
rootMobile: "sd-multipletext--mobile",
itemLabel: "sd-multipletext__item-container sd-input",
itemLabelOnError: "sd-multipletext__item-container--error",
itemLabelAllowFocus: "sd-multipletext__item-container--allow-focus",
itemLabelAnswered: "sd-multipletext__item-container--answered",
item: "sd-multipletext__item",
itemTitle: "sd-multipletext__item-title",
content: "sd-multipletext__content sd-question__content",
Expand Down
83 changes: 47 additions & 36 deletions src/defaultV2-theme/defaultV2.m600.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,32 +28,53 @@
min-width: 100%;
}

//multipletext responsiveness
.sd-multipletext__cell {
display: block;
@include table_responsive();
@include ranking_responsive();
}
}

&:not(:first-of-type) {
padding-left: 0;
padding-top: calcSize(1);
}
.sd-multipletext--mobile {
.sd-multipletext__cell {
display: block;

:not(:last-of-type) {
padding-bottom: calcSize(1);
}
&:not(:first-of-type) {
padding-left: 0;
padding-top: calcSize(1);
}

.sd-multipletext__item-container {
flex-direction: column;
:not(:last-of-type) {
padding-bottom: calcSize(1);
}
}

.sd-multipletext__item-container {
padding-top: calcSize(1);
padding-bottom: calcSize(1);
}

.sd-multipletext__item-title {
max-width: none;
border-right: none;
width: 100%;
padding: calcSize(1) 0;
margin: 0;
}

.sd-multipletext__item {
flex-basis: 0;

.sd-input {
padding: 0;
margin: 0;
}
}

.sd-multipletext__item-container--answered,
.sd-multipletext__item-container--allow-focus:focus-within {
flex-direction: column;

.sd-multipletext__item-title {
height: calcSize(2);
padding-right: 0;
border-right: none;
margin-bottom: 0;
margin-top: calcSize(1);
width: 100%;
max-width: none;
padding: 0;

span {
font-size: calcFontSize(0.75);
Expand All @@ -62,26 +83,16 @@
}

.sd-multipletext__item {
flex-basis: auto;
width: 100%;
}
}
}

.sd-multipletext__item .sd-input {
padding-right: 0;
padding-left: 0;
margin-top: 0;
margin-bottom: calcSize(1);
}

//eo multipletext responsiveness
.sd-selectbase--multi-column {
flex-direction: column;

.sd-selectbase__column:not(:last-child) {
padding-right: 0;
}
}
.sd-selectbase--mobile .sd-selectbase--multi-column {
flex-direction: column;

@include table_responsive();
@include ranking_responsive();
.sd-selectbase__column:not(:last-child) {
padding-right: 0;
}
}
2 changes: 1 addition & 1 deletion src/knockout/templates/question-multipletext.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script type="text/html" id="survey-question-multipletext">
<table data-bind="css: question.cssClasses.root">
<table data-bind="css: question.getQuestionRootCss()">
<tbody data-bind="foreach: { data: question.getRows(), as: 'row' }">
<!-- ko if: row.isVisible -->
<tr data-bind="foreach: { data: row.cells, as: 'cell' }, css: question.cssClasses.row">
Expand Down
22 changes: 18 additions & 4 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,17 @@ export class Question extends SurveyElement<Question>
return this.isReadOnly && settings.readOnly.commentRenderMode === "div";
}

protected setIsMobile(val: boolean) { }

@property({ defaultValue: false, onSet: (val: boolean, target: Question) => {
protected allowMobileInDesignMode() {
return false;
}
public updateIsMobileFromSurvey() {
this.setIsMobile((<SurveyModel>this.survey)._isMobile);
}
public setIsMobile(val: boolean) {
this.isMobile = val && (this.allowMobileInDesignMode() || !this.isDesignMode);
}
@property({ defaultValue: false, onSet: (val, target) => {
target.renderMinWidth = !val;
target.setIsMobile(val);
} }) isMobile: boolean;
@property() forceIsInputReadOnly: boolean;

Expand Down Expand Up @@ -476,6 +482,7 @@ export class Question extends SurveyElement<Question>
if(!this.visible) {
this.updateIsVisibleProp();
}
this.updateIsMobileFromSurvey();
}
/**
* Returns a survey element (panel or page) that contains the question and allows you to move this question to a different survey element.
Expand Down Expand Up @@ -952,6 +959,13 @@ export class Question extends SurveyElement<Question>
.append(this.cssClasses.invisible, !this.isDesignMode && this.areInvisibleElementsShowing && !this.visible)
.toString();
}

public getQuestionRootCss() {
return new CssClassBuilder()
.append(this.cssClasses.root)
.append(this.cssClasses.rootMobile, this.isMobile)
.toString();
}
public updateElementCss(reNew?: boolean): void {
super.updateElementCss(reNew);
if (reNew) {
Expand Down
5 changes: 4 additions & 1 deletion src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1659,10 +1659,13 @@ export class QuestionSelectBase extends Question {
}
public getSelectBaseRootCss(): string {
return new CssClassBuilder()
.append(this.cssClasses.root)
.append(this.getQuestionRootCss())
.append(this.cssClasses.rootRow, this.rowLayout)
.toString();
}
protected allowMobileInDesignMode(): boolean {
return true;
}

public getAriaItemLabel(item: ItemValue) {
return item.locText.renderedHtml;
Expand Down
10 changes: 9 additions & 1 deletion src/question_multipletext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ export class QuestionMultipleTextModel extends Question
}
return res;
}
protected allowMobileInDesignMode(): boolean {
return true;
}
//IMultipleTextData
getMultipleTextValue(name: string) {
if (!this.value) return null;
Expand Down Expand Up @@ -706,7 +709,12 @@ export class QuestionMultipleTextModel extends Question
// do nothing
}
public getItemLabelCss(item: MultipleTextItemModel): string {
return new CssClassBuilder().append(this.cssClasses.itemLabel).append(this.cssClasses.itemLabelOnError, item.editor.errors.length > 0).toString();
return new CssClassBuilder()
.append(this.cssClasses.itemLabel)
.append(this.cssClasses.itemLabelAnswered, item.editor.isAnswered)
.append(this.cssClasses.itemLabelAllowFocus, !this.isDesignMode)
.append(this.cssClasses.itemLabelOnError, item.editor.errors.length > 0)
.toString();
}
public getItemCss(): string {
return new CssClassBuilder().append(this.cssClasses.item).toString();
Expand Down
3 changes: 2 additions & 1 deletion src/question_paneldynamic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,8 @@ export class QuestionPanelDynamicModel extends Question
super.setValueCore(newValue);
}
}
protected setIsMobile(val: boolean) {
public setIsMobile(val: boolean) {
super.setIsMobile(val);
(this.panels || []).forEach(panel => panel.elements.forEach(element => {
if(element instanceof Question) {
(element as Question).isMobile = val;
Expand Down
2 changes: 1 addition & 1 deletion src/react/reactquestion_multipletext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class SurveyQuestionMultipleText extends SurveyQuestionElementBase {
}
}
return (
<table className={cssClasses.root}>
<table className={this.question.getQuestionRootCss()}>
<tbody>{rows}</tbody>
</table>
);
Expand Down
8 changes: 4 additions & 4 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2029,14 +2029,14 @@ export class SurveyModel extends SurveyElementCore

@property() _isMobile = false;
public setIsMobile(newVal = true) {
if (this.isMobile !== newVal) {
if (this._isMobile !== newVal) {
this._isMobile = newVal;
this.updateCss();
this.getAllQuestions().map(q => q.isMobile = newVal);
this.getAllQuestions().map(q => q.setIsMobile(newVal));
}
}
private get isMobile() {
return this._isMobile;
public get isMobile() {
return this._isMobile && !this.isDesignMode;
}
@property() private _isCompact: boolean = false;
private set isCompact(newVal: boolean) {
Expand Down
2 changes: 1 addition & 1 deletion src/vue/multipletext.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<table :class="question.cssClasses.root">
<table :class="question.getQuestionRootCss()">
<tbody>
<template
v-for="(row, rowIndex) in question.getRows()"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<tbody>
<tr class="sd-multipletext__row">
<td class="sd-multipletext__cell">
<label class="sd-input sd-multipletext__item-container sd-multipletext__item-container--error">
<label class="sd-input sd-multipletext__item-container sd-multipletext__item-container--allow-focus sd-multipletext__item-container--error">
<span class="sd-multipletext__item-title">
<span class="sv-string-viewer">Text 1</span>
<span>&nbsp;</span>
Expand Down
2 changes: 1 addition & 1 deletion tests/markup/snapshots/multipletext-error-top-v2.snap.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</tr>
<tr class="sd-multipletext__row">
<td class="sd-multipletext__cell">
<label class="sd-input sd-multipletext__item-container sd-multipletext__item-container--error">
<label class="sd-input sd-multipletext__item-container sd-multipletext__item-container--allow-focus sd-multipletext__item-container--error">
<span class="sd-multipletext__item-title">
<span class="sv-string-viewer">Text 1</span>
<span>&nbsp;</span>
Expand Down
51 changes: 51 additions & 0 deletions tests/surveytests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15778,6 +15778,57 @@ QUnit.test("Check survey getRootCss function - defaultV2Css", function (assert)
survey.fitToContainer = true;
assert.equal(survey.getRootCss(), "sd-root-modern sd-root--compact sd-root-modern--full-container");
});

QUnit.test("Check survey isMobile in design mode", function (assert) {
const survey = new SurveyModel({
"elements": [
{
type: "text",
name: "q1",
},
{
type: "multipletext",
name: "q2",
items: [
{
"name": "text1"
}
]
},
{
type: "checkbox",
name: "q3",
choices: ["Item1", "Item2"]
}
]
});
survey.css = defaultV2Css;
survey.setDesignMode(true);
const textQuestion = survey.getQuestionByName("q1");
const multipleTextQuestion = survey.getQuestionByName("q2");
const checkboxQuestion = survey.getQuestionByName("q3");
survey.setIsMobile(true);
assert.ok(survey._isMobile);
assert.notOk(survey.isMobile);
assert.notOk(textQuestion.isMobile);
assert.ok(multipleTextQuestion.isMobile);
assert.ok(checkboxQuestion.isMobile);
});
QUnit.test("Check survey isMobile is set correctly on adding new question", function (assert) {
const survey = new SurveyModel({
"elements": [
{
type: "text",
name: "q1",
},
]
});
survey.css = defaultV2Css;
survey.setIsMobile(true);
survey.pages[0].addNewQuestion("text", "q2", 0);
const question = survey.getQuestionByName("q2");
assert.ok(question.isMobile);
});
QUnit.test("Set correct activePage on fromSurvey and update buttons visibility", function (assert) {
const survey = new SurveyModel({
"elements": [
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions visualRegressionTests/tests/defaultV2/responsiveness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ frameworks.forEach(framework => {
]
});
const inputSelector = Selector(".sd-input");
await takeElementScreenshot("responsiveness-multipletext-empty.png", Selector(".sd-question"), t, comparer);
await t.click(inputSelector.nth(0));
await takeElementScreenshot("responsiveness-multipletext-focus.png", Selector(".sd-question"), t, comparer);
await t.typeText(inputSelector.nth(0), "Jon Snow")
.typeText(inputSelector.nth(2), "jon@snow.com")
.typeText(inputSelector.nth(4), "1234-56789");
Expand Down

0 comments on commit 16033e9

Please sign in to comment.