Skip to content

Commit

Permalink
fix: use field instance validation in viewer core
Browse files Browse the repository at this point in the history
Related to #1147
  • Loading branch information
Skaiir committed Apr 17, 2024
1 parent 8d575f6 commit 9a45332
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 26 deletions.
23 changes: 12 additions & 11 deletions packages/form-js-viewer/src/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,17 +200,19 @@ export class Form {

const getErrorPath = (id, indexes) => [id, ...Object.values(indexes || {})];

formFieldInstanceRegistry.getAllKeyed().forEach(({ id, valuePath, indexes }) => {
formFieldInstanceRegistry.getAllKeyed().forEach((fieldInstance) => {
const { id, valuePath, indexes } = fieldInstance;

const field = formFieldRegistry.get(id);

// (1) Skip disabled fields
if (field.disabled) {
return;
}

// (2) Validate the field
// (2) Validate the field instance
const value = get(data, valuePath);
const fieldErrors = validator.validateField(field, value);
const fieldErrors = validator.validateFieldInstance(fieldInstance, value);

if (fieldErrors.length) {
set(errors, getErrorPath(field.id, indexes), fieldErrors);
Expand Down Expand Up @@ -323,23 +325,22 @@ export class Form {
/**
* @internal
*
* @param { { field: any, indexes: object, value: any } } update
* @param { { fieldInstance: any, value: any } } update
*/
_update(update) {
const { field, indexes, value } = update;
const { fieldInstance, value } = update;

const { data, errors } = this._getState();
const { id, valuePath, indexes } = fieldInstance;

const validator = this.get('validator'),
pathRegistry = this.get('pathRegistry');
const { data, errors } = this._getState();

const fieldErrors = validator.validateField(field, value);
const validator = this.get('validator');

const valuePath = pathRegistry.getValuePath(field, { indexes });
const fieldErrors = validator.validateFieldInstance(fieldInstance, value);

set(data, valuePath, value);

set(errors, [field.id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);
set(errors, [id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);

this._emit('field.updated', update);

Expand Down
36 changes: 21 additions & 15 deletions packages/form-js-viewer/src/render/components/FormField.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { gridColumnClasses, prefixId } from './Util';
const noop = () => false;

export function FormField(props) {
const { field, indexes, onChange } = props;
const { field, indexes, onChange: _onChange } = props;

const formFields = useService('formFields'),
viewerCommands = useService('viewerCommands', false),
Expand Down Expand Up @@ -53,21 +53,26 @@ export function FormField(props) {

const hidden = useCondition((field.conditional && field.conditional.hide) || null);

const fieldInstance = useMemo(
() => ({
id: field.id,
expressionContextInfo: localExpressionContext,
valuePath,
indexes,
}),
[field.id, valuePath, localExpressionContext, indexes],
);

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

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

// ensures the initial validation behavior can be re-triggered upon form reset
useEffect(() => {
Expand Down Expand Up @@ -112,15 +117,16 @@ export function FormField(props) {
eventBus.fire('formField.focus', { formField: field });
}, [eventBus, field]);

const onChangeIndexed = useCallback(
const onChange = useCallback(
(update) => {
// any data change will trigger validation
setInitialValidationTrigger(false);
if (!fieldConfig.keyed) {
return;
}

// add indexes of the keyed field to the update, if any
onChange(fieldConfig.keyed ? { ...update, indexes } : update);
setInitialValidationTrigger(false);
_onChange({ ...update, field, indexes, fieldInstance });
},
[onChange, fieldConfig.keyed, indexes],
[_onChange, field, fieldConfig.keyed, fieldInstance, indexes],
);

if (hidden) {
Expand All @@ -136,7 +142,7 @@ export function FormField(props) {
disabled={disabled}
errors={fieldErrors}
domId={domId}
onChange={disabled || readonly ? noop : onChangeIndexed}
onChange={disabled || readonly ? noop : onChange}
onBlur={disabled || readonly ? noop : onBlur}
onFocus={disabled || readonly ? noop : onFocus}
readonly={readonly}
Expand Down

0 comments on commit 9a45332

Please sign in to comment.