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

Commit 8e5ca2b

Browse files
committed
Validating form relative to fields pending validation in validateFields action. Fixes #395
1 parent 7c52fd7 commit 8e5ca2b

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

src/actions/field-actions.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,24 @@ const validateErrors = trackable((model, errorValidators) => (dispatch, getState
160160
dispatch(setValidity(model, errors, { errors: true }));
161161
});
162162

163+
function isFormValidWithoutFields(form, fieldsValidity) {
164+
if (Object.keys(form.validity).length && !isValid(form.validity)) {
165+
return false;
166+
}
167+
168+
// TODO: map through form keys without $form
169+
const valid = Object.keys(form.fields)
170+
.every((fieldKey) => {
171+
if (fieldsValidity.hasOwnProperty(fieldKey)) {
172+
return true;
173+
}
174+
175+
return form.fields[fieldKey].valid;
176+
});
177+
178+
return valid;
179+
}
180+
163181
const validateFields = trackable((model, fieldValidators, options = {}) => (dispatch, getState) => {
164182
const value = _get(getState(), model);
165183

@@ -179,7 +197,7 @@ const validateFields = trackable((model, fieldValidators, options = {}) => (disp
179197
if (validCB || invalidCB) {
180198
const form = getForm(getState(), model);
181199
const formValid = (form && !fieldsValidity.hasOwnProperty(''))
182-
? form.valid
200+
? isFormValidWithoutFields(form, fieldsValidity)
183201
: true;
184202
const fieldsValid = options.errors
185203
? !isInvalid(fieldsValidity)

test/form-component-spec.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,4 +1497,55 @@ describe('<Form> component', () => {
14971497
assert.equal(timesTwoValidationCalled, 1);
14981498
});
14991499
});
1500+
1501+
describe('submitting after invalid', () => {
1502+
const store = createStore(combineReducers({
1503+
login: modelReducer('login', { username: '' }),
1504+
loginForm: formReducer('login', { username: '' }),
1505+
}), applyMiddleware(thunk));
1506+
let timesCalled = 0;
1507+
const handleSubmit = () => {
1508+
timesCalled++;
1509+
};
1510+
const form = TestUtils.renderIntoDocument(
1511+
<Provider store={store}>
1512+
<Form
1513+
model="login"
1514+
onSubmit={handleSubmit}
1515+
validators={{ username: (val) => !!val }}
1516+
validateOn="submit"
1517+
>
1518+
<Field model="login.username">
1519+
<input />
1520+
</Field>
1521+
</Form>
1522+
</Provider>
1523+
);
1524+
1525+
const formNode = TestUtils.findRenderedDOMComponentWithTag(form, 'form');
1526+
const input = TestUtils.findRenderedDOMComponentWithTag(form, 'input');
1527+
1528+
it('should be invalid after initial submit', () => {
1529+
TestUtils.Simulate.submit(formNode);
1530+
1531+
assert.isFalse(store.getState().loginForm.valid);
1532+
assert.isFalse(store.getState().loginForm.fields.username.valid);
1533+
});
1534+
1535+
it('should submit after found to be valid', () => {
1536+
input.value = 'changed';
1537+
1538+
TestUtils.Simulate.change(input);
1539+
1540+
assert.isFalse(store.getState().loginForm.fields.username.valid,
1541+
'should not be valid yet');
1542+
1543+
TestUtils.Simulate.submit(formNode);
1544+
1545+
assert.isTrue(store.getState().loginForm.valid);
1546+
assert.isTrue(store.getState().loginForm.fields.username.valid);
1547+
1548+
assert.equal(timesCalled, 1);
1549+
});
1550+
});
15001551
});

0 commit comments

Comments
 (0)