Skip to content

Commit

Permalink
Merge branch 'master' into a11y/8460-checkboxes
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitry-kurmanov committed Jun 26, 2024
2 parents 6a83fd5 + 2b55bca commit 4ea234c
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 22 deletions.
17 changes: 16 additions & 1 deletion src/panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,21 @@ export class PanelModelBase extends SurveyElement<Question>
if (this.parent) return this.parent.getQuestionTitleLocation();
return this.survey ? this.survey.questionTitleLocation : "top";
}
availableQuestionTitleWidth(): boolean {
const questionTitleLocation = this.getQuestionTitleLocation();
if (questionTitleLocation === "left") return true;
return this.hasElementWithTitleLocationLeft();
}
hasElementWithTitleLocationLeft(): boolean {
const result = this.elements.some(el => {
if (el instanceof PanelModelBase) {
return el.hasElementWithTitleLocationLeft();
} else if (el instanceof Question) {
return el.getTitleLocation() === "left";
}
});
return result;
}
/**
* Sets consistent width for question titles in CSS values. Applies only when [`questionTitleLocation`](#questionTitleLocation) evaluates to `"left"`.
*
Expand Down Expand Up @@ -2161,7 +2176,7 @@ Serializer.addClass(
{
name: "questionTitleWidth",
visibleIf: function (obj: any) {
return !!obj && obj["getQuestionTitleLocation"]() === "left";
return !!obj && obj["availableQuestionTitleWidth"]();
}
},
{
Expand Down
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
27 changes: 25 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 Expand Up @@ -1934,6 +1953,10 @@ export class QuestionSelectBase extends Question {
}
/**
* The name of a component used to render items.
*
* [View Dropdown Demo](https://surveyjs.io/form-library/examples/dropdown-box-with-custom-items/ (linkStyle))
*
* [View Ranking Demo](https://surveyjs.io/form-library/examples/dropdown-box-with-custom-items/ (linkStyle))
*/
public get itemComponent(): string {
return this.getPropertyValue("itemComponent", this.getDefaultItemComponent());
Expand Down
3 changes: 0 additions & 3 deletions src/question_ranking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,9 +586,6 @@ export class QuestionRankingModel extends QuestionCheckboxModel {
this.setPropertyValue("longTap", val);
}

/**
* The name of a component used to render items.
*/
protected getDefaultItemComponent(): string {
return "sv-ranking-item";
}
Expand Down
11 changes: 9 additions & 2 deletions src/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,11 +429,18 @@ export var settings = {
*/
ratingMaximumRateValueCount: 20,
/**
* Specifies whether to close the drop-down menu of a [TagBox](https://surveyjs.io/form-library/examples/how-to-create-multiselect-tag-box/) question after a user selects a value.
* Specifies whether to close the drop-down menu of a [Multi-Select Dropdown (Tag Box)](https://surveyjs.io/form-library/examples/how-to-create-multiselect-tag-box/) question after a user selects a value.
*
* This setting applies to all TagBox questions on a page. You can use the [closeOnSelect](https://surveyjs.io/form-library/documentation/api-reference/dropdown-tag-box-model#closeOnSelect) property to specify the same setting for an individual TagBox question.
* This setting applies to all Multi-Select Dropdown questions on a web page. You can use the [`closeOnSelect`](https://surveyjs.io/form-library/documentation/api-reference/dropdown-tag-box-model#closeOnSelect) property to specify the same setting for an individual Multi-Select Dropdown question.
*/
tagboxCloseOnSelect: false,
/**
* A time interval in milliseconds between the last entered character and the beginning of search in [Single-](https://surveyjs.io/form-library/examples/create-dropdown-menu-in-javascript/) and [Multi-Select Dropdown](https://surveyjs.io/form-library/examples/how-to-create-multiselect-tag-box/) questions. Applies only to questions with the [`choicesLazyLoadEnabled`](https://surveyjs.io/form-library/documentation/api-reference/dropdown-menu-model#choicesLazyLoadEnabled) property set to `true`.
*
* Default value: 500
*
* [View Demo](https://surveyjs.io/form-library/examples/lazy-loading-dropdown/ (linkStyle))
*/
dropdownSearchDelay: 500,
/**
* A function that activates a browser confirm dialog.
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
23 changes: 23 additions & 0 deletions tests/surveytests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6920,6 +6920,29 @@ QUnit.test("Define questionTitleWidth on Panel/Page level", function (assert) {
assert.equal(q.titleWidth, undefined, "titleWidth available if titleLocation is left");
});

QUnit.test("availableQuestionTitleWidth on Panel/Page", function (assert) {
const survey = new SurveyModel();
const page = survey.addNewPage("page");
const panel = page.addNewPanel("panel");
const panel2 = panel.addNewPanel("panel2");
const q = <Question>panel.addNewQuestion("text");

assert.equal(page.availableQuestionTitleWidth(), false, "page");
assert.equal(panel.availableQuestionTitleWidth(), false, "panel1");
assert.equal(panel2.availableQuestionTitleWidth(), false, "panel2");

q.titleLocation = "left";
assert.equal(page.availableQuestionTitleWidth(), true, "page");
assert.equal(panel.availableQuestionTitleWidth(), true, "panel1");
assert.equal(panel2.availableQuestionTitleWidth(), false, "panel2");

q.titleLocation = "top";
page.questionTitleLocation = "left";
assert.equal(page.availableQuestionTitleWidth(), true, "page");
assert.equal(panel.availableQuestionTitleWidth(), true, "panel1");
assert.equal(panel2.availableQuestionTitleWidth(), true, "panel2");
});

QUnit.test("Question property.page getChoices", function (assert) {
var property = Serializer.findProperty("questionbase", "page");
assert.ok(property, "page property is here");
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 4ea234c

Please sign in to comment.