Skip to content

Commit

Permalink
#8209 - tagbox and dropdown
Browse files Browse the repository at this point in the history
  • Loading branch information
novikov82 committed May 13, 2024
1 parent e880b8d commit d12f6bd
Show file tree
Hide file tree
Showing 25 changed files with 237 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div [class]="model.cssClasses.selectWrapper" (click)="click($event)">
<div *ngIf="!model.isReadOnly" [attr.tabindex]="dropdownModel.noTabIndex ? null : 0" [class]="model.getControlClass()"
[attr.disabled]="model.isInputReadOnly ? true : null" (blur)="blur($event)"
[attr.disabled]="model.isDisabledAttr ? true : null" (blur)="blur($event)"
(keydown)="keyhandler($event)" [attr.id]="model.inputId" [attr.aria-required]="model.ariaRequired"
[attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid"
[attr.aria-errormessage]="model.ariaErrormessage" [attr.role]="model.ariaRole"
Expand All @@ -24,7 +24,7 @@
[attr.id]="model.getInputId()"
[attr.inputmode]="dropdownModel.inputMode"
[attr.tabindex]="dropdownModel.noTabIndex ? null : -1"
[attr.disabled]="model.isInputReadOnly ? true : null"
[attr.disabled]="model.isDisabledAttr ? true : null"
[attr.aria-controls]="dropdownModel.listElementId"
[attr.aria-label]="model.a11y_input_ariaLabel"
[attr.aria-labelledby]="model.a11y_input_ariaLabelledBy"
Expand All @@ -44,7 +44,12 @@
</div>
</div>
<sv-ng-popup *ngIf="!model.isReadOnly" [popupModel]="dropdownModel.popupModel"></sv-ng-popup>
<div disabled *ngIf="model.isReadOnly" [class]="model.getControlClass()" [attr.id]="model.inputId">
<div *ngIf="model.isReadOnly" [class]="model.getControlClass()" [attr.id]="model.inputId"
[attr.tabindex]="model.isDisabledAttr ? null : 0"
[attr.disabled]="model.isDisabledAttr ? true : null"
[attr.aria-label]="model.a11y_input_ariaLabel"
[attr.aria-labelledby]="model.a11y_input_ariaLabelledBy"
[attr.aria-describedby]="model.a11y_input_ariaDescribedBy">
<sv-ng-string *ngIf="model.selectedItemLocText" [model]="model.selectedItemLocText"></sv-ng-string>
<div>{{ model.readOnlyText }}</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
[attr.inputmode]="model.inputMode"
[attr.role]="model.filterStringEnabled ? question.ariaRole : null"
[attr.readonly]="model.filterReadOnly ? true : null"
[attr.disabled]="question.isInputReadOnly ? true : null"
[attr.disabled]="question.isDisabledAttr ? true : null"
[attr.size]="!model.inputStringRendered ? 1 : null"
[attr.aria-label]="question.a11y_input_ariaLabel"
[attr.aria-labelledby]="question.a11y_input_ariaLabelledBy"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<div [class]="model.cssClasses.selectWrapper" (click)="click($event)">
<div *ngIf="!model.isReadOnly" [attr.tabindex]="dropdownModel.noTabIndex ? null : 0" [class]="model.getControlClass()"
[attr.disabled]="model.isInputReadOnly ? true : null" (blur)="blur($event)"
[attr.disabled]="model.isDisabledAttr ? true : null" (blur)="blur($event)"
(keydown)="keyhandler($event)" [attr.id]="model.inputId" [attr.aria-required]="model.ariaRequired"
[attr.aria-label]="model.ariaLabel" [attr.aria-invalid]="model.ariaInvalid"
[attr.aria-errormessage]="model.ariaErrormessage" [attr.role]="model.ariaRole"
Expand All @@ -23,7 +23,12 @@
</div>
</div>
<sv-ng-popup *ngIf="!model.isReadOnly" [popupModel]="model.popupModel"></sv-ng-popup>
<div disabled *ngIf="model.isReadOnly" [class]="model.getControlClass()" [attr.id]="model.inputId">
<div *ngIf="model.isReadOnly" [class]="model.getControlClass()" [attr.id]="model.inputId"
[attr.tabindex]="model.isDisabledAttr ? null : 0"
[attr.disabled]="model.isDisabledAttr ? true : null"
[attr.aria-label]="model.a11y_input_ariaLabel"
[attr.aria-labelledby]="model.a11y_input_ariaLabelledBy"
[attr.aria-describedby]="model.a11y_input_ariaDescribedBy">
<sv-ng-string *ngIf="model.locReadOnlyText" [model]="model.locReadOnlyText"></sv-ng-string>
</div>
<div *ngIf="model.cssClasses.chevronButtonIconId" [class]="model.cssClasses.chevronButton" (pointerdown)="chevronPointerDown($event)" aria-hidden="true">
Expand Down
8 changes: 6 additions & 2 deletions packages/survey-vue3-ui/src/components/dropdown/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div
v-if="!question.isReadOnly"
:id="question.inputId"
:disabled="question.isInputReadOnly ? true : null"
:disabled="question.isDisabledAttr ? true : null"
:tabindex="model.noTabIndex ? undefined : 0"
@keydown="keyhandler"
@blur="blur"
Expand Down Expand Up @@ -51,7 +51,7 @@
type="text"
ref="inputElement"
v-bind:class="question.cssClasses.filterStringInput"
v-bind:disabled="question.isInputReadOnly"
v-bind:disabled="question.isDisabledAttr"
autocomplete="off"
:inputmode="model.inputMode"
:role="model.filterStringEnabled ? question.ariaRole : undefined"
Expand Down Expand Up @@ -98,6 +98,10 @@
disabled
v-else
:id="question.inputId"
:aria-label="question.a11y_input_ariaLabel"
:aria-labelledby="question.a11y_input_ariaLabelledBy"
:aria-describedby="question.a11y_input_ariaDescribedBy"
:tabindex="question.isDisabledAttr ? undefined : 0"
:class="question.getControlClass()"
>
<survey-string
Expand Down
7 changes: 5 additions & 2 deletions packages/survey-vue3-ui/src/components/tagbox/Tagbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
v-if="!question.isReadOnly"
:id="question.inputId"
:tabindex="model.noTabIndex ? undefined : 0"
v-bind:disabled="question.isInputReadOnly ? true : null"
v-bind:disabled="question.isDisabledAttr ? true : null"
@keydown="keyhandler"
@blur="blur"
:class="question.getControlClass()"
Expand Down Expand Up @@ -52,9 +52,12 @@
</div>
<sv-popup v-if="!question.isReadOnly" :model="model.popupModel"></sv-popup>
<div
disabled
v-else
:id="question.inputId"
:aria-label="question.a11y_input_ariaLabel"
:aria-labelledby="question.a11y_input_ariaLabelledBy"
:aria-describedby="question.a11y_input_ariaDescribedBy"
:tabindex="question.isDisabledAttr ? undefined : 0"
:class="question.getControlClass()"
>
<survey-string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
v-model="model.inputStringRendered"
:class="question.cssClasses.filterStringInput"
:placeholder="model.filterStringPlaceholder"
:disabled="question.isInputReadOnly"
:disabled="question.isDisabledAttr"
:inputmode="model.inputMode"
:role="model.filterStringEnabled ? question.ariaRole : undefined"
:aria-expanded="
Expand Down
4 changes: 4 additions & 0 deletions src/defaultV2-theme/blocks/sd-dropdown.scss
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@
.sd-input.sd-dropdown:focus-within {
box-shadow: $shadow-inner-reset, 0 0 0 2px $primary;
}
.sd-input.sd-dropdown.sd-input--readonly {
box-shadow: none;
transition: none;
}

.sd-dropdown__filter-string-input {
@include useEditorFontSize;
Expand Down
13 changes: 10 additions & 3 deletions src/knockout/components/dropdown/dropdown.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
id: question.inputId,
required: question.isRequired,
tabindex: model.noTabIndex ? undefined : 0,
disabled: question.isInputReadOnly,
disabled: question.isDisabledAttr,
role: question.ariaRole,
'aria-required': question.ariaRequired,
'aria-label': question.ariaLabel,
Expand Down Expand Up @@ -50,7 +50,7 @@
readonly: model.filterReadOnly || undefined,
role: model.filterStringEnabled ? question.ariaRole : undefined,
tabindex: model.noTabIndex ? undefined : -1,
disabled: question.isInputReadOnly,
disabled: question.isDisabledAttr,
id: question.getInputId(),
inputmode: model.inputMode
},
Expand All @@ -67,7 +67,14 @@
<!-- /ko -->
<!-- /ko -->
<!-- ko if: question.isReadOnly -->
<div disabled data-bind="css: question.getControlClass(), attr: { id: question.inputId }, ">
<div data-bind="css: question.getControlClass(), attr: {
id: question.inputId,
'aria-label': question.a11y_input_ariaLabel,
'aria-labelledby': question.a11y_input_ariaLabelledBy,
'aria-describedby': question.a11y_input_ariaDescribedBy,
tabindex: model.isDisabledAttr ? undefined : 0,
disabled: model.isDisabledAttr
} ">
<!-- ko if: question.selectedItemLocText -->
<!-- ko template: { name: 'survey-string', data: question.selectedItemLocText } -->
<!-- /ko -->
Expand Down
12 changes: 9 additions & 3 deletions src/knockout/components/tagbox/tagbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
id: question.inputId,
required: question.isRequired,
tabindex: model.noTabIndex ? undefined : 0,
disabled: question.isInputReadOnly,
disabled: question.isDisabledAttr,
role: question.ariaRole,
'aria-required': question.ariaRequired,
'aria-label': question.ariaLabel,
Expand Down Expand Up @@ -48,7 +48,7 @@
'aria-labelledby': question.a11y_input_ariaLabelledBy,
'aria-describedby': question.a11y_input_ariaDescribedBy,
placeholder: model.filterStringPlaceholder,
disabled: question.isInputReadOnly,
disabled: question.isDisabledAttr,
readonly: model.filterReadOnly
},
event: { keydown: inputKeyHandler, blur: blur, focus: focus }"></input>
Expand All @@ -66,7 +66,13 @@
<!-- /ko -->
<!-- /ko -->
<!-- ko if: question.isReadOnly -->
<div disabled data-bind="css: question.getControlClass(), attr: { id: question.inputId }, ">
<div disabled data-bind="css: question.getControlClass(), attr: {
id: question.inputId,
'aria-label': question.a11y_input_ariaLabel,
'aria-labelledby': question.a11y_input_ariaLabelledBy,
'aria-describedby': question.a11y_input_ariaDescribedBy,
tabindex: model.isDisabledAttr ? undefined : 0,
disabled: model.isDisabledAttr } ">
<!-- ko if: question.locReadOnlyText -->
<!-- ko template: { name: 'survey-string', data: question.locReadOnlyText } -->
<!-- /ko -->
Expand Down
8 changes: 4 additions & 4 deletions src/question.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1354,16 +1354,16 @@ export class Question extends SurveyElement<Question>
}
return this.isReadOnly || this.isDesignModeV2;
}
public get renderedInputReadOnly() {
public get renderedInputReadOnly(): string {
return this.isInputReadOnly ? "" : undefined;
}
public get renderedInputDisabled() {
public get renderedInputDisabled(): string {
return this.isInputReadOnly ? "" : undefined;
}
public get isReadOnlyAttr() {
public get isReadOnlyAttr(): boolean {
return this.isReadOnly;
}
public get isDisabledAttr() {
public get isDisabledAttr(): boolean {
return this.isDesignModeV2;
}
protected onReadOnlyChanged(): void {
Expand Down
11 changes: 8 additions & 3 deletions src/react/dropdown-base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@ export class SurveyQuestionDropdownBase<T extends Question> extends SurveyQuesti
const text = (this.question.selectedItemLocText) ? this.renderLocString(this.question.selectedItemLocText) : "";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
selectElement = <div id={this.question.inputId} className={this.question.getControlClass()} disabled>
selectElement = <div id={this.question.inputId}
aria-label={this.question.a11y_input_ariaLabel}
aria-labelledby={this.question.a11y_input_ariaLabelledBy}
aria-describedby={this.question.a11y_input_ariaDescribedBy}
tabIndex={this.question.isDisabledAttr ? undefined : 0}
className={this.question.getControlClass()}>
{text}
{this.renderReadOnlyElement()}
</div>;
Expand Down Expand Up @@ -92,7 +97,7 @@ export class SurveyQuestionDropdownBase<T extends Question> extends SurveyQuesti
tabIndex={dropdownListModel.noTabIndex ? undefined : 0}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
disabled={this.question.isInputReadOnly}
disabled={this.question.isDisabledAttr}
required={this.question.isRequired}
onKeyDown={this.keyhandler}
onBlur={this.blur}
Expand Down Expand Up @@ -130,7 +135,7 @@ export class SurveyQuestionDropdownBase<T extends Question> extends SurveyQuesti
placeholder={dropdownListModel.placeholderRendered}
readOnly={dropdownListModel.filterReadOnly ? true : undefined}
tabIndex={dropdownListModel.noTabIndex ? undefined : -1}
disabled={this.question.isInputReadOnly}
disabled={this.question.isDisabledAttr}
inputMode={dropdownListModel.inputMode}
onChange={(e) => { onInputChange(e); }}
onBlur={this.blur}
Expand Down
11 changes: 8 additions & 3 deletions src/vue/components/dropdown/dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div
v-if="!question.isReadOnly"
:id="question.inputId"
v-bind:disabled="question.isInputReadOnly"
v-bind:disabled="question.isDisabledAttr"
:tabindex="model.noTabIndex ? undefined : 0"
@keydown="keyhandler"
@blur="blur"
Expand Down Expand Up @@ -42,7 +42,7 @@
type="text"
ref="inputElement"
v-bind:class="question.cssClasses.filterStringInput"
v-bind:disabled="question.isInputReadOnly"
v-bind:disabled="question.isDisabledAttr"
autocomplete="off"
:inputmode="model.inputMode"
:role="model.filterStringEnabled ? question.ariaRole : null"
Expand Down Expand Up @@ -81,7 +81,12 @@
v-if="!question.isReadOnly"
:model="question.dropdownListModel.popupModel"
></sv-popup>
<div disabled v-else :id="question.inputId" :class="question.getControlClass()">
<div v-else :id="question.inputId"
:aria-label="question.a11y_input_ariaLabel"
:aria-labelledby="question.a11y_input_ariaLabelledBy"
:aria-describedby="question.a11y_input_ariaDescribedBy"
:tabindex="question.isDisabledAttr ? undefined : 0"
:class="question.getControlClass()">
<survey-string
v-if="selectedItemLocText"
:locString="selectedItemLocText"
Expand Down
2 changes: 1 addition & 1 deletion src/vue/components/tagbox/tagbox-filter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
v-model="model.inputStringRendered"
v-bind:class="question.cssClasses.filterStringInput"
v-bind:placeholder="model.filterStringPlaceholder"
v-bind:disabled="question.isInputReadOnly"
v-bind:disabled="question.isDisabledAttr"
:inputmode="model.inputMode"
:role="model.filterStringEnabled ? question.ariaRole : null"
:aria-expanded="question.ariaExpanded"
Expand Down
9 changes: 7 additions & 2 deletions src/vue/components/tagbox/tagbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
v-if="!question.isReadOnly"
:id="question.inputId"
:tabindex="model.noTabIndex ? undefined : 0"
v-bind:disabled="question.isInputReadOnly"
v-bind:disabled="question.isDisabledAttr"
@keydown="keyhandler"
@blur="blur"
:class="question.getControlClass()"
Expand Down Expand Up @@ -44,7 +44,12 @@
</div>
</div>
<sv-popup v-if="!question.isReadOnly" :model="model.popupModel"></sv-popup>
<div disabled v-else :id="question.inputId" :class="question.getControlClass()">
<div disabled v-else :id="question.inputId"
:aria-label="question.a11y_input_ariaLabel"
:aria-labelledby="question.a11y_input_ariaLabelledBy"
:aria-describedby="question.a11y_input_ariaDescribedBy"
:tabindex="model.isDisabledAttr ? undefined : 0"
:class="question.getControlClass()">
<survey-string
v-if="question.locReadOnlyText"
:locString="question.locReadOnlyText"
Expand Down
23 changes: 23 additions & 0 deletions tests/markup/etalon_dropdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,29 @@ registerMarkupTests(
},
snapshot: "dropdown-readonly-with-value"
},
{
name: "Test Dropdown question markup disabled with value",
json: {
questions: [
{
"type": "dropdown",
"name": "name",
"title": "Question title",
defaultValue: "item1",
"choices": [
"item1",
"item2",
"item3"
],
titleLocation: "hidden"
}
]
},
initSurvey: (survey) => survey.setDesignMode(true),
before: () => { settings.supportCreatorV2 = true; },
after: () => { settings.supportCreatorV2 = false; },
snapshot: "dropdown-disabled-with-value"
},
{
name: "Test Dropdown Select question markup",
json: {
Expand Down
25 changes: 24 additions & 1 deletion tests/markup/etalon_tagbox.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { _setIsTouch } from "survey-core";
import { _setIsTouch, settings } from "survey-core";
import { registerMarkupTests } from "./helper";

registerMarkupTests(
Expand Down Expand Up @@ -107,6 +107,29 @@ registerMarkupTests(
]
},
snapshot: "tagbox-readonly-with-value"
}, {
name: "Test Tagbox question markup disabled with value",
json: {
questions: [
{
"type": "tagbox",
"name": "name",
"title": "Question title",
defaultValue: "item1",
"choices": [
"item1",
"item2",
"item3"
],
titleLocation: "hidden"
}
]
},
removeIds: true,
initSurvey: (survey) => survey.setDesignMode(true),
before: () => { settings.supportCreatorV2 = true; },
after: () => { settings.supportCreatorV2 = false; },
snapshot: "tagbox-disabled-with-value"
}, {
name: "Test Tagbox question without clear button markup",
json: {
Expand Down
2 changes: 2 additions & 0 deletions tests/markup/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,8 @@ function clearAttributes(el: Element, removeIds = false) {
}
if(el.hasAttribute("readonly"))
el.setAttribute("readonly", "");
if (el.hasAttribute("disabled"))
el.setAttribute("disabled", "");
if(el.hasAttribute("ng-reflect-value")) {
el.setAttribute("value", <string>el.getAttribute("ng-reflect-value"));
}
Expand Down

0 comments on commit d12f6bd

Please sign in to comment.