Skip to content

Commit 33ae737

Browse files
2 parents d8cd404 + cd37020 commit 33ae737

17 files changed

+729
-201
lines changed

bower.json

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,25 @@
11
{
22
"name": "formsy-react",
3-
"version": "0.12.4",
3+
"version": "0.12.5",
4+
"description": "A form input builder and validator for React JS",
5+
"repository": {
6+
"type": "git",
7+
"url": "https://github.com/christianalfoni/formsy-react.git"
8+
},
49
"main": "src/main.js",
10+
"license": "MIT",
11+
"ignore": [
12+
"build/",
13+
"Gulpfile.js"
14+
],
515
"dependencies": {
616
"react": "^0.13.1"
7-
}
17+
},
18+
"keywords": [
19+
"react",
20+
"form",
21+
"forms",
22+
"validation",
23+
"react-component"
24+
]
825
}

package.json

Lines changed: 8 additions & 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",
@@ -13,6 +13,13 @@
1313
},
1414
"author": "Christian Alfoni",
1515
"license": "MIT",
16+
"keywords": [
17+
"react",
18+
"form",
19+
"forms",
20+
"validation",
21+
"react-component"
22+
],
1623
"devDependencies": {
1724
"browserify": "^6.2.0",
1825
"glob": "^4.0.6",

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-
_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/Rules-equals-spec.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var Formsy = require('./../src/main.js');
2+
3+
describe('Rules: equals', function() {
4+
var TestInput, isValid, form, input;
5+
6+
beforeEach(function() {
7+
isValid = jasmine.createSpy('valid');
8+
9+
TestInput = React.createClass({
10+
mixins: [Formsy.Mixin],
11+
updateValue: function (event) {
12+
this.setValue(event.target.value);
13+
},
14+
render: function () {
15+
if (this.isValid()) {
16+
isValid();
17+
}
18+
return <input value={this.getValue()} onChange={this.updateValue}/>
19+
}
20+
});
21+
22+
form = TestUtils.renderIntoDocument(
23+
<Formsy.Form>
24+
<TestInput name="foo" validations="equals:myValue"/>
25+
</Formsy.Form>
26+
);
27+
28+
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
29+
30+
});
31+
32+
afterEach(function() {
33+
TestInput = isValid = isInvalid = form = null;
34+
});
35+
36+
it('should fail with undefined', function () {
37+
expect(isValid).not.toHaveBeenCalled();
38+
TestUtils.Simulate.change(input, {target: {value: undefined}});
39+
expect(isValid).not.toHaveBeenCalled();
40+
});
41+
42+
it('should fail with null', function () {
43+
expect(isValid).not.toHaveBeenCalled();
44+
TestUtils.Simulate.change(input, {target: {value: null}});
45+
expect(isValid).not.toHaveBeenCalled();
46+
});
47+
48+
it('should fail when the value is not equal', function () {
49+
expect(isValid).not.toHaveBeenCalled();
50+
TestUtils.Simulate.change(input, {target: {value: 'foo'}});
51+
expect(isValid).not.toHaveBeenCalled();
52+
});
53+
54+
it('should pass when the value is equal', function () {
55+
expect(isValid).not.toHaveBeenCalled();
56+
TestUtils.Simulate.change(input, {target: {value: 'myValue'}});
57+
expect(isValid).toHaveBeenCalled();
58+
});
59+
60+
});

specs/Rules-hasValue-spec.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
var Formsy = require('./../src/main.js');
2+
3+
describe('Rules: hasValue', function() {
4+
var TestInput, isValid, form, input;
5+
6+
beforeEach(function() {
7+
isValid = jasmine.createSpy('valid');
8+
9+
TestInput = React.createClass({
10+
mixins: [Formsy.Mixin],
11+
updateValue: function (event) {
12+
this.setValue(event.target.value);
13+
},
14+
render: function () {
15+
if (this.isValid()) {
16+
isValid();
17+
}
18+
return <input value={this.getValue()} onChange={this.updateValue}/>
19+
}
20+
});
21+
22+
form = TestUtils.renderIntoDocument(
23+
<Formsy.Form>
24+
<TestInput name="foo" validations="hasValue"/>
25+
</Formsy.Form>
26+
);
27+
28+
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
29+
30+
});
31+
32+
afterEach(function() {
33+
TestInput = isValid = isInvalid = form = null;
34+
});
35+
36+
it('should fail with undefined', function () {
37+
expect(isValid).not.toHaveBeenCalled();
38+
TestUtils.Simulate.change(input, {target: {value: undefined}});
39+
expect(isValid).not.toHaveBeenCalled();
40+
});
41+
42+
it('should fail with null', function () {
43+
expect(isValid).not.toHaveBeenCalled();
44+
TestUtils.Simulate.change(input, {target: {value: null}});
45+
expect(isValid).not.toHaveBeenCalled();
46+
});
47+
48+
it('should pass with a string', function () {
49+
expect(isValid).not.toHaveBeenCalled();
50+
TestUtils.Simulate.change(input, {target: {value: 'myValue'}});
51+
expect(isValid).toHaveBeenCalled();
52+
});
53+
54+
});

specs/Rules-isAlpha-spec.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
var Formsy = require('./../src/main.js');
2+
3+
describe('Rules: isAlpha', function() {
4+
var TestInput, isValid, form, input;
5+
6+
beforeEach(function() {
7+
isValid = jasmine.createSpy('valid');
8+
9+
TestInput = React.createClass({
10+
mixins: [Formsy.Mixin],
11+
updateValue: function (event) {
12+
this.setValue(event.target.value);
13+
},
14+
render: function () {
15+
if (this.isValid()) {
16+
isValid();
17+
}
18+
return <input value={this.getValue()} onChange={this.updateValue}/>
19+
}
20+
});
21+
22+
form = TestUtils.renderIntoDocument(
23+
<Formsy.Form>
24+
<TestInput name="foo" validations="isAlpha"/>
25+
</Formsy.Form>
26+
);
27+
28+
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
29+
30+
});
31+
32+
afterEach(function() {
33+
TestInput = isValid = isInvalid = form = null;
34+
});
35+
36+
it('should fail with undefined', function () {
37+
expect(isValid).not.toHaveBeenCalled();
38+
TestUtils.Simulate.change(input, {target: {value: undefined}});
39+
expect(isValid).not.toHaveBeenCalled();
40+
});
41+
42+
it('should fail with null', function () {
43+
expect(isValid).not.toHaveBeenCalled();
44+
TestUtils.Simulate.change(input, {target: {value: null}});
45+
expect(isValid).not.toHaveBeenCalled();
46+
});
47+
48+
it('should fail with a number', function () {
49+
expect(isValid).not.toHaveBeenCalled();
50+
TestUtils.Simulate.change(input, {target: {value: 123}});
51+
expect(isValid).not.toHaveBeenCalled();
52+
});
53+
54+
it('should pass with a string', function () {
55+
expect(isValid).not.toHaveBeenCalled();
56+
TestUtils.Simulate.change(input, {target: {value: 'myValue'}});
57+
expect(isValid).toHaveBeenCalled();
58+
});
59+
60+
});

specs/Rules-isEmail-spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
var Formsy = require('./../src/main.js');
2+
3+
describe('Rules: isEmail', function() {
4+
var TestInput, isValid, form, input;
5+
6+
beforeEach(function() {
7+
isValid = jasmine.createSpy('valid');
8+
9+
TestInput = React.createClass({
10+
mixins: [Formsy.Mixin],
11+
updateValue: function (event) {
12+
this.setValue(event.target.value);
13+
},
14+
render: function () {
15+
if (this.isValid()) {
16+
isValid();
17+
}
18+
return <input value={this.getValue()} onChange={this.updateValue}/>
19+
}
20+
});
21+
22+
form = TestUtils.renderIntoDocument(
23+
<Formsy.Form>
24+
<TestInput name="foo" value="foo" validations="isEmail"/>
25+
</Formsy.Form>
26+
);
27+
28+
input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT');
29+
30+
});
31+
32+
afterEach(function() {
33+
TestInput = isValid = isInvalid = form = null;
34+
});
35+
36+
it('should fail with "foo"', function () {
37+
expect(isValid).not.toHaveBeenCalled();
38+
TestUtils.Simulate.change(input, {target: {value: 'foo'}});
39+
expect(isValid).not.toHaveBeenCalled();
40+
});
41+
42+
it('should pass with "foo@foo.com"', function () {
43+
expect(isValid).not.toHaveBeenCalled();
44+
TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}});
45+
expect(isValid).toHaveBeenCalled();
46+
});
47+
48+
});

0 commit comments

Comments
 (0)