diff --git a/packages/form-js-viewer/src/Form.js b/packages/form-js-viewer/src/Form.js
index 07d7572c4..096bc1a42 100644
--- a/packages/form-js-viewer/src/Form.js
+++ b/packages/form-js-viewer/src/Form.js
@@ -330,24 +330,16 @@ export class Form {
_update(update) {
const { fieldInstance, value } = update;
- const { id, valuePath, indexes } = fieldInstance;
+ const { valuePath } = fieldInstance;
- const { data, errors } = this._getState();
+ const { data: _data } = this._getState();
- const validator = this.get('validator');
+ const data = set(_data, valuePath, value);
+ this._setState({ data: clone(data) });
- const fieldErrors = validator.validateFieldInstance(fieldInstance, value);
-
- set(data, valuePath, value);
-
- set(errors, [id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);
+ this.validate();
this._emit('field.updated', update);
-
- this._setState({
- data: clone(data),
- errors: clone(errors),
- });
}
/**
diff --git a/packages/form-js-viewer/src/features/expressionLanguage/ConditionChecker.js b/packages/form-js-viewer/src/features/expressionLanguage/ConditionChecker.js
index 04a184f61..263313ea0 100644
--- a/packages/form-js-viewer/src/features/expressionLanguage/ConditionChecker.js
+++ b/packages/form-js-viewer/src/features/expressionLanguage/ConditionChecker.js
@@ -1,6 +1,6 @@
import { unaryTest } from 'feelin';
import { get, isString, set, values, isObject } from 'min-dash';
-import { buildExpressionContext, clone } from '../../util';
+import { wrapExpressionContext, clone } from '../../util';
/**
* @typedef {object} Condition
@@ -35,7 +35,7 @@ export class ConditionChecker {
const { conditional, components, id } = field;
// build the expression context in the right format
- const localExpressionContext = buildExpressionContext({
+ const expressionContext = wrapExpressionContext({
this: scopeData,
data: contextData,
i: expressionIndexes,
@@ -43,9 +43,7 @@ export class ConditionChecker {
});
context.isHidden =
- startHidden ||
- context.isHidden ||
- (conditional && this._checkHideCondition(conditional, localExpressionContext));
+ startHidden || context.isHidden || (conditional && this._checkHideCondition(conditional, expressionContext));
// if a field is repeatable and visible, we need to implement custom recursion on its children
if (isRepeatable && !context.isHidden) {
diff --git a/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js b/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js
index 3211ab0a3..b4f7e0518 100644
--- a/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js
+++ b/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js
@@ -3,14 +3,13 @@
import { get } from 'min-dash';
import { useContext, useMemo, useRef } from 'preact/hooks';
-import { LocalExpressionContext } from '../../render/context/LocalExpressionContext';
+import { ExpressionContextInfo } from '../../render/context/ExpressionContextInfo';
import ExpandSvg from '../../render/components/form-fields/icons/Expand.svg';
import CollapseSvg from '../../render/components/form-fields/icons/Collapse.svg';
import AddSvg from '../../render/components/form-fields/icons/Add.svg';
import DeleteSvg from '../../render/components/form-fields/icons/Delete.svg';
-import { buildExpressionContext } from '../../util';
import { useScrollIntoView } from '../../render/hooks';
import classNames from 'classnames';
@@ -48,8 +47,8 @@ export class RepeatRenderManager {
const { data } = this._form._getState();
const repeaterField = props.field;
- const dataPath = this._pathRegistry.getValuePath(repeaterField, { indexes });
- const values = get(data, dataPath) || [];
+ const valuePath = this._pathRegistry.getValuePath(repeaterField, { indexes });
+ const values = get(data, valuePath) || [];
const nonCollapsedItems = this._getNonCollapsedItems(repeaterField);
const collapseEnabled = !repeaterField.disableCollapse && values.length > nonCollapsedItems;
@@ -71,7 +70,7 @@ export class RepeatRenderManager {
});
};
- const parentExpressionContextInfo = useContext(LocalExpressionContext);
+ const parentExpressionContextInfo = useContext(ExpressionContextInfo);
return (
<>
@@ -81,6 +80,7 @@ export class RepeatRenderManager {
itemIndex={itemIndex}
itemValue={itemValue}
parentExpressionContextInfo={parentExpressionContextInfo}
+ parentValuePath={valuePath}
repeaterField={repeaterField}
RowsRenderer={RowsRenderer}
indexes={indexes}
@@ -196,6 +196,7 @@ export class RepeatRenderManager {
* @param {number} props.itemIndex
* @param {Object} props.itemValue
* @param {Object} props.parentExpressionContextInfo
+ * @param {string} props.parentValuePath
* @param {Object} props.repeaterField
* @param {Function} props.RowsRenderer
* @param {Object} props.indexes
@@ -208,6 +209,7 @@ const RepetitionScaffold = (props) => {
itemIndex,
itemValue,
parentExpressionContextInfo,
+ parentValuePath,
repeaterField,
RowsRenderer,
indexes,
@@ -224,26 +226,30 @@ const RepetitionScaffold = (props) => {
[itemIndex, indexes, repeaterField.id, restProps],
);
- const localExpressionContextInfo = useMemo(
+ const expressionContextInfo = useMemo(
() => ({
- data: parentExpressionContextInfo.data,
- this: itemValue,
- parent: buildExpressionContext(parentExpressionContextInfo),
- i: [...parentExpressionContextInfo.i, itemIndex + 1],
+ ...parentExpressionContextInfo,
+ segments: [
+ ...parentExpressionContextInfo.segments,
+ {
+ path: parentValuePath,
+ index: itemIndex,
+ },
+ ],
}),
- [itemIndex, parentExpressionContextInfo, itemValue],
+ [parentExpressionContextInfo, parentValuePath, itemIndex],
);
return !showRemove ? (
-
+
-
+
) : (
-
+
-
+