Skip to content

Commit

Permalink
feat(Forms): deprecate filterSubmitData in Form.Handler and return `f…
Browse files Browse the repository at this point in the history
…ilterData` in onSubmit and onChange instead (#3873)

The property `filterSubmitData` on the `Form.Handler` was a way to
define a filter, so data returned in the `onSubmit` got filtered.

But I think we rather should return the filter function and let devs do
it right where it happens. We do that already in `useData` and in
`getData` that way. And now we also return `filterData` in the
`onChange` event.

The motivation is to keep consistency and rather offer declarative ways
of defining filters.

---------

Co-authored-by: Anders <[email protected]>
  • Loading branch information
tujoworker and langz authored Aug 28, 2024
1 parent 645a7b3 commit f05bdd2
Show file tree
Hide file tree
Showing 33 changed files with 976 additions and 572 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,3 @@ import { ProviderEvents } from '@dnb/eufemia/src/extensions/forms/DataContext/Pr
## Events

<PropertiesTable props={ProviderEvents} />

### onSubmit parameters

The `onSubmit` event returns additional methods to can call:

- `resetForm` Deletes `sessionStorage` and browser stored autocomplete data.
- `clearData` Empties the given/internal data set.

```jsx
render(
<Form.Handler
onSubmit={(data, { resetForm, clearData }) => {
resetForm()
clearData()
}}
sessionStorageId="session-key"
>
<Form.SubmitButton />
</Form.Handler>,
)
```
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,9 @@ export const FilterData = () => {
return (
<Form.Handler
id={id}
onSubmit={(data) => console.log('onSubmit', data)}
filterSubmitData={filterDataHandler}
onSubmit={(data, { filterData }) => {
console.log('onSubmit', filterData(filterDataHandler))
}}
>
<Flex.Stack>
<Field.Boolean label="Disabled" path="/disabled" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,12 @@ This example is only for demo purpose and will NOT redirect to a new location. I

### Filter your data

By using the `filterSubmitData` prop you can filter out data that you don't want to send to your server.
By using the `filterData` method from the `onSubmit` event callback you can filter out data that you don't want to send to your server.

It will filter out data from the `onSubmit` event property.
More info about `filterData` can be found in the [Getting Started](/uilib/extensions/forms/getting-started/#filter-data) section.

In this example we filter out all fields that are disabled.

More info about `filterData` can be found in the [Getting Started](/uilib/extensions/forms/getting-started/#filter-data) section.

<Examples.FilterData />

### With session storage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ It will flush the storage once the form gets submitted.

## Filter data

You can use the `filterSubmitData` method to filter your `onSubmit` data. It might be useful, for example, to **exclude disabled fields** or filter out empty fields. The callback function receives the following arguments:
You can use the `filterData` method to filter your `onSubmit` data. It might be useful, for example, to **exclude disabled fields** or filter out empty fields. The callback function receives the following arguments:

1. `path` as the first argument.
2. `value` as the second argument.
Expand All @@ -142,8 +142,42 @@ It returns the filtered form data.

The [useData](/uilib/extensions/forms/Form/useData/#filter-data) hook and the [getData](/uilib/extensions/forms/Form/getData/#filter-data) method also returns a `filterData` function you can use to filter data the same way.

In the demo section is an example of how to use the `filterSubmitData` method.
In the demo section is an example of how to use the `filterData` method.

### Filter arrays

You can filter arrays by using the `filterSubmitData` method. You can find more information about this in the [Iterate.Array](/uilib/extensions/forms/Iterate/Array/#filter-data) docs.
You can filter arrays by using the `filterData` method. You can find more information about this in the [Iterate.Array](/uilib/extensions/forms/Iterate/Array/#filter-data) docs.

### onSubmit parameters

The `onSubmit` event returns additional methods you can call:

- `filterData` Filters the given/internal data set.
- `resetForm` Deletes `sessionStorage` and browser stored autocomplete data.
- `clearData` Empties the given/internal data set.

```jsx
import { Form } from '@dnb/eufemia/extensions/forms'

const myFilter = {
'/myPath': (value) => {
return value.length > 0
},
}

const MyForm = () => {
return (
<Form.Handler
onSubmit={(data, { filterData, resetForm, clearData }) => {
resetForm()
clearData()

const myData = filterData(myFilter)
}}
sessionStorageId="session-key"
>
<Form.SubmitButton />
</Form.Handler>
)
}
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import ComponentBox from '../../../../../../shared/tags/ComponentBox'
import { Section } from '@dnb/eufemia/src'
import { Form, Field, Value } from '@dnb/eufemia/src/extensions/forms'
import { Flex, Section } from '@dnb/eufemia/src'
import { Form, Field } from '@dnb/eufemia/src/extensions/forms'

export function Default() {
return (
Expand Down Expand Up @@ -31,7 +31,11 @@ export function FilterData() {
{() => {
// Method A (if you know the paths)
const filterDataPaths = {
'/foo': ({ value }) => value !== 'bar',
'/foo': ({ value }) => {
if (value === 'foo') {
return false
}
},
}

// Method B (will iterate over all fields regardless of the path)
Expand All @@ -44,24 +48,24 @@ export function FilterData() {
const Component = () => {
return (
<Form.Handler id="filter-data">
<Value.String path="/foo" value="foo" />{' '}
<Value.String path="/bar" value="baz" />
<Flex.Stack>
<Field.String path="/foo" value="foo" />
<Field.String path="/bar" value="bar" />
</Flex.Stack>
</Form.Handler>
)
}

const { data, filterData } = Form.getData('filter-data')
const { filterData } = Form.getData('filter-data')

return (
<>
<Flex.Stack>
<Component />

<Section backgroundColor="sand-yellow" innerSpace>
<pre>{JSON.stringify(data)}</pre>
<pre>{JSON.stringify(filterData(filterDataPaths))}</pre>
<pre>{JSON.stringify(filterData(filterDataHandler))}</pre>
</Section>
</>
</Flex.Stack>
)
}}
</ComponentBox>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ import * as Examples from './Examples'

<Examples.Default />

### Filter data
### Filter your data

<Examples.FilterData />
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Related helpers:

You can use the `filterData` method to filter your data.

You simply give it the same kind of callback function as you would with the `Form.Handler` [filterSubmitData](/uilib/extensions/forms/Form/Handler/demos/#filter-your-data) property method.
You simply give it the [same kind of filter](/uilib/extensions/forms/Form/Handler/demos/#filter-your-data) as you would within the `onSubmit` event callback.

The callback function receives the following arguments:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ export function FilterData() {
/>
</Form.Visibility>
</Form.Visibility>
</Flex.Stack>

<Output />
<Output />
</Flex.Stack>
</Form.Handler>
)
}
Expand All @@ -170,9 +170,13 @@ export function FilterData() {
>
<ScrollView>
<pre>
Filtered: {JSON.stringify(filterData(filterDataPaths))}
Filtered: <br />
{JSON.stringify(filterData(filterDataPaths), null, 2)}
</pre>
<pre>
All data: <br />
{JSON.stringify(data, null, 2)}
</pre>
<pre>All data: {JSON.stringify(data)}</pre>
</ScrollView>
</Section>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function MyForm() {

You can use the `filterData` method to filter your data. Check out [the example below](#filter-your-data).

You simply give it the same kind of callback function as you would with the `Form.Handler` [filterSubmitData](/uilib/extensions/forms/Form/Handler/demos/#filter-your-data) property method.
You simply give it the [same kind of filter](/uilib/extensions/forms/Form/Handler/demos/#filter-your-data) as you would within the `onSubmit` event callback.

The callback function receives the following arguments:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,21 @@ In the example below, the data given in `onSubmit` will still have "foo2" and "b
```tsx
import { Iterate, Form, Field } from '@dnb/eufemia/extensions/forms'

const filterSubmitData = {
const myFilter = {
'/myList/0': false,
}

render(
<Form.Handler
filterSubmitData={filterSubmitData}
data={{
myList: [
{ foo: 'foo1', bar: 'bar1' },
{ foo: 'foo2', bar: 'bar2' },
],
}}
onSubmit={console.log}
onSubmit={(data, { filterData }) => {
console.log('onSubmit', filterData(myFilter))
}}
>
<Iterate.Array path="/myList">
<Field.String itemPath="/foo" label="Foo no. {itemNr}" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,17 @@ As you can see in the code above, you can even handle the state outside the `For

#### Filter data

The internal data will always contain all the fields, even if they are not visible. But you may want to filter out some data based on your own logic.

You can filter data by any given criteria. This is done by utilizing the `filterData` method from e.g.:
In this seciton we will show how to filter out some data based on your own logic. You can filter data by any given criteria. This is done by utilizing the `filterData` method from e.g.:

- [useData](/uilib/extensions/forms/Form/useData/#filter-data) hook.
- [getData](/uilib/extensions/forms/Form/getData/#filter-data) method.
- [Visibility](/uilib/extensions/forms/Form/Visibility/#filter-data) component.

You can provide either a function handler or an object with the paths (JSON Pointer) you want to filter out.

Return `false` to exclude an entry:
Return `false` to exclude an entry.

Here is an example of how to filter data outlining the different ways to filter data:

```tsx
// 1. Method – by using paths (JSON Pointer)
Expand Down Expand Up @@ -186,7 +186,23 @@ You may check out an [interactive example](/uilib/extensions/forms/Form/useData/

##### Filter data during submit

For filtering data during form submit (`onSubmit`), you can use the `filterSubmitData` property from:
For filtering data during form submit (`onSubmit`), you can use the `filterData` method given as a parameter to the `onSubmit` event callback:

```tsx
const onSubmit = (data, { filterData }) => {
// Same method as in the previous example
const filteredDataA = filterData(filterDataPaths)
const filteredDataB = filterData(filterDataHandler)
console.log(filteredDataA)
console.log(filteredDataB)
}

render(
<Form.Handler onSubmit={onSubmit}>
<Field.String path="/foo" />
</Form.Handler>,
)
```

- [Form.Handler](/uilib/extensions/forms/Form/Handler/)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FieldProps,
FormError,
ValueProps,
OnChange,
} from '../types'
import { Props as ProviderProps } from './Provider'

Expand Down Expand Up @@ -94,7 +95,7 @@ export interface ContextState {
handleUnMountField: (path: Path) => void
setFormState?: (state: SubmitState) => void
setSubmitState?: (state: EventStateObject) => void
addOnChangeHandler?: (callback: (data: unknown) => void) => void
addOnChangeHandler?: (callback: OnChange) => void
handleSubmitCall: ({
onSubmit,
enableAsyncBehaviour,
Expand Down
Loading

0 comments on commit f05bdd2

Please sign in to comment.