Skip to content

Commit

Permalink
feat: implement formFieldInstanceRegistry
Browse files Browse the repository at this point in the history
Related to #1142
  • Loading branch information
Skaiir committed Apr 11, 2024
1 parent 49c2856 commit 29e50cb
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
66 changes: 66 additions & 0 deletions packages/form-js-viewer/src/core/FormFieldInstanceRegistry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
export class FormFieldInstanceRegistry {
constructor(eventBus, formFieldRegistry, formFields) {
this._eventBus = eventBus;
this._formFieldRegistry = formFieldRegistry;
this._formFields = formFields;

this._formFieldInstances = {};

eventBus.on('form.clear', () => this.clear());
}

add(instance) {

const {
id,
expressionContextInfo,
valuePath,
indexes
} = instance;

const instanceId = [ id, ...Object.values(indexes || {}) ].join('_');

if (this._formFieldInstances[ instanceId ]) {
throw new Error('this form field instance is already registered');
}

this._formFieldInstances[ instanceId ] = {
id,
instanceId,
expressionContextInfo,
valuePath,
indexes
};

return instanceId;
}

remove(instanceId) {

if (!this._formFieldInstances[ instanceId ]) {
return;
}

delete this._formFieldInstances[ instanceId ];
}

getAll() {
return Object.values(this._formFieldInstances);
}

getAllKeyed() {
return this.getAll().filter(({ id }) => {
const { type } = this._formFieldRegistry.get(id);
const { config } = this._formFields.get(type);

return config.keyed;
});
}

clear() {
this._formFieldInstances = {};
}

}

FormFieldInstanceRegistry.$inject = [ 'eventBus', 'formFieldRegistry', 'formFields' ];
2 changes: 2 additions & 0 deletions packages/form-js-viewer/src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { FieldFactory } from './FieldFactory';
import { PathRegistry } from './PathRegistry';
import { FormLayouter } from './FormLayouter';
import { FormFieldRegistry } from './FormFieldRegistry';
import { FormFieldInstanceRegistry } from './FormFieldInstanceRegistry';

import { RenderModule } from '../render';

Expand All @@ -16,6 +17,7 @@ export const CoreModule = {
importer: [ 'type', Importer ],
fieldFactory: [ 'type', FieldFactory ],
formFieldRegistry: [ 'type', FormFieldRegistry ],
formFieldInstanceRegistry: [ 'type', FormFieldInstanceRegistry ],
pathRegistry: [ 'type', PathRegistry ],
formLayouter: [ 'type', FormLayouter ],
validator: [ 'type', Validator ]
Expand Down
20 changes: 19 additions & 1 deletion packages/form-js-viewer/src/render/components/FormField.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import isEqual from 'lodash/isEqual';

import { get } from 'min-dash';

import { FormContext, FormRenderContext } from '../context';
import { FormContext, FormRenderContext, LocalExpressionContext } from '../context';

import {
useCondition,
Expand All @@ -25,6 +25,7 @@ export function FormField(props) {

const formFields = useService('formFields'),
viewerCommands = useService('viewerCommands', false),
formFieldInstanceRegistry = useService('formFieldInstanceRegistry', false),
pathRegistry = useService('pathRegistry'),
eventBus = useService('eventBus'),
form = useService('form');
Expand Down Expand Up @@ -56,6 +57,7 @@ export function FormField(props) {

const fieldConfig = FormFieldComponent.config;

const localExpressionContext = useContext(LocalExpressionContext);
const valuePath = useMemo(() => pathRegistry.getValuePath(field, { indexes }), [ field, indexes, pathRegistry ]);

const initialValue = useMemo(() => get(initialData, valuePath), [ initialData, valuePath ]);
Expand All @@ -69,6 +71,22 @@ export function FormField(props) {
properties.disabled || field.disabled || false
);

// register form field instance
useEffect(() => {
if (formFieldInstanceRegistry) {
const instanceId = formFieldInstanceRegistry.add({
id: field.id,
expressionContextInfo: localExpressionContext,
valuePath,
indexes
});

return () => {
formFieldInstanceRegistry.remove(instanceId);
};
}
}, [ formFieldInstanceRegistry, field.id, localExpressionContext, valuePath, indexes ]);

// ensures the initial validation behavior can be re-triggered upon form reset
useEffect(() => {

Expand Down

0 comments on commit 29e50cb

Please sign in to comment.