Adds validation to Checkbox List property editor

This commit is contained in:
leekelleher
2025-03-11 09:47:29 +00:00
committed by Jacob Overgaard
parent b684bf0a69
commit b2f69691d6
2 changed files with 64 additions and 18 deletions

View File

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

View File

@@ -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<Array<string> | string | undefined, typeof UmbLitElement, undefined>(
UmbLitElement,
undefined,
)
implements UmbPropertyEditorUiElement
{
#selection: Array<string> = [];
@property({ type: Array })
public set value(value: Array<string> | string | undefined) {
public override set value(value: Array<string> | string | undefined) {
this.#selection = Array.isArray(value) ? value : value ? [value] : [];
}
public get value(): Array<string> | undefined {
public override get value(): Array<string> | 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<UmbCheckboxListItem> = [];
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`
<umb-input-checkbox-list
.list=${this._list}
.required=${this.mandatory}
.requiredMessage=${this.mandatoryMessage}
.selection=${this.#selection}
?readonly=${this.readonly}
@change=${this.#onChange}></umb-input-checkbox-list>
@change=${this.#onChange}>
</umb-input-checkbox-list>
`;
}
}