Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 488 lines (373 sloc) 11.543 kB
f771ccf @addyosmani Adding further information, working towards a version to be added to …
authored
1 Backbone.validation by Thomas Pedersen is a useful extension to Backbone which allows us to easily add
2 complex validation rules to our Backbone models. You might be wondering how this extension differs from
3 the out-of-the box approach to writing validation rules, so let's briefly review what we learned in the
4 basics section.
5
6 Backbone models support a ```.validate()``` method for adding validation rules to a model, which is undefined
7 unless we override it. If the model and attributes we're using pass our validation rules, ```validate()``` will
8 return nothing, otherwise it can return an error of our choice. Below we can see an example of some simple
9 validation against a Photo model's ```src``` attribute.
10
11 ```javascript
12 var Photo = Backbone.Model.extend({
13 validate: function(attrs) {
14 if (src === "") {
15 return "source can't be empty!";
16 }
17 }
18 });
4d39d8e @thedersen Started writing the readme
thedersen authored
19
f771ccf @addyosmani Adding further information, working towards a version to be added to …
authored
20 var one = new Photo({
21 src : ""
22 });
23
24 one.bind("error", function(model, error) {
25 alert(model.get("src") + " " + error);
26 });
27
28 one.set({
29 caption: "this is a photo"
30 });
31 ```
32
33 Todo: differences.
4d39d8e @thedersen Started writing the readme
thedersen authored
34
4403a34 @thedersen Updated readme
thedersen authored
35 ## Getting started
4d39d8e @thedersen Started writing the readme
thedersen authored
36
9a9d021 @thedersen Updated readme
thedersen authored
37 It's easy to get up and running. You only need to have Backbone (including underscore.js) in your page before including the Backbone.Validation plugin. If you are using the default implementation of the callbacks, you also need to include jQuery.
4d39d8e @thedersen Started writing the readme
thedersen authored
38
4403a34 @thedersen Updated readme
thedersen authored
39 ### Configure validation rules on the Model
4d39d8e @thedersen Started writing the readme
thedersen authored
40
4403a34 @thedersen Updated readme
thedersen authored
41 To configure your validation rules, simply add a validation property with a property for each attribute you want to validate on your model. The validation rules can either be an object with one of the built-in validators or a combination of two or more of them, or a function where you implement your own custom validation logic. If you want to provide a custom error message when using one of the built-in validators, simply define the `msg` property with your message.
4d39d8e @thedersen Started writing the readme
thedersen authored
42
4403a34 @thedersen Updated readme
thedersen authored
43 #### Example
4d39d8e @thedersen Started writing the readme
thedersen authored
44
4403a34 @thedersen Updated readme
thedersen authored
45 var SomeModel = Backbone.Model.extend({
eccdd23 @thedersen Updated readme
thedersen authored
46 validation: {
4403a34 @thedersen Updated readme
thedersen authored
47 name: {
48 required: true,
49 msg: 'Name is required'
50 },
eccdd23 @thedersen Updated readme
thedersen authored
51 age: {
bd2b8ee @thedersen Updated readme
thedersen authored
52 range: [1, 80]
4403a34 @thedersen Updated readme
thedersen authored
53 },
54 email: {
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
55 pattern: 'email'
4403a34 @thedersen Updated readme
thedersen authored
56 },
57 someAttribute: function(value) {
58 if(value !== 'somevalue') {
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
59 return 'Error';
4403a34 @thedersen Updated readme
thedersen authored
60 }
61 }
eccdd23 @thedersen Updated readme
thedersen authored
62 }
63 });
4d39d8e @thedersen Started writing the readme
thedersen authored
64
f771ccf @addyosmani Adding further information, working towards a version to be added to …
authored
65
4403a34 @thedersen Updated readme
thedersen authored
66
67 ### Validation binding
68
2a56f66 @thedersen Updated readme with new changes
thedersen authored
69 The validation binding code is executed with a call to `Backbone.Validation.bind(view)`. The [validate](http://documentcloud.github.com/backbone/#Model-validate) method on the view's model is then overridden to perform the validation. In addition, the model is extended with an `isValid()` method.
4d39d8e @thedersen Started writing the readme
thedersen authored
70
4403a34 @thedersen Updated readme
thedersen authored
71 There are several places that it can be called from, depending on your circumstances.
72
73 // Binding when rendering
74 var SomeView = Backbone.View.extend({
75 render: function(){
4d39d8e @thedersen Started writing the readme
thedersen authored
76 Backbone.Validation.bind(this);
77 }
78 });
79
4403a34 @thedersen Updated readme
thedersen authored
80 // Binding when initializing
81 var SomeView = Backbone.View.extend({
4d39d8e @thedersen Started writing the readme
thedersen authored
82 initialize: function(){
83 Backbone.Validation.bind(this);
84 }
85 });
86
4403a34 @thedersen Updated readme
thedersen authored
87 // Binding from outside a view
88 var SomeView = Backbone.View.extend({
89 });
90 var someView = new SomeView();
91 Backbone.Validation.bind(someView);
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
92
eccdd23 @thedersen Updated readme
thedersen authored
93 ### Specifying error messages
94
2755173 @thedersen Updated readme
thedersen authored
95 You can specify an error message per attribute:
eccdd23 @thedersen Updated readme
thedersen authored
96
97 MyModel = Backbone.Model.extend({
98 validation: {
99 email: {
100 required: true,
101 pattern: "email",
102 msg: "Please enter a valid email"
103 }
104 }
105 });
106
2755173 @thedersen Updated readme
thedersen authored
107 Or, you can specify an error message per validator:
eccdd23 @thedersen Updated readme
thedersen authored
108
109 MyModel = Backbone.Model.extend({
110 validation: {
111 email: [{
112 required: true,
113 msg: "Please enter an email address"
114 },{
115 pattern: "email",
116 msg: "Please enter a valid email"
117 }]
118 }
119 });
120
121
122 ## Configuration
123
2755173 @thedersen Updated readme
thedersen authored
124 ### Callbacks
4403a34 @thedersen Updated readme
thedersen authored
125
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
126 The `Backbone.Validation.callbacks` contains two methods: `valid` and `invalid`. These are called after validation of an attribute is performed.
4d39d8e @thedersen Started writing the readme
thedersen authored
127
35dcbf0 @thedersen Changed default selector in the callbacks from 'id' to 'name'
thedersen authored
128 The default implementation of `invalid` tries to look up an element within the view with an name attribute equal to the name of the attribute that is validated. If it finds one, an `invalid` class is added to the element as well as a `data-error` attribute with the error message. The `valid` method removes these if they exists.
4d39d8e @thedersen Started writing the readme
thedersen authored
129
4403a34 @thedersen Updated readme
thedersen authored
130 The default implementation of these can of course be overridden:
131
132 _.extend(Backbone.Validation.callbacks, {
9a9d021 @thedersen Updated readme
thedersen authored
133 valid: function(view, attr, selector) {
4403a34 @thedersen Updated readme
thedersen authored
134 // do something
135 },
9a9d021 @thedersen Updated readme
thedersen authored
136 invalid: function(view, attr, error, selector) {
4403a34 @thedersen Updated readme
thedersen authored
137 // do something
138 }
139 });
140
141 You can also override these per view when binding:
142
143 var SomeView = Backbone.View.extend({
144 render: function(){
145 Backbone.Validation.bind(this, {
146 valid: function(view, attr) {
147 // do something
148 },
149 invalid: function(view, attr, error) {
150 // do something
151 }
152 });
153 }
154 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
155
2755173 @thedersen Updated readme
thedersen authored
156 ### Selector
eccdd23 @thedersen Updated readme
thedersen authored
157
158 If you need to look up elements in the view by using for instance a class name or id instead of name, there are two ways to configure this.
9a9d021 @thedersen Updated readme
thedersen authored
159
160 You can configure it globally by calling:
161
4acebf0 @thedersen setDefaultSelector is replaced with configure({selector: 'class'})
thedersen authored
162 Backbone.Validation.configure({
163 selector: 'class'
164 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
165
9a9d021 @thedersen Updated readme
thedersen authored
166 Or, you can configure it per view when binding:
167
168 Backbone.Validation.bind(this.view, {
169 selector: 'class'
170 });
171
35dcbf0 @thedersen Changed default selector in the callbacks from 'id' to 'name'
thedersen authored
172 If you have set the global selector to class, you can of course set the selector to name or id on specific views.
2a56f66 @thedersen Updated readme with new changes
thedersen authored
173
2755173 @thedersen Updated readme
thedersen authored
174 ### Force update
6b16c2a @thedersen Can configure per view or globally to force update the model with inv…
thedersen authored
175
176 Sometimes it can be useful to update the model with invalid values. Especially when using automatic modelbinding and late validation (e.g. when submitting the form).
177
178 You can turn this on globally by calling:
179
180 Backbone.Validation.configure({
181 forceUpdate: true
182 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
183
6b16c2a @thedersen Can configure per view or globally to force update the model with inv…
thedersen authored
184 Or, you can turn it on per view when binding:
185
186 Backbone.Validation.bind(this.view, {
187 forceUpdate: true
188 });
189
eccdd23 @thedersen Updated readme
thedersen authored
190 Note that when switching this on, the error event is no longer triggered.
6b16c2a @thedersen Can configure per view or globally to force update the model with inv…
thedersen authored
191
2a56f66 @thedersen Updated readme with new changes
thedersen authored
192 ## Events
193
2755173 @thedersen Updated readme
thedersen authored
194 After validation is performed, the model will trigger some events with the result of the validation.
2a56f66 @thedersen Updated readme with new changes
thedersen authored
195
eccdd23 @thedersen Updated readme
thedersen authored
196 ### validated
197
2755173 @thedersen Updated readme
thedersen authored
198 The `validated` event is triggered after validation is performed, either it was successful or not. `isValid` is `true` or `false` depending on the result of the validation.
199
8fb71b0 @thedersen Fiex typos in readme
thedersen authored
200 model.bind('validated', function(isValid, model, attrs) {
2755173 @thedersen Updated readme
thedersen authored
201 // do something
1d17dd6 @thedersen Added model and an array of invalid attribute names as arguments to t…
thedersen authored
202 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
203
eccdd23 @thedersen Updated readme
thedersen authored
204 ### validated:valid
205
2755173 @thedersen Updated readme
thedersen authored
206 The `validated:valid` event is triggered after a successful validation is performed.
207
8fb71b0 @thedersen Fiex typos in readme
thedersen authored
208 model.bind('validated:valid', function(model) {
2755173 @thedersen Updated readme
thedersen authored
209 // do something
1d17dd6 @thedersen Added model and an array of invalid attribute names as arguments to t…
thedersen authored
210 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
211
eccdd23 @thedersen Updated readme
thedersen authored
212 ### validated:invalid
213
2755173 @thedersen Updated readme
thedersen authored
214 The `validated:invalid` event is triggered after an unsuccessful validation is performed.
215
8fb71b0 @thedersen Fiex typos in readme
thedersen authored
216 model.bind('validated:invalid', function(model, attrs) {
2755173 @thedersen Updated readme
thedersen authored
217 // do something
1d17dd6 @thedersen Added model and an array of invalid attribute names as arguments to t…
thedersen authored
218 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
219
eccdd23 @thedersen Updated readme
thedersen authored
220 ## Built-in validators
4403a34 @thedersen Updated readme
thedersen authored
221
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
222 ### method validator
4403a34 @thedersen Updated readme
thedersen authored
223
224 var SomeModel = Backbone.Model.extend({
225 validation: {
226 name: function(value) {
227 if(value !== 'something') {
228 return 'Name is invalid';
229 }
230 }
231 }
232 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
233
1bf8ee0 @thedersen method validator and named method validator can be combined with othe…
thedersen authored
234 var SomeModel = Backbone.Model.extend({
235 validation: {
236 name: {
237 fn: function(value) {
238 if(value !== 'something') {
239 return 'Name is invalid';
240 }
241 }
242 }
243 }
244 });
245
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
246 ### named method validator
ceebfff @thedersen Updated readme with named function validator
thedersen authored
247
248 var SomeModel = Backbone.Model.extend({
249 validation: {
250 name: 'validateName'
251 },
409444d @thedersen Updated named method validator in readme
thedersen authored
252 validateName: function(value, attr) {
ceebfff @thedersen Updated readme with named function validator
thedersen authored
253 if(value !== 'something') {
254 return 'Name is invalid';
255 }
256 }
257 });
4403a34 @thedersen Updated readme
thedersen authored
258
1bf8ee0 @thedersen method validator and named method validator can be combined with othe…
thedersen authored
259 var SomeModel = Backbone.Model.extend({
260 validation: {
261 name: {
262 fn: 'validateName'
263 }
264 },
265 validateName: function(value, attr) {
266 if(value !== 'something') {
267 return 'Name is invalid';
268 }
269 }
270 });
271
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
272 ### required
4403a34 @thedersen Updated readme
thedersen authored
273
274 var SomeModel = Backbone.Model.extend({
275 validation: {
276 name: {
e7c2117 @thedersen Required validator can be a function returning true or false
thedersen authored
277 required: true | false
278 }
279 }
280 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
281
e7c2117 @thedersen Required validator can be a function returning true or false
thedersen authored
282 var SomeModel = Backbone.Model.extend({
283 validation: {
284 name: {
285 required: function() {
286 return true | false;
287 }
4403a34 @thedersen Updated readme
thedersen authored
288 }
289 }
4d39d8e @thedersen Started writing the readme
thedersen authored
290 });
291
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
292 ### acceptance
7267397 @thedersen Added acceptance validator
thedersen authored
293
294 var SomeModel = Backbone.Model.extend({
295 validation: {
ac908d1 @thedersen Updated readme
thedersen authored
296 termsOfUse: {
7267397 @thedersen Added acceptance validator
thedersen authored
297 acceptance: true
298 }
299 }
300 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
301
302 ### min
7e51a5d @thedersen Added copyright notice and license
thedersen authored
303
4403a34 @thedersen Updated readme
thedersen authored
304 var SomeModel = Backbone.Model.extend({
305 validation: {
306 age: {
307 min: 1
308 }
309 }
310 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
311
312 ### max
4403a34 @thedersen Updated readme
thedersen authored
313
314 var SomeModel = Backbone.Model.extend({
315 validation: {
316 age: {
317 max: 100
318 }
319 }
320 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
321
322 ### range
8cafbcd @thedersen Added range validator
thedersen authored
323
324 var SomeModel = Backbone.Model.extend({
325 validation: {
326 age: {
327 range: [1, 10]
328 }
329 }
330 });
760d4f1 @thedersen Added length validator
thedersen authored
331
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
332 ### length
760d4f1 @thedersen Added length validator
thedersen authored
333
334 var SomeModel = Backbone.Model.extend({
335 validation: {
336 postalCode: {
337 length: 4
338 }
339 }
340 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
341
342 ### minLength
4403a34 @thedersen Updated readme
thedersen authored
343
344 var SomeModel = Backbone.Model.extend({
345 validation: {
346 password: {
347 minLength: 8
348 }
349 }
350 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
351
352 ### maxLength
4403a34 @thedersen Updated readme
thedersen authored
353
354 var SomeModel = Backbone.Model.extend({
355 validation: {
356 password: {
357 maxLength: 100
358 }
359 }
360 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
361
362 ### rangeLength
f54f2f8 @thedersen Added oneOf validator
thedersen authored
363
364 var SomeModel = Backbone.Model.extend({
365 validation: {
366 password: {
367 rangeLength: [6, 100]
368 }
369 }
370 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
371
372 ### oneOf
e7c2117 @thedersen Required validator can be a function returning true or false
thedersen authored
373
374 var SomeModel = Backbone.Model.extend({
375 validation: {
376 country: {
377 oneOf: ['Norway', 'Sweeden']
378 }
379 }
380 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
381
382 ### equalTo
f8c49e6 @thedersen Added equalTo validator
thedersen authored
383
384 var SomeModel = Backbone.Model.extend({
385 validation: {
386 password: {
387 required: true
388 },
389 passwordRepeat: {
390 equalTo: 'password'
391 }
392 }
393 });
394
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
395 ### pattern
4403a34 @thedersen Updated readme
thedersen authored
396
397 var SomeModel = Backbone.Model.extend({
398 validation: {
399 email: {
400 pattern: 'email'
401 }
402 }
403 });
404
405 where the built-in patterns are:
406
407 * number
408 * email
409 * url
f82382a @thedersen Added new pattern digits
thedersen authored
410 * digits
4403a34 @thedersen Updated readme
thedersen authored
411
412 or specify any regular expression you like:
413
414 var SomeModel = Backbone.Model.extend({
415 validation: {
416 email: {
417 pattern: /^sample/
418 }
419 }
420 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
421
9bd8c55 @thedersen Updated minified version
thedersen authored
422 See the [wiki](https://github.com/thedersen/backbone.validation/wiki) for more details about the validators.
4403a34 @thedersen Updated readme
thedersen authored
423
424 ## Extending Backbone.Validation
425
426 ### Adding custom validators
427
ac908d1 @thedersen Updated readme
thedersen authored
428 If you have custom validation logic that are used several places in your code, you can extend the validators with your own. And if you don't like the default implementation of one of the built-ins, you can override it.
4403a34 @thedersen Updated readme
thedersen authored
429
430 _.extend(Backbone.Validation.validators, {
bd2b8ee @thedersen Updated readme
thedersen authored
431 myValidator: function(value, attr, customValue, model) {
4403a34 @thedersen Updated readme
thedersen authored
432 if(value !== customValue){
18f28bd @thedersen Updated readme
thedersen authored
433 return 'error';
4403a34 @thedersen Updated readme
thedersen authored
434 }
435 },
bd2b8ee @thedersen Updated readme
thedersen authored
436 required: function(value, attr, customValue, model) {
4403a34 @thedersen Updated readme
thedersen authored
437 if(!value){
18f28bd @thedersen Updated readme
thedersen authored
438 return 'My version of the required validator';
4403a34 @thedersen Updated readme
thedersen authored
439 }
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
440 },
4403a34 @thedersen Updated readme
thedersen authored
441 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
442
4403a34 @thedersen Updated readme
thedersen authored
443 var Model = Backbone.Model.extend({
444 validation: {
445 age: {
446 myValidator: 1 // uses your custom validator
447 }
448 }
449 });
450
9a9d021 @thedersen Updated readme
thedersen authored
451 The validator should return an error message when the value is invalid, and nothing (`undefined`) if the value is valid. If the validator returns `false`, this will result in that all other validators specified for the attribute is bypassed, and the attribute is considered valid.
18f28bd @thedersen Updated readme
thedersen authored
452
4403a34 @thedersen Updated readme
thedersen authored
453 ### Adding custom patterns
454
ac908d1 @thedersen Updated readme
thedersen authored
455 If you have custom patterns that are used several places in your code, you can extend the patterns with your own. And if you don't like the default implementation of one of the built-ins, you can override it.
4403a34 @thedersen Updated readme
thedersen authored
456
457 _.extend(Backbone.Validation.patterns, {
458 myPattern: /my-pattern/,
459 email: /my-much-better-email-regex/
460 });
461
462 var Model = Backbone.Model.extend({
463 validation: {
464 name: {
465 pattern: 'myPattern'
466 }
467 }
468 });
7e51a5d @thedersen Added copyright notice and license
thedersen authored
469
27c87b9 @thedersen Can override the default error messages globally
thedersen authored
470 ### Overriding the default error messages
471
38ce076 @thedersen Updated Readme
thedersen authored
472 If you don't like the default error messages there are several ways of customizing them.
473
474 You can override the default ones globally:
27c87b9 @thedersen Can override the default error messages globally
thedersen authored
475
476 _.extend(Backbone.Validation.messages, {
eccdd23 @thedersen Updated readme
thedersen authored
477 required: 'This field is required',
478 min: '{0}' should be at least {1} characters
27c87b9 @thedersen Can override the default error messages globally
thedersen authored
479 });
207bb07 @thedersen Changed some formatting in the readme, so it works better with Docume…
thedersen authored
480
ac908d1 @thedersen Updated readme
thedersen authored
481 The message can contain placeholders for arguments that will be replaced:
482
483 * `{0}` will be replaced with the name of the attribute being validated
484 * `{1}` will be replaced with the allowed value configured in the validation (or the first one in a range validator)
485 * `{2}` will be replaced with the second value in a range validator
7e51a5d @thedersen Added copyright notice and license
thedersen authored
486
f771ccf @addyosmani Adding further information, working towards a version to be added to …
authored
487
Something went wrong with that request. Please try again.