8000 Fixed validation errors using callback · ssejava/formsy-react@4267c40 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4267c40

Browse files
Fixed validation errors using callback
1 parent 7e909fb commit 4267c40

File tree

7 files changed

+106
-19
lines changed

7 files changed

+106
-19
lines changed

bower.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "formsy-react",
3-
"version": "0.12.4",
3+
"version": "0.12.5",
44
"main": "src/main.js",
55
"dependencies": {
66
"react": "^0.13.1"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "formsy-react",
3-
"version": "0.12.4",
3+
"version": "0.12.5",
44
"description": "A form input builder and validator for React JS",
55
"repository": {
66
"type": "git",

release/formsy-react.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ Formsy.Form = React.createClass({displayName: "Form",
7878

7979
// Update model, submit to url prop and send the model
8080
submit: function (event) {
81-
event.preventDefault();
81+
82+
event && event.preventDefault();
8283

8384
// Trigger form as not pristine.
8485
// If any inputs have not been touched yet this will make them dirty
@@ -117,7 +118,7 @@ Formsy.Form = React.createClass({displayName: "Form",
117118
var component = this.inputs[name];
118119
var args = [{
119120
_isValid: !(name in errors),
120-
_serverError: errors[name]
121+
_validationError: errors[name]
121122
}];
122123
component.setState.apply(component, args);
123124
}.bind(this));
@@ -136,7 +137,7 @@ Formsy.Form = React.createClass({displayName: "Form",
136137

137138
var args = [{
138139
_isValid: false,
139-
_validationError: errors[name]
140+
_externalError: errors[name]
140141
}];
141142
component.setState.apply(component, args);
142143
}.bind(this));
@@ -217,15 +218,15 @@ Formsy.Form = React.createClass({displayName: "Form",
217218
component.setState({
218219
_isValid: validation.isValid,
219220
_isRequired: validation.isRequired,
220-
9E7A _validationError: validation.error
221+
_validationError: validation.error,
222+
_externalError: null
221223
}, this.validateForm);
222224

223225
},
224226

225227
// Checks validation on current value or a passed value
226228
runValidation: function (component, value) {
227229

228-
229230
var currentValues = this.getCurrentValues();
230231
var validationErrors = component.props.validationErrors;
231232
var validationError = component.props.validationError;
@@ -241,6 +242,7 @@ Formsy.Form = React.createClass({displayName: "Form",
241242

242243
var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;
243244
var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);
245+
244246
return {
245247
isRequired: isRequired,
246248
isValid: isRequired ? false : isValid,
@@ -360,10 +362,14 @@ Formsy.Form = React.createClass({displayName: "Form",
360362
inputKeys.forEach(function (name, index) {
361363
var component = inputs[name];
362364
var validation = this.runValidation(component);
365+
if (validation.isValid && component.state._externalError) {
366+
validation.isValid = false;
367+
}
363368
component.setState({
364369
_isValid: validation.isValid,
365370
_isRequired: validation.isRequired,
366-
_validationError: validation.error
371+
_validationError: validation.error,
372+
_externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null
367373
}, index === inputKeys.length - 1 ? onValidationComplete : null);
368374
}.bind(this));
369375

@@ -447,7 +453,8 @@ module.exports = {
447453
_isValid: true,
448454
_isPristine: true,
449455
_pristineValue: this.props.value,
450-
_validationError: ''
456+
_validationError: '',
457+
_externalError: null
451458
};
452459
},
453460
getDefaultProps: function () {
@@ -538,7 +545,7 @@ module.exports = {
538545
return this.state._value !== '';
539546
},
540547
getErrorMessage: function () {
541-
return !this.isValid() || this.showRequired() ? this.state._validationError : null;
548+
return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null;
542549
},
543550
isFormDisabled: function () {
544551
return this.props._isFormDisabled();

release/formsy-react.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

specs/Validation-spec.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,79 @@ var Formsy = require('./../src/main.js');
22

33
describe('Validation', function() {
44

5+
it('should reset only changed form element when external error is passed', function (done) {
6+
7+
var onSubmit = function (model, reset, invalidate) {
8+
invalidate({
9+
foo: 'bar',
10+
bar: 'foo'
11+
});
12+
}
13+
var TestInput = React.createClass({
14+
mixins: [Formsy.Mixin],
15+
updateValue: function (event) {
16+
this.setValue(event.target.value);
17+
},
18+
render: function () {
19+
return <input value={this.getValue()} onChange={this.updateValue}/>
20+
}
21+
});
22+
var form = TestUtils.renderIntoDocument(
23+
<Formsy.Form onSubmit={onSubmit}>
24+
<TestInput name="foo"/>
25+
<TestInput name="bar"/>
26+
</Formsy.Form>
27+
);
28+
29+
var input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT')[0];
30+
var inputComponents = TestUtils.scryRenderedComponentsWithType(form, TestInput);
31+
32+
form.submit();
33+
expect(inputComponents[0].isValid()).toBe(false);
34+
expect(inputComponents[1].isValid()).toBe(false);
35+
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
36+
setTimeout(function () {
37+
expect(inputComponents[0].isValid()).toBe(true);
38+
expect(inputComponents[1].isValid()).toBe(false);
39+
done();
40+
}, 0);
41+
});
42+
43+
it('should let normal validation take over when component with external error is ch 566 anged', function (done) {
44+
45+
var onSubmit = function (model, reset, invalidate) {
46+
invalidate({
47+
foo: 'bar'
48+
});
49+
}
50+
var TestInput = React.createClass({
51+
mixins: [Formsy.Mixin],
52+
updateValue: function (event) {
53+
this.setValue(event.target.value);
54+
},
55+
render: function () {
56+
return <input value={this.getValue()} onChange={this.updateValue}/>
57+
}
58+
});
59+
var form = TestUtils.renderIntoDocument(
60+
<Formsy.Form onSubmit={onSubmit}>
61+
<TestInput name="foo" validations="isEmail"/>
62+
</Formsy.Form>
63+
);
64+
65+
var input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
66+
var inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput);
67+
68+
form.submit();
69+
expect(inputComponent.isValid()).toBe(false);
70+
TestUtils.Simulate.change(input, {target: {value: 'bar'}});
71+
setTimeout(function () {
72+
expect(inputComponent.getValue()).toBe('bar');
73+
expect(inputComponent.isValid()).toBe(false);
74+
done();
75+
}, 0);
76+
});
77+
578
it('should trigger an onValid handler, if passed, when form is valid', function () {
679

780
var onValid = jasmine.createSpy('valid');

src/Mixin.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ module.exports = {
3333
_isValid: true,
3434
_isPristine: true,
3535
_pristineValue: this.props.value,
36-
_validationError: ''
36+
_validationError: '',
37+
_externalError: null
3738
};
3839
},
3940
getDefaultProps: function () {
@@ -124,7 +125,7 @@ module.exports = {
124125
return this.state._value !== '';
125126
},
126127
getErrorMessage: function () {
127-
return !this.isValid() || this.showRequired() ? this.state._validationError : null;
128+
return !this.isValid() || this.showRequired() ? (this.state._externalError || this.state._validationError) : null;
128129
},
129130
isFormDisabled: function () {
130131
return this.props._isFormDisabled();

src/main.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ Formsy.Form = React.createClass({
7676

7777
// Update model, submit to url prop and send the model
7878
submit: function (event) {
79-
event.preventDefault();
79+
80+
event && event.preventDefault();
8081

8182
// Trigger form as not pristine.
8283
// If any inputs have not been touched yet this will make them dirty
@@ -115,7 +116,7 @@ Formsy.Form = React.createClass({
115116
var component = this.inputs[name];
116117
var args = [{
117118
_isValid: !(name in errors),
118-
_serverError: errors[name]
119+
_validationError: errors[name]
119120
}];
120121
component.setState.apply(component, args);
121122
}.bind(this));
@@ -134,7 +135,7 @@ Formsy.Form = React.createClass({
134135

135136
var args = [{
136137
_isValid: false,
137-
_validationError: errors[name]
138+
_externalError: errors[name]
138139
}];
139140
component.setState.apply(component, args);
140141
}.bind(this));
@@ -215,15 +216,15 @@ Formsy.Form = React.createClass({
215216
component.setState({
216217
_isValid: validation.isValid,
217218
_isRequired: validation.isRequired,
218-
_validationError: validation.error
219+
_validationError: validation.error,
220+
_externalError: null
219221
}, this.validateForm);
220222

221223
},
222224

223225
// Checks validation on current value or a passed value
224226
runValidation: function (component, value) {
225227

226-
227228
var currentValues = this.getCurrentValues();
228229
var validationErrors = component.props.validationErrors;
229230
var validationError = component.props.validationError;
@@ -239,6 +240,7 @@ Formsy.Form = React.createClass({
239240

240241
var isRequired = Object.keys(component._requiredValidations).length ? !!requiredResults.success.length : false;
241242
var isValid = !validationResults.failed.length && !(this.props.validationErrors && this.props.validationErrors[component.props.name]);
243+
242244
return {
243245
isRequired: isRequired,
244246
isValid: isRequired ? false : isValid,
@@ -358,10 +360,14 @@ Formsy.Form = React.createClass({
358360
inputKeys.forEach(function (name, index) {
359361
var component = inputs[name];
360362
var validation = this.runValidation(component);
363+
if (validation.isValid && component.state._externalError) {
364+
validation.isValid = false;
365+
}
361366
component.setState({
362367
_isValid: validation.isValid,
363368
_isRequired: validation.isRequired,
364-
_validationError: validation.error
369+
_validationError: validation.error,
370+
_externalError: !validation.isValid && component.state._externalError ? component.state._externalError : null
365371
}, index === inputKeys.length - 1 ? onValidationComplete : null);
366372
}.bind(this));
367373

0 commit comments

Comments
 (0)
0