Skip to content

Commit

Permalink
Merge pull request #8456 from surveyjs/bug/S2255-checkbox-adaptivity
Browse files Browse the repository at this point in the history
Fixed surveyjs/service#2255 - Improve checkboxes adaptivity
  • Loading branch information
OlgaLarina authored Jun 26, 2024
2 parents 89850f1 + e024765 commit 1e6f0b7
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 16 deletions.
14 changes: 10 additions & 4 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class TriggerExpressionInfo {
runSecondCheck: (keys: any) => boolean = (keys: any): boolean => false;
}

function querySelectorIncludingSelf(el: HTMLElement, selector: string): HTMLElement {
return el.querySelector(selector) || el as any != DomWindowHelper.getWindow() && el.matches(selector) && el;
}

/**
* A base class for all questions.
*/
Expand Down Expand Up @@ -2526,7 +2530,7 @@ export class Question extends SurveyElement<Question>
if (!!el && this.isDefaultRendering()) {
const scrollableSelector = this.getObservedElementSelector();
if (!scrollableSelector) return;
const defaultRootEl = el.querySelector(scrollableSelector);
const defaultRootEl: HTMLElement = querySelectorIncludingSelf(el, scrollableSelector);
if (!defaultRootEl) return;
let isProcessed = false;
let requiredWidth: number = undefined;
Expand All @@ -2537,7 +2541,7 @@ export class Question extends SurveyElement<Question>
isProcessed = false;
}
const callback = () => {
const rootEl = <HTMLElement>el.querySelector(scrollableSelector);
const rootEl: HTMLElement = querySelectorIncludingSelf(el, scrollableSelector);
if (!requiredWidth && this.isDefaultRendering()) {
requiredWidth = rootEl.scrollWidth;
}
Expand All @@ -2561,8 +2565,10 @@ export class Question extends SurveyElement<Question>
});
this.onMobileChangedCallback = () => {
setTimeout(() => {
const rootEl = <HTMLElement>el.querySelector(scrollableSelector);
this.processResponsiveness(requiredWidth, getElementWidth(rootEl));
const rootEl = querySelectorIncludingSelf(el, scrollableSelector);
if (rootEl) {
this.processResponsiveness(requiredWidth, getElementWidth(rootEl));
}
}, 0);
};
this.resizeObserver.observe(el);
Expand Down
23 changes: 21 additions & 2 deletions src/question_baseselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ConditionRunner } from "./conditions";
import { Helpers, HashTable } from "./helpers";
import { settings } from "./settings";
import { CssClassBuilder } from "./utils/cssClassBuilder";
import { mergeValues } from "./utils/utils";
import { classesToSelector, mergeValues } from "./utils/utils";

