From a48d8a41103c54d036e8116a256c92375e0d2633 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Mon, 10 Mar 2025 15:27:48 +0000 Subject: [PATCH] Adds validation to Radio Button List property editor Fixes #18268 --- .../input-radio-button-list.element.ts | 44 ++++++++++++++----- ...rty-editor-ui-radio-button-list.element.ts | 34 ++++++++++---- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-radio-button-list/input-radio-button-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-radio-button-list/input-radio-button-list.element.ts index 747b5cb4bd..5840ae9081 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/components/input-radio-button-list/input-radio-button-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/components/input-radio-button-list/input-radio-button-list.element.ts @@ -1,15 +1,18 @@ import { css, html, nothing, repeat, customElement, property, classMap } from '@umbraco-cms/backoffice/external/lit'; -import { UUIFormControlMixin, UUIRadioElement } from '@umbraco-cms/backoffice/external/uui'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UUIRadioElement } from '@umbraco-cms/backoffice/external/uui'; +import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; + import type { UUIRadioEvent } from '@umbraco-cms/backoffice/external/uui'; export type UmbRadioButtonItem = { label: string; value: string; invalid?: boolean }; @customElement('umb-input-radio-button-list') -export class UmbInputRadioButtonListElement extends UUIFormControlMixin(UmbLitElement, '') { - #value: string = ''; - +export class UmbInputRadioButtonListElement extends UmbFormControlMixin( + UmbLitElement, + undefined, +) { @property() public override set value(value: string) { this.#value = value; @@ -17,6 +20,7 @@ export class UmbInputRadioButtonListElement extends UUIFormControlMixin(UmbLitEl public override get value(): string { return this.#value; } + #value: string = ''; @property({ type: Array }) public list: Array = []; @@ -30,8 +34,24 @@ export class UmbInputRadioButtonListElement extends UUIFormControlMixin(UmbLitEl @property({ type: Boolean, reflect: true }) readonly = false; - protected override getFormElement() { - return undefined; + /** + * Sets the input to required, meaning validation will fail if the value is empty. + * @type {boolean} + */ + @property({ type: Boolean }) + required?: boolean; + + @property({ type: String }) + requiredMessage?: string; + + constructor() { + super(); + + this.addValidator( + 'valueMissing', + () => this.requiredMessage ?? UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, + () => !this.readonly && !!this.required && (this.value === undefined || this.value === null || this.value === ''), + ); } #onChange(event: UUIRadioEvent) { @@ -56,11 +76,13 @@ export class UmbInputRadioButtonListElement extends UUIFormControlMixin(UmbLitEl } #renderRadioButton(item: (typeof this.list)[0]) { - return html``; + return html` + + `; } static override readonly styles = [ diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts index 875411a640..8a7b906076 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/radio-button-list/property-editor-ui-radio-button-list.element.ts @@ -1,7 +1,8 @@ -import type { UmbInputRadioButtonListElement, UmbRadioButtonItem } from '@umbraco-cms/backoffice/components'; import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor'; +import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; +import type { UmbInputRadioButtonListElement, UmbRadioButtonItem } from '@umbraco-cms/backoffice/components'; import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, @@ -11,9 +12,12 @@ import type { * @element umb-property-editor-ui-radio-button-list */ @customElement('umb-property-editor-ui-radio-button-list') -export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement implements UmbPropertyEditorUiElement { - @property() - value?: string = ''; +export class UmbPropertyEditorUIRadioButtonListElement + extends UmbFormControlMixin(UmbLitElement) + implements UmbPropertyEditorUiElement +{ + @state() + private _list: Array = []; /** * Sets the input to readonly mode, meaning value cannot be changed but still able to read and select its content. @@ -24,6 +28,16 @@ export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement imp @property({ type: Boolean, reflect: true }) readonly = false; + /** + * Sets the input to mandatory, meaning validation will fail if the value is empty. + * @type {boolean} + */ + @property({ type: Boolean }) + mandatory?: boolean; + + @property({ type: String }) + mandatoryMessage = UMB_VALIDATION_EMPTY_LOCALIZATION_KEY; + public set config(config: UmbPropertyEditorConfigCollection | undefined) { if (!config) return; @@ -42,8 +56,9 @@ export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement imp } } - @state() - private _list: Array = []; + protected override firstUpdated() { + this.addFormControlElement(this.shadowRoot!.querySelector('umb-input-radio-button-list')!); + } #onChange(event: CustomEvent & { target: UmbInputRadioButtonListElement }) { this.value = event.target.value; @@ -54,9 +69,12 @@ export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement imp return html` + ?readonly=${this.readonly} + @change=${this.#onChange}> + `; } }