Skip to content

Commit 8d5227c

Browse files
committed
Hacky validation stuff
1 parent f88293b commit 8d5227c

File tree

6 files changed

+155
-23
lines changed

6 files changed

+155
-23
lines changed

comments.json

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,35 @@
88
"id": 1420070400000,
99
"author": "Paul O’Shannessy",
1010
"text": "React is *great*!"
11+
},
12+
{
13+
"id": 1455145027806,
14+
"author": "dfgh",
15+
"text": "dgh"
16+
},
17+
{
18+
"id": 1455145275989,
19+
"author": "dfghdf",
20+
"text": "ghfgjh"
21+
},
22+
{
23+
"id": 1455145280188,
24+
"author": "fghjfgj",
25+
"text": "fgjh"
26+
},
27+
{
28+
"id": 1455152836500,
29+
"author": "sdfgsd",
30+
31+
},
32+
{
33+
"id": 1455154018698,
34+
"author": "sdfg",
35+
36+
},
37+
{
38+
"id": 1455154150577,
39+
"author": "sdfgsdfg",
40+
"text": "sdsdfgsdfgsdf"
1141
}
12-
]
42+
]

components/components.js

Lines changed: 80 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ var templates = require('./templates.jsx');
1414
var React = require('react');
1515
var marked = require('marked');
1616
var $ = require('jquery');
17+
var classNames = require('classnames');
18+
19+
var validation = require('react-validation-mixin');
20+
var Validator = require('validatorjs');
1721

1822
var Comment = React.createClass({
1923
displayName: 'Comment',
@@ -82,27 +86,94 @@ var CommentList = React.createClass({
8286
var CommentForm = React.createClass({
8387
displayName: 'CommentForm',
8488
getInitialState: function () {
89+
// Define the rules and custom messages for each field.
90+
// Do this by creating a validator with no data; it's added later.
91+
this.validatorTypes = new Validator(
92+
{},
93+
{
94+
95+
},
96+
{
97+
'min.text': 'Enter a message between 10 and 50 characters',
98+
'max.text': 'Enter a message between 10 and 50 characters'
99+
}
100+
);
101+
85102
return {author: '', text: ''};
86103
},
104+
addValidation: function(e) {
105+
this.validatorTypes.rules = this.validatorTypes._parseRules({
106+
author: 'required',
107+
text: 'required|min:10|max:50'
108+
});
109+
110+
this.props.handleValidation('author')(e);
111+
this.props.handleValidation('text')(e);
112+
},
87113
handleAuthorChange: function (e) {
88-
this.setState({author: e.target.value});
114+
this.setState({author: e.target.value}, () => {
115+
this.props.handleValidation('author')(e);
116+
});
89117
},
90118
handleTextChange: function (e) {
91-
this.setState({text: e.target.value});
119+
this.setState({text: e.target.value}, () => {
120+
this.props.handleValidation('text')(e);
121+
});
92122
},
93123
handleSubmit: function (e) {
94124
e.preventDefault();
95-
var author = this.state.author.trim();
96-
var text = this.state.text.trim();
97-
if (!text || !author) {
98-
return;
99-
}
100-
this.props.onCommentSubmit({author: author, text: text});
101-
this.setState({author: '', text: ''});
125+
126+
// If the form is valid, then submit the comment
127+
this.props.validate((error) => {
128+
if (!error) {
129+
this.props.onCommentSubmit(this.state);
130+
this.setState({author: '', text: ''});
131+
}
132+
});
133+
},
134+
getValidatorData: function () {
135+
return this.state;
136+
},
137+
getClasses: function (field) {
138+
return classNames({
139+
'has-error': !this.props.isValid(field)
140+
});
102141
},
103142
render: templates.commentForm
104143
});
105144

145+
var strategy = {
146+
/**
147+
* Validate using the validatorjs library
148+
*
149+
* @see https://www.npmjs.com/package/validatorjs
150+
*
151+
* @param {Object} data the data submitted
152+
* @param {Validator} validator the validatorjs validator
153+
* @param {Object} options contains name of element being validated and previous errors
154+
* @param {Function} callback called and passed the errors
155+
*/
156+
validate: function(data, validator, options, callback) {
157+
// Set the data again on the validator and clear existing errors
158+
validator.input = data;
159+
validator.errors.errors = {};
160+
161+
var getErrors = () => {
162+
if (options.key) {
163+
options.prevErrors[options.key] = validator.errors.get(options.key);
164+
callback(options.prevErrors);
165+
} else {
166+
callback(validator.errors.all());
167+
}
168+
};
169+
170+
// Run the validator asynchronously in case any async rules have been added
171+
validator.checkAsync(getErrors, getErrors);
172+
}
173+
};
174+
175+
CommentForm = validation(strategy)(CommentForm);
176+
106177
module.exports = {
107178
Comment,
108179
CommentBox,

components/templates.jsx

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,43 @@ module.exports = {
3636
);
3737
},
3838
commentForm: function () {
39+
function renderErrors(messages) {
40+
if (messages.length) {
41+
messages = messages.map((message) => <li>{message}</li>);
42+
43+
return <ul class="errors">{messages}</ul>;
44+
}
45+
}
46+
3947
return (
4048
<form className="commentForm" onSubmit={this.handleSubmit}>
41-
<input
42-
type="text"
43-
placeholder="Your name"
44-
value={this.state.author}
45-
onChange={this.handleAuthorChange}
49+
<p>
50+
<input
51+
type="text"
52+
placeholder="Your name"
53+
className={this.getClasses('author')}
54+
value={this.state.author}
55+
onChange={this.handleAuthorChange}
56+
onBlur={this.addValidation}
4657
/>
47-
<input
48-
type="text"
49-
placeholder="Say something..."
50-
value={this.state.text}
51-
onChange={this.handleTextChange}
58+
</p>
59+
60+
{renderErrors(this.props.getValidationMessages('author'))}
61+
62+
<p>
63+
<input
64+
type="text"
65+
placeholder="Say something..."
66+
className={this.getClasses('text')}
67+
value={this.state.text}
68+
onChange={this.handleTextChange}
69+
onBlur={this.addValidation}
70+
5271
/>
72+
</p>
73+
74+
{renderErrors(this.props.getValidationMessages('text'))}
75+
5376
<input type="submit" value="Post" />
5477
</form>
5578
);

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
"main": "server.js",
66
"dependencies": {
77
"body-parser": "^1.4.3",
8+
"classnames": "^2.2.3",
89
"express": "^4.4.5",
10+
"install": "^0.4.2",
911
"jquery": "^2.2.0",
1012
"marked": "^0.3.5",
1113
"node-jsx": "^0.13.3",
1214
"react": "^0.14.7",
1315
"react-dom": "^0.14.7",
14-
"swig": "^1.4.2"
16+
"react-validation-mixin": "^5.3.4",
17+
"swig": "^1.4.2",
18+
"validatorjs": "^2.0.2"
1519
},
1620
"devDependencies": {
1721
"babel-core": "^6.4.5",

public/css/base.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,7 @@ p, ul {
6060
ul {
6161
padding-left: 30px;
6262
}
63+
64+
.has-error {
65+
border: 1px solid red;
66+
}

public/scripts/.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
*
2-
!.gitignore
1+
bundle.js
2+
bundle.js.map

0 commit comments

Comments
 (0)