Skip to content

Commit ff17971

Browse files
committed
fix(renderer): Do not override initial values with set values.
1 parent 1c46635 commit ff17971

File tree

3 files changed

+131
-6
lines changed

3 files changed

+131
-6
lines changed

packages/react-form-renderer/demo/index.js

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,59 @@ import { FormRenderer } from '../src';
66
import FormTemplate from './form-template';
77
import mapper from './form-fields-mapper';
88

9+
const schema = {
10+
title: 'Sequence condition',
11+
fields: [
12+
{
13+
component: 'text-field',
14+
name: 'field-1',
15+
label: 'first name',
16+
},
17+
{
18+
component: 'text-field',
19+
name: 'field-2',
20+
label: 'last name',
21+
},
22+
{
23+
component: 'text-field',
24+
name: 'field-3',
25+
label: 'occupation',
26+
condition: {
27+
sequence: [
28+
{
29+
and: [
30+
{ when: 'field-1', is: 'james' },
31+
{ when: 'field-2', is: 'bond' },
32+
],
33+
then: { set: { 'field-3': 'SPY' } },
34+
else: { visible: true },
35+
},
36+
{
37+
and: [
38+
{ when: 'field-1', is: 'steve' },
39+
{ when: 'field-2', is: 'jobs' },
40+
],
41+
then: { set: { 'field-3': 'CEO' } },
42+
else: { visible: true },
43+
},
44+
],
45+
},
46+
},
47+
],
48+
};
949
const App = () => {
1050
return (
1151
<div style={{ padding: 20 }}>
1252
<FormRenderer
53+
initialValues={{
54+
'field-1': 'steve',
55+
'field-2': 'jobs',
56+
'field-3': 'RETIRED',
57+
}}
1358
componentMapper={mapper}
1459
onSubmit={console.log}
1560
FormTemplate={FormTemplate}
16-
schema={{ fields: [{ component: 'text-field', name: 'text' }] }}
17-
subscription={{ pristine: false }}
61+
schema={schema}
1862
/>
1963
</div>
2064
);

packages/react-form-renderer/src/condition/condition.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,20 @@ const Condition = React.memo(
4747
setters.forEach((setter, index) => {
4848
if (setter && (state.initial || !isEqual(setter, state.sets[index]))) {
4949
setTimeout(() => {
50-
formOptions.batch(() => {
51-
Object.entries(setter).forEach(([name, value]) => {
52-
formOptions.change(name, value);
50+
/**
51+
* We have to get the meta in the timetout to wait for state initialization
52+
*/
53+
const meta = formOptions.getFieldState(field.name);
54+
/**
55+
* Apply setter only on modfied fields or on fields with no initial value.
56+
*/
57+
if (typeof meta.initial === 'undefined' || meta.modified) {
58+
formOptions.batch(() => {
59+
Object.entries(setter).forEach(([name, value]) => {
60+
formOptions.change(name, value);
61+
});
5362
});
54-
});
63+
}
5564
});
5665
}
5766
});

packages/react-form-renderer/src/tests/form-renderer/condition.test.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,78 @@ describe('condition test', () => {
183183
});
184184
});
185185

186+
it('should not override initial value with setter value', async () => {
187+
const schema = {
188+
fields: [
189+
{
190+
component: 'text-field',
191+
name: 'field-1',
192+
label: 'first name',
193+
},
194+
{
195+
component: 'text-field',
196+
name: 'field-2',
197+
label: 'last name',
198+
},
199+
{
200+
component: 'text-field',
201+
name: 'field-3',
202+
label: 'occupation',
203+
condition: {
204+
sequence: [
205+
{
206+
and: [
207+
{ when: 'field-1', is: 'james' },
208+
{ when: 'field-2', is: 'bond' },
209+
],
210+
then: { set: { 'field-3': 'SPY' } },
211+
else: { visible: true },
212+
},
213+
{
214+
and: [
215+
{ when: 'field-1', is: 'steve' },
216+
{ when: 'field-2', is: 'jobs' },
217+
],
218+
then: { set: { 'field-3': 'CEO' } },
219+
else: { visible: true },
220+
},
221+
],
222+
},
223+
},
224+
],
225+
};
226+
227+
render(
228+
<FormRenderer
229+
{...initialProps}
230+
schema={schema}
231+
initialValues={{
232+
'field-1': 'steve',
233+
'field-2': 'jobs',
234+
'field-3': 'RETIRED',
235+
}}
236+
/>
237+
);
238+
239+
await act(async () => {
240+
jest.advanceTimersByTime(1);
241+
});
242+
243+
expect(screen.getByLabelText('field-3')).toBeInTheDocument();
244+
245+
await act(async () => {
246+
jest.advanceTimersByTime(10);
247+
});
248+
249+
userEvent.click(screen.getByText('Submit'));
250+
251+
expect(onSubmit).toHaveBeenCalledWith({
252+
'field-1': 'steve',
253+
'field-2': 'jobs',
254+
'field-3': 'RETIRED',
255+
});
256+
});
257+
186258
it('sets value when condition is fulfill on reset', async () => {
187259
schema = {
188260
fields: [

0 commit comments

Comments
 (0)