Skip to content

Commit 7d6dc52

Browse files
authored
Dropdown in Read-Only Mode - Render a Custom Component (#11162)
* Dropdown in Read-Only Mode - Render a Custom Component * Add etalon
1 parent a2899fb commit 7d6dc52

File tree

5 files changed

+61
-6
lines changed

5 files changed

+61
-6
lines changed

packages/survey-angular-ui/src/components/dropdown/dropdown.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@
4848
[attr.aria-labelledby]="dropdownModel?.ariaQuestionLabelledby"
4949
[attr.aria-describedby]="dropdownModel?.ariaQuestionDescribedby" [attr.aria-expanded]="false"
5050
[attr.aria-readonly]="true" [attr.aria-disabled]="true">
51-
<div *ngIf="model.readOnlyText" [class]="model.cssClasses.controlValue">
51+
<div *ngIf="model.showInputFieldComponent" [class]="model.cssClasses.controlValue">
52+
<ng-template
53+
[component]="{ name: model.inputFieldComponentName, data: { model: dropdownModel.getSelectedAction(), question: model } }"></ng-template>
54+
</div>
55+
<div *ngIf="!model.showInputFieldComponent && model.readOnlyText" [class]="model.cssClasses.controlValue">
5256
<sv-ng-string [model]="model.locReadOnlyText"></sv-ng-string>
5357
</div>
5458
<sv-ng-action-bar [model]="dropdownModel.editorButtons"></sv-ng-action-bar>

packages/survey-react-ui/src/dropdown-base.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,17 @@ export class SurveyQuestionDropdownBase<T extends Question> extends SurveyQuesti
4141
return this.questionBase.renderedValue;
4242
}
4343
protected renderReadOnlyElement(): React.JSX.Element | null {
44+
if (this.question.showInputFieldComponent) {
45+
return (<div className={this.question.cssClasses.controlValue}>
46+
{this.renderValueElement()}
47+
</div>);
48+
}
4449
if (this.question.readOnlyText) {
4550
return (<div className={this.question.cssClasses.controlValue}>
4651
{this.renderLocString(this.question.locReadOnlyText)}
4752
</div>);
48-
} else {
49-
return null;
5053
}
54+
return null;
5155
}
5256
protected renderSelect(cssClasses: any): React.JSX.Element {
5357
let selectElement: React.JSX.Element | null = null;
@@ -85,7 +89,9 @@ export class SurveyQuestionDropdownBase<T extends Question> extends SurveyQuesti
8589

8690
renderValueElement(): React.JSX.Element | null {
8791
if (this.question.showInputFieldComponent) {
88-
return ReactElementFactory.Instance.createElement(this.question.inputFieldComponentName, { item: this.dropdownListModel.getSelectedAction(), question: this.question });
92+
const listModel = this.dropdownListModel;
93+
const actionItem = !!listModel ? listModel.getSelectedAction() : this.question.selectedItem;
94+
return ReactElementFactory.Instance.createElement(this.question.inputFieldComponentName, { item: actionItem, question: this.question });
8995
} else if (this.question.showSelectedItemLocText) {
9096
return this.renderLocString(this.question.selectedItemLocText);
9197
}

packages/survey-vue3-ui/src/components/dropdown/Dropdown.vue

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,21 @@
9393
:tabindex="question.isDisabledAttr ? undefined : 0"
9494
:class="question.getControlClass()"
9595
>
96-
<div v-if="question.readOnlyText" :class="question.cssClasses.controlValue">
97-
<SvComponent :is="'survey-string'" :locString="question.locReadOnlyText" />
96+
<div
97+
v-if="question.showInputFieldComponent"
98+
:class="question.cssClasses.controlValue"
99+
>
100+
<SvComponent
101+
:is="question.inputFieldComponentName"
102+
:item="readonlySelectedItem"
103+
:question="question"
104+
/>
105+
</div>
106+
<div
107+
v-else-if="question.readOnlyText"
108+
:class="question.cssClasses.controlValue"
109+
>
110+
<SvComponent :is="'survey-string'" :locString="question.locReadOnlyText" />
98111
</div>
99112
<SvComponent :is="'sv-action-bar'" :model="model.editorButtons" />
100113
</div>
@@ -144,6 +157,12 @@ const showSelectedItemLocText = computed(
144157
() => props.question.showSelectedItemLocText
145158
);
146159
const selectedItemLocText = computed(() => props.question.selectedItemLocText);
160+
const readonlySelectedItem = computed(() => {
161+
const m = model.value;
162+
return m && typeof m.getSelectedAction === "function"
163+
? m.getSelectedAction()
164+
: props.question.selectedItem;
165+
});
147166
148167
useBase(() => model.value);
149168

screenshots/dropdown.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,32 @@ frameworks.forEach(framework => {
390390
await compareScreenshot(page, ".sd-question__content", "dropdown-custom-component.png");
391391
});
392392

393+
test("Check ReadOnly dropdown with custom component", async ({ page }) => {
394+
await registerCustomItemComponent(page, framework);
395+
const json = {
396+
showQuestionNumbers: true,
397+
autoFocusFirstQuestion: true,
398+
elements: [
399+
{
400+
type: "dropdown",
401+
readOnly: true,
402+
name: "cars",
403+
title: "Dropdown",
404+
defaultValue: "Ford",
405+
itemComponent: "new-item",
406+
choices: ["Ford", "Vauxhall", "Volkswagen", "Nissan", "Audi", "Mercedes-Benz", "BMW", "Peugeot", "Toyota", "Citroen"]
407+
}
408+
]
409+
};
410+
await initSurvey(page, framework, json);
411+
await page.setViewportSize({ width: 1280, height: 1100 });
412+
// await page.evaluate(() => {
413+
// (<HTMLElement>(window as any).survey.rootElement.getRootNode().querySelector(".sd-question__content svg")).style.height = "48px";
414+
// (<HTMLElement>(window as any).survey.rootElement.getRootNode().querySelector(".sd-question__content input")).style.backgroundColor = "red";
415+
// });
416+
await compareScreenshot(page, ".sd-question__content", "dropdown-readonly-custom-component.png");
417+
});
418+
393419
test("Check overlay popup in dropdown question", async ({ page }) => {
394420
await page.setViewportSize({ width: 500, height: 700 });
395421
await page.evaluate(() => {
1.36 KB
Loading

0 commit comments

Comments
 (0)