UNPKG

11.4 kBMarkdownView Raw
1# express-form
2
3Express Form provides data filtering and validation as route middleware to your Express applications.
4
5[![Build Status](https://travis-ci.org/freewil/express-form.png?branch=express-2.x)](https://travis-ci.org/freewil/express-form)
6
7## Install
8
9* **Express 2.x** `npm install express-form@0.9.x`
10
11* **Express 3.x** `npm install express-form@0.10.x`
12
13## Usage
14
15```js
16var form = require("express-form"),
17 field = form.field;
18
19var app = express.createServer();
20
21app.configure(function() {
22 app.use(express.bodyDecoder());
23 app.use(app.router);
24});
25
26app.post(
27
28 // Route
29 '/user',
30
31 // Form filter and validation middleware
32 form(
33 field("username").trim().required().is(/^[a-z]+$/),
34 field("password").trim().required().is(/^[0-9]+$/),
35 field("email").trim().isEmail()
36 ),
37
38 // Express request-handler now receives filtered and validated data
39 function(req, res){
40 if (!req.form.isValid) {
41 // Handle errors
42 console.log(req.form.errors);
43
44 } else {
45 // Or, use filtered form data from the form object:
46 console.log("Username:", req.form.username);
47 console.log("Password:", req.form.password);
48 console.log("Email:", req.form.email);
49 }
50 }
51);
52```
53
54## Documentation
55
56### Module
57
58`express-form` returns an `express` [Route Middleware](http://expressjs.com/guide.html#Route-Middleware) function.
59You specify filtering and validation by passing filters and validators as
60arguments to the main module function. For example:
61
62```js
63var form = require("express-form");
64
65app.post('/user',
66
67 // Express Form Route Middleware: trims whitespace off of
68 // the `username` field.
69 form(form.field("username").trim()),
70
71 // standard Express handler
72 function(req, res) {
73 // ...
74 }
75);
76```
77
78### Fields
79
80The `field` property of the module creates a filter/validator object tied to a specific field.
81
82```
83field(fieldname[, label]);
84```
85
86You can access nested properties with either dot or square-bracket notation.
87
88```js
89field("post.content").minLength(50),
90field("post[user][id]").isInt(),
91field("post.super.nested.property").required()
92```
93
94Simply specifying a property like this, makes sure it exists. So, even if `req.body.post` was undefined,
95`req.form.post.content` would be defined. This helps avoid any unwanted errors in your code.
96
97The API is chainable, so you can keep calling filter/validator methods one after the other:
98
99```js
100filter("username")
101 .required()
102 .trim()
103 .toLower()
104 .truncate(5)
105 .isAlphanumeric()
106```
107
108### Filter API:
109
110Type Coercion
111
112 toFloat() -> Number
113
114 toInt() -> Number, rounded down
115
116 toBoolean() -> Boolean from truthy and falsy values
117
118 toBooleanStrict() -> Only true, "true", 1 and "1" are `true`
119
120 ifNull(replacement) -> "", undefined and null get replaced by `replacement`
121
122
123HTML Encoding for `& " < >`
124
125 entityEncode() -> encodes HTML entities
126
127 entityDecode() -> decodes HTML entities
128
129
130String Transformations
131
132 trim(chars) -> `chars` defaults to whitespace
133
134 ltrim(chars)
135
136 rtrim(chars)
137
138 toLower() / toLowerCase()
139
140 toUpper() / toUpperCase()
141
142 truncate(length) -> Chops value at (length - 3), appends `...`
143
144
145### Validator API:
146
147**Validation messages**: each validator has its own default validation message.
148These can easily be overridden at runtime by passing a custom validation message
149to the validator. The custom message is always the **last** argument passed to
150the validator. `required()` allows you to set a placeholder (or default value)
151that your form contains when originally presented to the user. This prevents the
152placeholder value from passing the `required()` check.
153
154Use "%s" in the message to have the field name or label printed in the message:
155
156 validate("username").required()
157 // -> "username is required"
158
159 validate("username").required("Type your desired username", "What is your %s?")
160 // -> "What is your username?"
161
162 validate("username", "Username").required("", "What is your %s?")
163 // -> "What is your Username?"
164
165
166**Validation Methods**
167
168*By Regular Expressions*
169
170 regex(pattern[, modifiers[, message]])
171 - pattern (RegExp|String): RegExp (with flags) or String pattern.
172 - modifiers (String): Optional, and only if `pattern` is a String.
173 - message (String): Optional validation message.
174
175 alias: is
176
177 Checks that the value matches the given regular expression.
178
179 Example:
180
181 validate("username").is("[a-z]", "i", "Only letters are valid in %s")
182 validate("username").is(/[a-z]/i, "Only letters are valid in %s")
183
184
185 notRegex(pattern[, modifiers[, message]])
186 - pattern (RegExp|String): RegExp (with flags) or String pattern.
187 - modifiers (String): Optional, and only if `pattern` is a String.
188 - message (String): Optional validation message.
189
190 alias: not
191
192 Checks that the value does NOT match the given regular expression.
193
194 Example:
195
196 validate("username").not("[a-z]", "i", "Letters are not valid in %s")
197 validate("username").not(/[a-z]/i, "Letters are not valid in %s")
198
199
200*By Type*
201
202 isNumeric([message])
203
204 isInt([message])
205
206 isDecimal([message])
207
208 isFloat([message])
209
210
211*By Format*
212
213 isDate([message])
214
215 isEmail([message])
216
217 isUrl([message])
218
219 isIP([message])
220
221 isAlpha([message])
222
223 isAlphanumeric([message])
224
225 isLowercase([message])
226
227 isUppercase([message])
228
229
230*By Content*
231
232 notEmpty([message])
233
234 Checks if the value is not just whitespace.
235
236
237 equals( value [, message] )
238 - value (String): A value that should match the field value OR a fieldname
239 token to match another field, ie, `field::password`.
240
241 Compares the field to `value`.
242
243 Example:
244 validate("username").equals("admin")
245
246 validate("password").is(/^\w{6,20}$/)
247 validate("password_confirmation").equals("field::password")
248
249
250 contains(value[, message])
251 - value (String): The value to test for.
252
253 Checks if the field contains `value`.
254
255
256 notContains(string[, message])
257 - value (String): A value that should not exist in the field.
258
259 Checks if the field does NOT contain `value`.
260
261
262*Other*
263
264 required([message])
265
266 Checks that the field is present in form data, and has a value.
267
268### Array Method
269
270 array()
271 Using the array() flag means that field always gives an array. If the field value is an array, but there is no flag, then the first value in that array is used instead.
272
273 This means that you don't have to worry about unexpected post data that might break your code. Eg/ when you call an array method on what is actually a string.
274
275 field("project.users").array(),
276 // undefined => [], "" => [], "q" => ["q"], ["a", "b"] => ["a", "b"]
277
278 field("project.block"),
279 // project.block: ["a", "b"] => "a". No "array()", so only first value used.
280
281 In addition, any other methods called with the array method, are applied to every value within the array.
282
283 field("post.users").array().toUpper()
284 // post.users: ["one", "two", "three"] => ["ONE", "TWO", "THREE"]
285
286### Custom Methods
287
288 custom(function[, message])
289 - function (Function): A custom filter or validation function.
290
291 This method can be utilised as either a filter or validator method.
292
293 If the function throws an error, then an error is added to the form. (If `message` is not provided, the thrown error message is used.)
294
295 If the function returns a value, then it is considered a filter method, with the field then becoming the returned value.
296
297 If the function returns undefined, then the method has no effect on the field.
298
299 Examples:
300
301 If the `name` field has a value of "hello there", this would
302 transform it to "hello-there".
303
304 field("name").custom(function(value) {
305 return value.replace(/\s+/g, "-");
306 });
307
308 Throws an error if `username` field does not have value "admin".
309
310 field("username").custom(function(value) {
311 if (value !== "admin") {
312 throw new Error("%s must be 'admin'.");
313 }
314 });
315
316 Validator based value on another field of the incoming source being validated
317
318 field("sport", "favorite sport").custom(function(value, source) {
319 if (!source.country) {
320 throw new Error('unable to validate %s');
321 }
322
323 switch (source.country) {
324 case 'US':
325 if (value !=== 'baseball') {
326 throw new Error('America likes baseball');
327 }
328 break;
329
330 case 'UK':
331 if (value !=== 'football') {
332 throw new Error('UK likes football');
333 }
334 break;
335 }
336
337 });
338
339 Asynchronous custom validator (3 argument function signature)
340
341 form.field('username').custom(function(value, source, callback) {
342 username.check(value, function(err) {
343 if (err) return callback(new Error('Invalid %s'));
344 callback(null);
345 });
346 });
347
348
349### http.ServerRequest.prototype.form
350
351Express Form adds a `form` object with various properties to the request.
352
353 isValid -> Boolean
354
355 errors -> Array
356
357 flashErrors(name) -> undefined
358
359 Flashes all errors. Configurable, enabled by default.
360
361 getErrors(name) -> Array or Object if no name given
362 - fieldname (String): The name of the field
363
364 Gets all errors for the field with the given name.
365
366 You can also call this method with no parameters to get a map of errors for all of the fields.
367
368 Example request handler:
369
370 function(req, res) {
371 if (!req.form.isValid) {
372 console.log(req.errors);
373 console.log(req.getErrors("username"));
374 console.log(req.getErrors());
375 }
376 }
377
378### Configuration
379
380Express Form has various configuration options, but aims for sensible defaults for a typical Express application.
381
382 form.configure(options) -> self
383 - options (Object): An object with configuration options.
384
385 flashErrors (Boolean): If validation errors should be automatically passed to Express’ flash() method. Default: true.
386
387 autoLocals (Boolean): If field values from Express’ request.body should be passed into Express’ response.locals object. This is helpful when a form is invalid an you want to repopulate the form elements with their submitted values. Default: true.
388
389 Note: if a field name dash-separated, the name used for the locals object will be in camelCase.
390
391 dataSources (Array): An array of Express request properties to use as data sources when filtering and validating data. Default: ["body", "query", "params"].
392
393 autoTrim (Boolean): If true, all fields will be automatically trimmed. Default: false.
394
395 passThrough (Boolean): If true, all data sources will be merged with `req.form`. Default: false.
396
397
398### Credits
399
400Currently, Express Form uses many of the validation and filtering functions provided by Chris O'Hara's [node-validator](https://github.com/chriso/node-validator).