Bugfix: CheckboxList data structure

This commit is contained in:
leekelleher
2024-03-19 09:14:17 +00:00
parent 14c44872d0
commit 031a976ac5
2 changed files with 42 additions and 53 deletions

View File

@@ -1,64 +1,64 @@
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { css, html, nothing, repeat, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui';
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-input-checkbox-list')
export class UmbInputCheckboxListElement extends FormControlMixin(UmbLitElement) {
/**
* List of items.
*/
// TODO: Could this use a type that we export to ensure TS failure, or hook this up with a type coming from backend?
// TODO: Could this use a type that we export to ensure TS failure, or hook this up with a type coming from backend?
@property({ attribute: false })
public list: Array<{ key: string; checked: boolean; value: string }> = [];
public list: Array<{ label: string; value: string; checked: boolean }> = [];
#selected: Array<string> = [];
public get selected(): Array<string> {
return this.#selected;
}
public set selected(keys: Array<string>) {
this.#selected = keys;
#selection: Array<string> = [];
@property({ type: Array })
public set selection(keys: Array<string>) {
this.#selection = keys;
super.value = keys.join(',');
}
public get selection(): Array<string> {
return this.#selection;
}
@property()
public set value(keysString: string) {
if (keysString !== this._value) {
this.selected = keysString.split(/[ ,]+/);
}
public set value(value: string) {
this.selection = value.split(',');
}
protected getFormElement() {
return undefined;
}
#setSelection(e: UUIBooleanInputEvent) {
#onChange(e: UUIBooleanInputEvent) {
e.stopPropagation();
if (e.target.checked) this.selected = [...this.selected, e.target.value];
else this.#removeFromSelection(this.selected.findIndex((key) => e.target.value === key));
if (e.target.checked) this.selection = [...this.selection, e.target.value];
else this.#removeFromSelection(this.selection.findIndex((key) => e.target.value === key));
this.dispatchEvent(new UmbChangeEvent());
}
#removeFromSelection(index: number) {
if (index == -1) return;
const keys = [...this.selected];
const keys = [...this.selection];
keys.splice(index, 1);
this.selected = keys;
this.selection = keys;
}
render() {
if (!this.list) return nothing;
return html`<form>
<uui-form @change="${this.#setSelection}">
${repeat(this.list, (item) => item.key, this.renderCheckbox)}
<uui-form @change="${this.#onChange}">
${repeat(
this.list,
(item) => item.value,
(item) => this.#renderCheckbox(item),
)}
</uui-form>
</form>`;
}
renderCheckbox(item: { key: string; checked: boolean; value: string }) {
return html`<uui-checkbox value="${item.value}" label="${item.value}" ?checked="${item.checked}"></uui-checkbox>`;
#renderCheckbox(item: (typeof this.list)[0]) {
return html`<uui-checkbox ?checked=${item.checked} label=${item.label} value=${item.value}></uui-checkbox>`;
}
static styles = [

View File

@@ -1,9 +1,11 @@
import type { UmbInputCheckboxListElement } from './input-checkbox-list/input-checkbox-list.element.js';
import './input-checkbox-list/input-checkbox-list.element.js';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import './input-checkbox-list/input-checkbox-list.element.js';
/**
* @element umb-property-editor-ui-checkbox-list
@@ -20,39 +22,26 @@ export class UmbPropertyEditorUICheckboxListElement extends UmbLitElement implem
}
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
if (!config) return;
const listData: Record<number, { value: string; sortOrder: number }> | undefined = config.getValueByAlias('items');
if (!listData) return;
// formatting the items in the dictionary into an array
const sortedItems = [];
const values = Object.values<{ value: string; sortOrder: number }>(listData);
const keys = Object.keys(listData);
for (let i = 0; i < values.length; i++) {
sortedItems.push({ key: keys[i], sortOrder: values[i].sortOrder, value: values[i].value });
}
// ensure the items are sorted by the provided sort order
sortedItems.sort((a, b) => {
return a.sortOrder > b.sortOrder ? 1 : b.sortOrder > a.sortOrder ? -1 : 0;
});
this._list = sortedItems.map((x) => ({ key: x.key, checked: this.#value.includes(x.value), value: x.value }));
const listData: string[] | undefined = config?.getValueByAlias('items');
this._list = listData?.map((item) => ({ label: item, value: item, checked: this.#value.includes(item) })) ?? [];
}
@state()
private _list: Array<{ key: string; checked: boolean; value: string }> = [];
private _list: UmbInputCheckboxListElement['list'] = [];
#onChange(event: CustomEvent) {
this.value = (event.target as UmbInputCheckboxListElement).selected;
this.dispatchEvent(new CustomEvent('property-value-change'));
const element = event.target as UmbInputCheckboxListElement;
this.value = element.selection;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`<umb-input-checkbox-list
@change="${this.#onChange}"
.selection="${this.#value}"
.list="${this._list}"></umb-input-checkbox-list>`;
return html`
<umb-input-checkbox-list
.list=${this._list}
.selection=${this.#value}
@change=${this.#onChange}></umb-input-checkbox-list>
`;
}
}