Skip to content

Commit 335b24f

Browse files
committed
feat(renderer): introduce initializeOnForm
1 parent 91fe195 commit 335b24f

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

packages/react-form-renderer/src/form-renderer/field-provider.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ import enhancedOnChange from './enhanced-on-change';
66
import { dataTypes } from '../constants';
77

88
class FieldProvider extends Component{
9+
componentDidMount() {
10+
if (this.props.initializeOnMount) {
11+
const initialValue = this.props.initialValue || this.props.formOptions.getFieldState(this.props.name).initial;
12+
this.props.formOptions.change(this.props.name, initialValue);
13+
}
14+
}
15+
916
componentWillUnmount(){
1017
if ((this.props.formOptions.clearOnUnmount || this.props.clearOnUnmount) && this.props.clearOnUnmount !== false) {
1118
this.props.formOptions.change(this.props.name, undefined);
@@ -56,13 +63,16 @@ FieldProvider.propTypes = {
5663
formOptions: PropTypes.shape({
5764
clearOnUnmount: PropTypes.bool,
5865
change: PropTypes.func,
66+
getFieldState: PropTypes.func,
5967
}),
6068
component: PropTypes.oneOfType(PropTypes.node, PropTypes.element, PropTypes.func),
6169
render: PropTypes.func,
6270
children: PropTypes.oneOfType(PropTypes.node, PropTypes.element, PropTypes.func),
6371
dataType: PropTypes.oneOf(Object.values(dataTypes)),
6472
name: PropTypes.string,
6573
clearOnUnmount: PropTypes.bool,
74+
initializeOnMount: PropTypes.bool,
75+
initialValue: PropTypes.any,
6676
};
6777

6878
FieldProvider.defaultProps = {

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

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import renderForm from '../../form-renderer/render-form';
77
import RendererContext from '../../form-renderer/renderer-context';
88
import { components, validators, layoutComponents } from '../../constants';
99
import FormRenderer from '../../form-renderer';
10+
import { componentTypes } from '../..';
1011

1112
describe('renderForm function', () => {
1213
let layoutMapper;
@@ -501,6 +502,7 @@ describe('renderForm function', () => {
501502
{ meta.error && <div><span>{ meta.error }</span></div> }
502503
</div>
503504
);
505+
504506
it('should add formSpy and call update function on each state change', () => {
505507
const onStateUpdate = jest.fn();
506508
const wrapper = mount(
@@ -523,6 +525,172 @@ describe('renderForm function', () => {
523525
wrapper.find('input').last().simulate('change', { target: { value: 'foovalue' }});
524526
expect(onStateUpdate).toHaveBeenCalledTimes(4);
525527
});
528+
});
529+
530+
describe('#initializeOnMount', () => {
531+
const SHOWER_FIELD = 'shower_FIELD';
532+
const INITIALIZED_FIELD = 'initialized_FIELD';
533+
const SHOW_VALUE = 'show';
534+
535+
const INITIAL_VALUE = 'some initial value';
536+
const SHOWER_FIELD_INDEX = 0;
537+
const INITIALIZED_FIELD_INDEX = 1;
538+
const NEW_VALUE = 'something different';
539+
const NOT_SHOW_VALUE = 'bla';
540+
const SCHEMA_INITIAL_VALUE = 'schema initial value';
541+
542+
const formFields = (initializeOnMount = false, initialValue) => ({
543+
fields: [{
544+
component: componentTypes.TEXT_FIELD,
545+
name: SHOWER_FIELD,
546+
}, {
547+
component: componentTypes.TEXT_FIELD,
548+
name: INITIALIZED_FIELD,
549+
initializeOnMount,
550+
initialValue,
551+
condition: {
552+
when: SHOWER_FIELD,
553+
is: SHOW_VALUE,
554+
},
555+
}],
556+
});
526557

558+
const TextField = ({ input, meta, formOptions, ...rest }) => (
559+
<div>
560+
<input { ...input } { ...rest } />
561+
</div>
562+
);
563+
564+
const updateInput = (wrapper, position, value) => {
565+
wrapper.find('input').at(position).simulate('change', { target: { value }});
566+
wrapper.update();
567+
};
568+
569+
const getFormValue = (wrapper, name) =>
570+
wrapper.find(Form).instance().form.getState().values[name];
571+
572+
const mountInitializedField = (wrapper) => updateInput(wrapper, SHOWER_FIELD_INDEX, SHOW_VALUE);
573+
const unmountInitializedField = (wrapper) => updateInput(wrapper, SHOWER_FIELD_INDEX, NOT_SHOW_VALUE);
574+
const setInitializedToNewValue = (wrapper) => updateInput(wrapper, INITIALIZED_FIELD_INDEX, NEW_VALUE);
575+
const expectNewValue = (wrapper) => expect(getFormValue(wrapper, INITIALIZED_FIELD)).toEqual(NEW_VALUE);
576+
const expectInitialValue = (wrapper) => expect(getFormValue(wrapper, INITIALIZED_FIELD)).toEqual(INITIAL_VALUE);
577+
const expectSchemaInitialValue = (wrapper) => expect(getFormValue(wrapper, INITIALIZED_FIELD)).toEqual(SCHEMA_INITIAL_VALUE);
578+
579+
it('should reset value after mount when set on fields', () => {
580+
const SET_INITIALIZE_ON_MOUNT = true;
581+
582+
const wrapper = mount(
583+
<FormRenderer
584+
layoutMapper={ layoutMapper }
585+
formFieldsMapper={{
586+
[components.TEXT_FIELD]: TextField,
587+
}}
588+
schema={ formFields(SET_INITIALIZE_ON_MOUNT) }
589+
onSubmit={ jest.fn() }
590+
initialValues={{
591+
[INITIALIZED_FIELD]: INITIAL_VALUE,
592+
}}
593+
/>
594+
);
595+
596+
expectInitialValue(wrapper);
597+
598+
mountInitializedField(wrapper);
599+
setInitializedToNewValue(wrapper);
600+
601+
expectNewValue(wrapper);
602+
603+
unmountInitializedField(wrapper);
604+
expectNewValue(wrapper);
605+
606+
mountInitializedField(wrapper);
607+
expectInitialValue(wrapper);
608+
});
609+
610+
it('should not reset value after mount when set on fields', () => {
611+
const UNSET_INITIALIZE_ON_MOUNT = false;
612+
613+
const wrapper = mount(
614+
<FormRenderer
615+
layoutMapper={ layoutMapper }
616+
formFieldsMapper={{
617+
[components.TEXT_FIELD]: TextField,
618+
}}
619+
schema={ formFields(UNSET_INITIALIZE_ON_MOUNT) }
620+
onSubmit={ jest.fn() }
621+
initialValues={{
622+
[INITIALIZED_FIELD]: INITIAL_VALUE,
623+
}}
624+
/>
625+
);
626+
627+
expectInitialValue(wrapper);
628+
629+
mountInitializedField(wrapper);
630+
setInitializedToNewValue(wrapper);
631+
632+
expectNewValue(wrapper);
633+
634+
unmountInitializedField(wrapper);
635+
expectNewValue(wrapper);
636+
637+
mountInitializedField(wrapper);
638+
expectNewValue(wrapper);
639+
});
640+
641+
it('should reset value after mount when set on fields and use initialValue from schema instead of renderer initialValues', () => {
642+
const SET_INITIALIZE_ON_MOUNT = true;
643+
644+
const wrapper = mount(
645+
<FormRenderer
646+
layoutMapper={ layoutMapper }
647+
formFieldsMapper={{
648+
[components.TEXT_FIELD]: TextField,
649+
}}
650+
schema={ formFields(SET_INITIALIZE_ON_MOUNT, SCHEMA_INITIAL_VALUE) }
651+
onSubmit={ jest.fn() }
652+
initialValues={{
653+
[INITIALIZED_FIELD]: INITIAL_VALUE,
654+
}}
655+
/>
656+
);
657+
658+
mountInitializedField(wrapper);
659+
setInitializedToNewValue(wrapper);
660+
661+
expectNewValue(wrapper);
662+
663+
unmountInitializedField(wrapper);
664+
expectNewValue(wrapper);
665+
666+
mountInitializedField(wrapper);
667+
expectSchemaInitialValue(wrapper);
668+
});
669+
670+
it('should reset value after mount when set on fields and use initialValue from schema', () => {
671+
const SET_INITIALIZE_ON_MOUNT = true;
672+
673+
const wrapper = mount(
674+
<FormRenderer
675+
layoutMapper={ layoutMapper }
676+
formFieldsMapper={{
677+
[components.TEXT_FIELD]: TextField,
678+
}}
679+
schema={ formFields(SET_INITIALIZE_ON_MOUNT, SCHEMA_INITIAL_VALUE) }
680+
onSubmit={ jest.fn() }
681+
/>
682+
);
683+
684+
mountInitializedField(wrapper);
685+
setInitializedToNewValue(wrapper);
686+
687+
expectNewValue(wrapper);
688+
689+
unmountInitializedField(wrapper);
690+
expectNewValue(wrapper);
691+
692+
mountInitializedField(wrapper);
693+
expectSchemaInitialValue(wrapper);
694+
});
527695
});
528696
});

0 commit comments

Comments
 (0)