diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/Examples.tsx
index 866b463be8b..60c2e8e1713 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/Examples.tsx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/Examples.tsx
@@ -408,7 +408,9 @@ export const TransformData = () => {
const transformedData = transformData(
data,
({ value, displayValue, label }) => {
- return { value, displayValue, label }
+ if (!Array.isArray(value)) {
+ return { value, displayValue, label }
+ }
},
)
diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/info.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/info.mdx
index 049f4cb2ad4..97fa2010338 100644
--- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/info.mdx
+++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler/info.mdx
@@ -339,3 +339,35 @@ The callback function receives the following arguments as an object:
Most of the fields will return the `displayValue` as a string. But there are some exceptions:
- [ArraySelection](/uilib/extensions/forms/base-fields/ArraySelection/) will return the displayed/active options content as an array that contains a string (or React.ReactNode).
+
+##### `displayValue` from fields inside Iterate.Array
+
+When using the `Iterate.Array` component, you may check if the current entry is an array. This way you ensure you never transform the array itself, but only the values from the fields inside the array.
+
+```jsx
+import { Form } from '@dnb/eufemia/extensions/forms'
+
+const MyForm = () => {
+ return (
+
{
+ const transformedData = transformData(
+ data,
+ ({ value, displayValue, label }) => {
+ if (!Array.isArray(value)) {
+ return { value, displayValue, label }
+ }
+ },
+ )
+ }}
+ >
+
+
+
+
+
+
+
+ )
+}
+```
diff --git a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/Provider.tsx b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/Provider.tsx
index e584077c70c..4e405c32c10 100644
--- a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/Provider.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/Provider.tsx
@@ -424,8 +424,13 @@ export default function Provider(
* Mutate the data set based on the filterData function
*/
const mutateDataHandler = useCallback(
- (data: Data, handler: TransformData | FilterData, remove = false) => {
- const mutate = (path: Path, result: boolean | unknown) => {
+ (
+ data: Data,
+ handler: TransformData | FilterData,
+ { remove = false, mutate = true } = {}
+ ) => {
+ const freshData = {} as Data
+ const mutateEntry = (path: Path, result: boolean | unknown) => {
if (remove) {
if (result === false) {
data = structuredClone(data)
@@ -433,8 +438,12 @@ export default function Provider(
}
} else {
if (typeof result !== 'undefined') {
- data = structuredClone(data)
- pointer.set(data, path, result)
+ if (mutate) {
+ data = structuredClone(data)
+ pointer.set(data, path, result)
+ } else {
+ pointer.set(freshData, path, result)
+ }
}
}
}
@@ -458,11 +467,15 @@ export default function Provider(
props,
internal,
})
- mutate(path, result)
+ mutateEntry(path, result)
}
}
)
+ if (!mutate) {
+ return freshData
+ }
+
return data
} else if (handler) {
const runFilter = ({ path, condition }) => {
@@ -480,7 +493,7 @@ export default function Provider(
internal,
})
: condition
- mutate(path, result)
+ mutateEntry(path, result)
}
}
@@ -567,7 +580,7 @@ export default function Provider(
const filterDataHandler = useCallback(
(data: Data, filter: FilterData) => {
if (filter) {
- return mutateDataHandler(data, filter, true)
+ return mutateDataHandler(data, filter, { remove: true })
}
return data
@@ -1176,7 +1189,7 @@ export default function Provider(
}
const transformData = (data: Data, handler: TransformData) => {
- return mutateDataHandler(data, handler)
+ return mutateDataHandler(data, handler, { mutate: false })
}
const formElement = formElementRef.current
diff --git a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx
index 0de80d238f4..2281a12c80f 100644
--- a/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx
+++ b/packages/dnb-eufemia/src/extensions/forms/DataContext/Provider/__tests__/Provider.test.tsx
@@ -23,6 +23,7 @@ import {
OnChange,
DataValueWriteProps,
OnSubmit,
+ Iterate,
} from '../../../'
import { isCI } from 'repo-utils'
import { Props as StringFieldProps } from '../../../Field/String'
@@ -4883,6 +4884,70 @@ describe('DataContext.Provider', () => {
})
})
+ it('should transform data with "transformData" from fields inside Iterate', async () => {
+ let transformedData = undefined
+ const onSubmit = jest.fn((data, { transformData }) => {
+ transformedData = transformData(
+ data,
+ ({ value, displayValue, label }) => {
+ if (!Array.isArray(value)) {
+ return { value, displayValue, label }
+ }
+ }
+ )
+ })
+
+ render(
+
+
+
+
+
+ )
+
+ fireEvent.submit(document.querySelector('form'))
+
+ expect(onSubmit).toHaveBeenCalledTimes(1)
+ expect(transformedData).toEqual({
+ accounts: [
+ {
+ fooPath: {
+ displayValue: 'foo value',
+ label: 'Bar label',
+ value: 'foo value',
+ },
+ },
+ ],
+ })
+
+ const stringField = document.querySelector('input')
+ fireEvent.change(stringField, { target: { value: 'bar value' } })
+
+ fireEvent.submit(document.querySelector('form'))
+
+ expect(onSubmit).toHaveBeenCalledTimes(2)
+ expect(transformedData).toEqual({
+ accounts: [
+ {
+ fooPath: {
+ displayValue: 'bar value',
+ label: 'Bar label',
+ value: 'bar value',
+ },
+ },
+ ],
+ })
+ })
+
describe('reduceToVisibleFields', () => {
it('should remove data entries of hidden fields using Visibility', async () => {
let submitData = null