diff --git a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts index 5c5ac3fe77..57c11096d4 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/block/block-grid/property-editors/block-grid-editor/property-editor-ui-block-grid.element.ts @@ -129,11 +129,7 @@ export class UmbPropertyEditorUIBlockGridElement #gotRootEntriesElement(element: Element | undefined): void { if (this.#currentEntriesElement === element) return; if (this.#currentEntriesElement) { - throw new Error( - 'Cannot re-render root entries element because we currently do not support removing form control elements.', - ); - // TODO: If this become relevant we should implement this method: [NL] - //this.removeFormControlElement(this.#currentEntriesElement as any); + this.removeFormControlElement(this.#currentEntriesElement as any); } this.#currentEntriesElement = element; this.addFormControlElement(element as any); diff --git a/src/Umbraco.Web.UI.Client/src/packages/core/validation/mixins/form-control.mixin.ts b/src/Umbraco.Web.UI.Client/src/packages/core/validation/mixins/form-control.mixin.ts index 20ff64ae08..e4f45a5518 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/core/validation/mixins/form-control.mixin.ts +++ b/src/Umbraco.Web.UI.Client/src/packages/core/validation/mixins/form-control.mixin.ts @@ -80,6 +80,7 @@ export declare abstract class UmbFormControlMixinElement ) => UmbFormControlValidatorConfig; removeValidator: (obj: UmbFormControlValidatorConfig) => void; protected addFormControlElement(element: UmbNativeFormControlElement): void; + protected removeFormControlElement(element: UmbNativeFormControlElement): void; //static formAssociated: boolean; protected getFormElement(): HTMLElement | undefined | null; @@ -251,20 +252,18 @@ export function UmbFormControlMixin< } } + #runValidatorsCallback = () => this._runValidators; + /** * @function addFormControlElement * @description Important notice if adding a native form control then ensure that its value and thereby validity is updated when value is changed from the outside. - * @param {UmbNativeFormControlElement} element - element to validate and include as part of this form association. + * @param {UmbNativeFormControlElement} element - element to validate and include as part of this form control association. * @returns {void} */ protected addFormControlElement(element: UmbNativeFormControlElement) { this.#formCtrlElements.push(element); - element.addEventListener(UmbValidationInvalidEvent.TYPE, () => { - this._runValidators(); - }); - element.addEventListener(UmbValidationValidEvent.TYPE, () => { - this._runValidators(); - }); + element.addEventListener(UmbValidationInvalidEvent.TYPE, this.#runValidatorsCallback); + element.addEventListener(UmbValidationValidEvent.TYPE, this.#runValidatorsCallback); // If we are in validationMode/'touched'/not-pristine then we need to validate this newly added control. [NL] if (this._pristine === false) { element.checkValidity(); @@ -273,6 +272,23 @@ export function UmbFormControlMixin< } } + /** + * @function removeFormControlElement + * @param {UmbNativeFormControlElement} element - element to remove as part of this form controls associated controls. + * @returns {void} + */ + protected removeFormControlElement(element: UmbNativeFormControlElement) { + const index = this.#formCtrlElements.indexOf(element); + if (index !== -1) { + this.#formCtrlElements.splice(index, 1); + element.removeEventListener(UmbValidationInvalidEvent.TYPE, this.#runValidatorsCallback); + element.removeEventListener(UmbValidationValidEvent.TYPE, this.#runValidatorsCallback); + if (this._pristine === false) { + this._runValidators(); + } + } + } + private _customValidityObject?: UmbFormControlValidatorConfig; /**