From b2f69691d635c13ae7b9abb03c05e7349afff479 Mon Sep 17 00:00:00 2001 From: leekelleher Date: Tue, 11 Mar 2025 09:47:29 +0000 Subject: [PATCH] Adds validation to Checkbox List property editor --- .../input-checkbox-list.element.ts | 46 ++++++++++++++----- ...roperty-editor-ui-checkbox-list.element.ts | 36 ++++++++++++--- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/components/input-checkbox-list/input-checkbox-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/components/input-checkbox-list/input-checkbox-list.element.ts index 405039641d..996f65d44c 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/components/input-checkbox-list/input-checkbox-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/components/input-checkbox-list/input-checkbox-list.element.ts @@ -1,13 +1,17 @@ -import { css, html, nothing, repeat, customElement, property, classMap } from '@umbraco-cms/backoffice/external/lit'; -import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui'; +import { classMap, css, customElement, html, nothing, property, repeat } from '@umbraco-cms/backoffice/external/lit'; import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui'; export type UmbCheckboxListItem = { label: string; value: string; checked: boolean; invalid?: boolean }; @customElement('umb-input-checkbox-list') -export class UmbInputCheckboxListElement extends UUIFormControlMixin(UmbLitElement, '') { +export class UmbInputCheckboxListElement extends UmbFormControlMixin< + string | undefined, + typeof UmbLitElement, + undefined +>(UmbLitElement, undefined) { @property({ attribute: false }) public list: Array = []; @@ -38,8 +42,24 @@ export class UmbInputCheckboxListElement extends UUIFormControlMixin(UmbLitEleme @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: UUIBooleanInputEvent) { @@ -73,13 +93,15 @@ export class UmbInputCheckboxListElement extends UUIFormControlMixin(UmbLitEleme } #renderCheckbox(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/checkbox-list/property-editor-ui-checkbox-list.element.ts b/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/property-editor-ui-checkbox-list.element.ts index 1b5cdda25d..a9cc829e44 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/property-editor-ui-checkbox-list.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/property-editors/checkbox-list/property-editor-ui-checkbox-list.element.ts @@ -2,28 +2,35 @@ import type { UmbCheckboxListItem, UmbInputCheckboxListElement, } from './components/input-checkbox-list/input-checkbox-list.element.js'; -import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit'; +import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element'; +import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY, UmbFormControlMixin } from '@umbraco-cms/backoffice/validation'; import type { UmbPropertyEditorConfigCollection, UmbPropertyEditorUiElement, } from '@umbraco-cms/backoffice/property-editor'; import './components/input-checkbox-list/input-checkbox-list.element.js'; -import { UmbChangeEvent } from '@umbraco-cms/backoffice/event'; /** * @element umb-property-editor-ui-checkbox-list */ @customElement('umb-property-editor-ui-checkbox-list') -export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implements UmbPropertyEditorUiElement { +export class UmbPropertyEditorUICheckboxListElement + extends UmbFormControlMixin | string | undefined, typeof UmbLitElement, undefined>( + UmbLitElement, + undefined, + ) + implements UmbPropertyEditorUiElement +{ #selection: Array = []; @property({ type: Array }) - public set value(value: Array | string | undefined) { + public override set value(value: Array | string | undefined) { this.#selection = Array.isArray(value) ? value : value ? [value] : []; } - public get value(): Array | undefined { + public override get value(): Array | undefined { return this.#selection; } @@ -60,9 +67,23 @@ export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implem @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; + @state() private _list: Array = []; + protected override firstUpdated() { + this.addFormControlElement(this.shadowRoot!.querySelector('umb-input-checkbox-list')!); + } + #onChange(event: CustomEvent & { target: UmbInputCheckboxListElement }) { this.value = event.target.selection; this.dispatchEvent(new UmbChangeEvent()); @@ -72,9 +93,12 @@ export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implem return html` + @change=${this.#onChange}> + `; } }