Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit 7a69d74

Browse files
committed
Moving validation logic for change after async validity in form for form component. Fixes #706
1 parent 8e622af commit 7a69d74

File tree

5 files changed

+57
-28
lines changed

5 files changed

+57
-28
lines changed

src/components/form-component.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ function createFormClass(s = defaultStrategy) {
151151
if (!formValue) return;
152152

153153
if (!validators && !errors && (modelValue !== nextProps.modelValue)) {
154-
// If the form is invalid (due to async validity)
155-
// but its fields are valid and the value has changed,
156-
// the form should be "valid" again.
157-
if (!formValue.$form.valid && isValid(formValue, { async: false })) {
158-
dispatch(s.actions.setValidity(model, true));
159-
}
160-
161154
return;
162155
}
163156

src/form/is-valid.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ export default function isValid(formState, options = { async: true }) {
3333
.every((key) => isValid(formState[key], options));
3434
}
3535

36-
export function fieldsValid(formState) {
36+
export function fieldsValid(formState, options = { async: true }) {
3737
return Object.keys(formState)
38-
.every((key) => (key === '$form') || isValid(formState[key]));
38+
.every((key) => (key === '$form') || isValid(formState[key], options));
3939
}

src/reducers/form-actions-reducer.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import toPath from '../utils/to-path';
1717
import initialFieldState from '../constants/initial-field-state';
1818
import { fieldOrForm, getMeta, updateFieldState } from '../utils/create-field';
1919
import assocIn from '../utils/assoc-in';
20+
import getFormValue from '../utils/get-form-value';
2021

2122
const resetFieldState = (field, customInitialFieldState) => {
2223
if (!isPlainObject(field)) return field;
@@ -187,7 +188,7 @@ export function createFormActionsReducer(options) {
187188
// If the field is a form, its validity is
188189
// also based on whether its fields are all valid.
189190
const areFieldsValid = (field && field.$form)
190-
? fieldsValid(field)
191+
? fieldsValid(field, { async: false })
191192
: true;
192193

193194
fieldUpdates = {
@@ -343,6 +344,39 @@ export function createFormActionsReducer(options) {
343344
break;
344345
}
345346

347+
case actionTypes.CHANGE: {
348+
return updateParentForms(state, localPath, (parentForm) => {
349+
const formModelValue = getFormValue(parentForm);
350+
351+
if (!parentForm.$form) {
352+
return {
353+
...customInitialFieldState,
354+
value: formModelValue,
355+
initialValue: formModelValue,
356+
};
357+
}
358+
359+
// If the form is invalid (due to async validity)
360+
// but its fields are valid and the value has changed,
361+
// the form should be "valid" again.
362+
if ((!Object.keys(parentForm.$form.validity).length
363+
|| !parentForm.$form.validity)
364+
&& !parentForm.$form.valid
365+
&& isValid(parentForm, { async: false })) {
366+
return {
367+
value: formModelValue,
368+
validity: true,
369+
errors: false,
370+
valid: true,
371+
};
372+
}
373+
374+
return {
375+
value: formModelValue,
376+
};
377+
});
378+
}
379+
346380
default:
347381
return state;
348382
}

src/reducers/form/change-action-reducer.js

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import mapValues from '../../utils/map-values';
77
import { createInitialState } from '../form-reducer';
88
import initialFieldState from '../../constants/initial-field-state';
99
import assocIn from '../../utils/assoc-in';
10+
import getFormValue from '../../utils/get-form-value';
1011
import invariant from 'invariant';
1112

1213
function updateFieldValue(field, action, parentModel = undefined) {
@@ -122,24 +123,6 @@ function updateFieldValue(field, action, parentModel = undefined) {
122123
return i.set(updatedField, '$form', dirtyFormState);
123124
}
124125

125-
function getFormValue(form) {
126-
if (form && !form.$form) {
127-
return typeof form.loadedValue !== 'undefined'
128-
? form.loadedValue
129-
: form.initialValue;
130-
}
131-
132-
const result = mapValues(form, (field, key) => {
133-
if (key === '$form') return undefined;
134-
135-
return getFormValue(field);
136-
});
137-
138-
delete result.$form;
139-
140-
return result;
141-
}
142-
143126
export default function changeActionReducer(state, action, localPath) {
144127
if (action.type !== actionTypes.CHANGE) return state;
145128

src/utils/get-form-value.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import mapValues from './map-values';
2+
3+
export default function getFormValue(form) {
4+
if (form && !form.$form) {
5+
return typeof form.loadedValue !== 'undefined'
6+
? form.loadedValue
7+
: form.initialValue;
8+
}
9+
10+
const result = mapValues(form, (field, key) => {
11+
if (key === '$form') return undefined;
12+
13+
return getFormValue(field);
14+
});
15+
16+
delete result.$form;
17+
18+
return result;
19+
}

0 commit comments

Comments
 (0)