Adds validation to Radio Button List property editor

Fixes #18268
This commit is contained in:
leekelleher
2025-03-10 15:27:48 +00:00
committed by Jacob Overgaard
parent c1671f4e9b
commit a48d8a4110
2 changed files with 59 additions and 19 deletions

View File

@@ -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<string, typeof UmbLitElement, undefined>(
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<UmbRadioButtonItem> = [];
@@ -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`<uui-radio
value=${item.value}
class=${classMap({ invalid: !!item.invalid })}
label=${item.label + (item.invalid ? ` (${this.localize.term('validation_legacyOption')})` : '')}
title=${item.invalid ? this.localize.term('validation_legacyOptionDescription') : ''}></uui-radio>`;
return html`
<uui-radio
value=${item.value}
class=${classMap({ invalid: !!item.invalid })}
label=${item.label + (item.invalid ? ` (${this.localize.term('validation_legacyOption')})` : '')}
title=${item.invalid ? this.localize.term('validation_legacyOptionDescription') : ''}></uui-radio>
`;
}
static override readonly styles = [

View File

@@ -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<string | undefined, typeof UmbLitElement, undefined>(UmbLitElement)
implements UmbPropertyEditorUiElement
{
@state()
private _list: Array<UmbRadioButtonItem> = [];
/**
* 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<UmbRadioButtonItem> = [];
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`
<umb-input-radio-button-list
.list=${this._list}
.required=${this.mandatory}
.requiredMessage=${this.mandatoryMessage}
.value=${this.value ?? ''}
@change=${this.#onChange}
?readonly=${this.readonly}></umb-input-radio-button-list>
?readonly=${this.readonly}
@change=${this.#onChange}>
</umb-input-radio-button-list>
`;
}
}