/**
* A base class for multiple-choice question types ([Checkboxes](https://surveyjs.io/form-library/documentation/questioncheckboxmodel), [Dropdown](https://surveyjs.io/form-library/documentation/questiondropdownmodel), [Radio Button Group](https://surveyjs.io/form-library/documentation/questionradiogroupmodel), etc.).
Expand Down Expand Up @@ -1833,8 +1833,27 @@ export class QuestionSelectBase extends Question {
}
return columns;
}

protected getObservedElementSelector(): string {
return classesToSelector(this.cssClasses.mainRoot);
}

protected supportResponsiveness(): boolean {
return true;
}

@property() allowMultiColumns = true;
protected onBeforeSetCompactRenderer(): void {
super.onBeforeSetDesktopRenderer();
this.allowMultiColumns = false;
}
protected onBeforeSetDesktopRenderer(): void {
super.onBeforeSetDesktopRenderer();
this.allowMultiColumns = true;
}

get hasColumns() {
return !this.isMobile &&
return !this.isMobile && this.allowMultiColumns &&
(this.getCurrentColCount() > 1);
}
get rowLayout() {
Expand Down
20 changes: 10 additions & 10 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ function preventDefaults(event: any) {
event.stopPropagation();
}
function classesToSelector(str: string): string {
if(!str) return str;
if (!str) return str;
const re = /\s*?([\w-]+)\s*?/g;
return str.replace(re, ".$1");
}
Expand Down Expand Up @@ -477,7 +477,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
const commonItemsInOldMap = new Map<any, number>();
oldValue.forEach((item) => {
const itemKey = getKey(item);
if(!oldItemsMap.has(itemKey)) {
if (!oldItemsMap.has(itemKey)) {
oldItemsMap.set(getKey(item), item);
} else {
//if keys are set incorrectly do not process comparing
Expand All @@ -486,7 +486,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
});
newValue.forEach((item) => {
const itemKey = getKey(item);
if(!newItemsMap.has(itemKey)) {
if (!newItemsMap.has(itemKey)) {
newItemsMap.set(itemKey, item);
} else {
//if keys are set incorrectly do not process comparing
Expand All @@ -498,7 +498,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:

//calculating addedItems and items that exist in both arrays
newItemsMap.forEach((item, key) => {
if(!oldItemsMap.has(key)) {
if (!oldItemsMap.has(key)) {
addedItems.push(item);
} else {
commonItemsInNewMap.set(key, commonItemsInNewMap.size);
Expand All @@ -508,7 +508,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
//calculating deletedItems and items that exist in both arrays

oldItemsMap.forEach((item, key) => {
if(!newItemsMap.has(key)) {
if (!newItemsMap.has(key)) {
deletedItems.push(item);
} else {
commonItemsInOldMap.set(key, commonItemsInOldMap.size);
Expand All @@ -520,7 +520,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
commonItemsInNewMap.forEach((index, key) => {
const oldIndex = commonItemsInOldMap.get(key);
const item = newItemsMap.get(key);
if(oldIndex !== index) reorderedItems.push({ item: item, movedForward: oldIndex < index });
if (oldIndex !== index) reorderedItems.push({ item: item, movedForward: oldIndex < index });
});

//calculating merged array if multiple operations are applied at once
Expand All @@ -529,7 +529,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
let commonItemsIndex = 0;
const commonItemsKeysOrder = Array.from(commonItemsInNewMap.keys());
oldValue.forEach((item, index) => {
if(commonItemsInNewMap.has(getKey(item))) {
if (commonItemsInNewMap.has(getKey(item))) {
oldItemsWithCorrectOrder[index] = newItemsMap.get(commonItemsKeysOrder[commonItemsIndex]);
commonItemsIndex++;
} else {
Expand All @@ -541,8 +541,8 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:
let tempValuesArray: Array<T> = [];
oldItemsWithCorrectOrder.forEach((item) => {
const itemKey = getKey(item);
if(newItemsMap.has(itemKey)) {
if(tempValuesArray.length > 0) {
if (newItemsMap.has(itemKey)) {
if (tempValuesArray.length > 0) {
valuesToInsertBeforeKey.set(itemKey, tempValuesArray);
tempValuesArray = [];
}
Expand All @@ -553,7 +553,7 @@ export function compareArrays<T>(oldValue: Array<T>, newValue: Array<T>, getKey:

const mergedItems = new Array<T>();
newItemsMap.forEach((item, key) => {
if(valuesToInsertBeforeKey.has(key)) {
if (valuesToInsertBeforeKey.has(key)) {
valuesToInsertBeforeKey.get(key).forEach((item) => {
mergedItems.push(item);
});
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions visualRegressionTests/tests/defaultV2/responsiveness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,50 @@ frameworks.forEach(framework => {
await takeElementScreenshot("responsiveness-checkbox-col-count-2.png", Selector(".sd-question"), t, comparer);
});
});
test("Check multicolumn checkbox question doesn't fit width", async (t) => {
await wrapVisualTest(t, async (t, comparer) => {
await t.resizeWindow(1600, 1080);
await initSurvey(framework, {
showQuestionNumbers: "off",
"widthMode": "static",
"width": "60%",
questions: [
{
"type": "checkbox",
"name": "contract-type",
"title": "Type of contract ",
"choices": [
{
"value": "Item 1",
"text": "Permanent"
},
{
"value": "Item 2",
"text": "Fixed-Term"
},
{
"value": "Item 3",
"text": "All year round"
},
{
"value": "Item 4",
"text": "Term-time only"
},
{
"value": "Item 5",
"text": "Annualized"
}
],
"colCount": 5
}
]
});
await takeElementScreenshot("responsiveness-checkbox-col-count-5-wide.png", Selector(".sd-question"), t, comparer);
await t.resizeWindow(1000, 1080);
await resetFocusToBody();
await takeElementScreenshot("responsiveness-checkbox-col-count-5-small.png", Selector(".sd-question"), t, comparer);
});
});

test("Check image question", async (t) => {
await wrapVisualTest(t, async (t, comparer) => {
Expand Down

0 comments on commit 1e6f0b7

Please sign in to comment.