backbone-validation-rails 0.6.2.1 → 0.7.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/lib/backbone-validation-rails/version.rb +1 -1
- data/vendor/assets/javascripts/backbone-validation.js +125 -71
- metadata +3 -3
data/README.md
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
// Backbone.Validation v0.
|
1
|
+
// Backbone.Validation v0.7.1
|
2
2
|
//
|
3
3
|
// Copyright (c) 2011-2012 Thomas Pedersen
|
4
4
|
// Distributed under MIT License
|
5
5
|
//
|
6
6
|
// Documentation and full license available at:
|
7
7
|
// http://thedersen.com/projects/backbone-validation
|
8
|
-
|
9
8
|
Backbone.Validation = (function(_){
|
10
9
|
'use strict';
|
11
10
|
|
@@ -13,13 +12,69 @@ Backbone.Validation = (function(_){
|
|
13
12
|
// ---------------
|
14
13
|
|
15
14
|
var defaultOptions = {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
forceUpdate: false,
|
16
|
+
selector: 'name',
|
17
|
+
labelFormatter: 'sentenceCase',
|
18
|
+
valid: Function.prototype,
|
19
|
+
invalid: Function.prototype
|
20
|
+
};
|
21
|
+
|
22
|
+
|
23
|
+
// Helper functions
|
24
|
+
// ----------------
|
25
|
+
|
26
|
+
// Formatting functions used for formatting error messages
|
27
|
+
var formatFunctions = {
|
28
|
+
// Uses the configured label formatter to format the attribute name
|
29
|
+
// to make it more readable for the user
|
30
|
+
formatLabel: function(attrName, model) {
|
31
|
+
return defaultLabelFormatters[defaultOptions.labelFormatter](attrName, model);
|
32
|
+
},
|
33
|
+
|
34
|
+
// Replaces nummeric placeholders like {0} in a string with arguments
|
35
|
+
// passed to the function
|
36
|
+
format: function() {
|
37
|
+
var args = Array.prototype.slice.call(arguments),
|
38
|
+
text = args.shift();
|
39
|
+
return text.replace(/\{(\d+)\}/g, function(match, number) {
|
40
|
+
return typeof args[number] !== 'undefined' ? args[number] : match;
|
41
|
+
});
|
42
|
+
}
|
21
43
|
};
|
22
44
|
|
45
|
+
// Flattens an object
|
46
|
+
// eg:
|
47
|
+
//
|
48
|
+
// var o = {
|
49
|
+
// address: {
|
50
|
+
// street: 'Street',
|
51
|
+
// zip: 1234
|
52
|
+
// }
|
53
|
+
// };
|
54
|
+
//
|
55
|
+
// becomes:
|
56
|
+
//
|
57
|
+
// var o = {
|
58
|
+
// 'address.street': 'Street',
|
59
|
+
// 'address.zip': 1234
|
60
|
+
// };
|
61
|
+
var flatten = function (obj, into, prefix) {
|
62
|
+
into = into || {};
|
63
|
+
prefix = prefix || '';
|
64
|
+
|
65
|
+
_.each(obj, function(val, key) {
|
66
|
+
if(obj.hasOwnProperty(key)) {
|
67
|
+
if (val && typeof val === 'object' && !(val instanceof Date || val instanceof RegExp)) {
|
68
|
+
flatten(val, into, prefix + key + '.');
|
69
|
+
}
|
70
|
+
else {
|
71
|
+
into[prefix + key] = val;
|
72
|
+
}
|
73
|
+
}
|
74
|
+
});
|
75
|
+
|
76
|
+
return into;
|
77
|
+
};
|
23
78
|
|
24
79
|
// Validation
|
25
80
|
// ----------
|
@@ -78,7 +133,11 @@ Backbone.Validation = (function(_){
|
|
78
133
|
// applying all the validators and returning the first error
|
79
134
|
// message, if any.
|
80
135
|
return _.reduce(getValidators(model, attr), function(memo, validator){
|
81
|
-
|
136
|
+
// Pass the format functions plus the default
|
137
|
+
// validators as the context to the validator
|
138
|
+
var ctx = _.extend({}, formatFunctions, defaultValidators),
|
139
|
+
result = validator.fn.call(ctx, value, attr, validator.val, model, computed);
|
140
|
+
|
82
141
|
if(result === false || memo === false) {
|
83
142
|
return false;
|
84
143
|
}
|
@@ -93,18 +152,19 @@ Backbone.Validation = (function(_){
|
|
93
152
|
// Returns and object containing names of invalid attributes
|
94
153
|
// as well as error messages.
|
95
154
|
var validateModel = function(model, attrs) {
|
96
|
-
var error,
|
155
|
+
var error,
|
97
156
|
invalidAttrs = {},
|
98
157
|
isValid = true,
|
99
|
-
computed = _.clone(attrs)
|
158
|
+
computed = _.clone(attrs),
|
159
|
+
flattened = flatten(attrs);
|
100
160
|
|
101
|
-
|
102
|
-
error = validateAttr(model, attr,
|
161
|
+
_.each(flattened, function(val, attr) {
|
162
|
+
error = validateAttr(model, attr, val, computed);
|
103
163
|
if (error) {
|
104
164
|
invalidAttrs[attr] = error;
|
105
165
|
isValid = false;
|
106
166
|
}
|
107
|
-
}
|
167
|
+
});
|
108
168
|
|
109
169
|
return {
|
110
170
|
invalidAttrs: invalidAttrs,
|
@@ -126,16 +186,15 @@ Backbone.Validation = (function(_){
|
|
126
186
|
// entire model is valid. Passing true will force a validation
|
127
187
|
// of the model.
|
128
188
|
isValid: function(option) {
|
189
|
+
var flattened = flatten(this.attributes);
|
190
|
+
|
129
191
|
if(_.isString(option)){
|
130
|
-
return !validateAttr(this, option,
|
192
|
+
return !validateAttr(this, option, flattened[option], _.extend({}, this.attributes));
|
131
193
|
}
|
132
194
|
if(_.isArray(option)){
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
}
|
137
|
-
}
|
138
|
-
return true;
|
195
|
+
return _.reduce(option, function(memo, attr) {
|
196
|
+
return memo && !validateAttr(this, attr, flattened[attr], _.extend({}, this.attributes));
|
197
|
+
}, true, this);
|
139
198
|
}
|
140
199
|
if(option === true) {
|
141
200
|
this.validate();
|
@@ -150,24 +209,33 @@ Backbone.Validation = (function(_){
|
|
150
209
|
var model = this,
|
151
210
|
validateAll = !attrs,
|
152
211
|
opt = _.extend({}, options, setOptions),
|
153
|
-
|
154
|
-
|
212
|
+
validatedAttrs = getValidatedAttrs(model),
|
213
|
+
allAttrs = _.extend({}, validatedAttrs, model.attributes, attrs),
|
214
|
+
changedAttrs = flatten(attrs || allAttrs),
|
215
|
+
|
155
216
|
result = validateModel(model, allAttrs);
|
156
217
|
|
157
218
|
model._isValid = result.isValid;
|
158
219
|
|
159
220
|
// After validation is performed, loop through all changed attributes
|
160
|
-
// and call
|
161
|
-
|
221
|
+
// and call the valid callbacks so the view is updated.
|
222
|
+
_.each(validatedAttrs, function(val, attr){
|
223
|
+
var invalid = result.invalidAttrs.hasOwnProperty(attr);
|
224
|
+
if(!invalid){
|
225
|
+
opt.valid(view, attr, opt.selector);
|
226
|
+
}
|
227
|
+
});
|
228
|
+
|
229
|
+
// After validation is performed, loop through all changed attributes
|
230
|
+
// and call the invalid callback so the view is updated.
|
231
|
+
_.each(validatedAttrs, function(val, attr){
|
162
232
|
var invalid = result.invalidAttrs.hasOwnProperty(attr),
|
163
233
|
changed = changedAttrs.hasOwnProperty(attr);
|
234
|
+
|
164
235
|
if(invalid && (changed || validateAll)){
|
165
236
|
opt.invalid(view, attr, result.invalidAttrs[attr], opt.selector);
|
166
237
|
}
|
167
|
-
|
168
|
-
opt.valid(view, attr, opt.selector);
|
169
|
-
}
|
170
|
-
}
|
238
|
+
});
|
171
239
|
|
172
240
|
// Trigger validated events.
|
173
241
|
// Need to defer this so the model is actually updated before
|
@@ -215,7 +283,7 @@ Backbone.Validation = (function(_){
|
|
215
283
|
return {
|
216
284
|
|
217
285
|
// Current version of the library
|
218
|
-
version: '0.
|
286
|
+
version: '0.7.1',
|
219
287
|
|
220
288
|
// Called to configure the default options
|
221
289
|
configure: function(options) {
|
@@ -227,6 +295,7 @@ Backbone.Validation = (function(_){
|
|
227
295
|
bind: function(view, options) {
|
228
296
|
var model = view.model,
|
229
297
|
collection = view.collection;
|
298
|
+
|
230
299
|
options = _.extend({}, defaultOptions, defaultCallbacks, options);
|
231
300
|
|
232
301
|
if(typeof model === 'undefined' && typeof collection === 'undefined'){
|
@@ -237,7 +306,7 @@ Backbone.Validation = (function(_){
|
|
237
306
|
if(model) {
|
238
307
|
bindModel(view, model, options);
|
239
308
|
}
|
240
|
-
if(collection) {
|
309
|
+
else if(collection) {
|
241
310
|
collection.each(function(model){
|
242
311
|
bindModel(view, model, options);
|
243
312
|
});
|
@@ -280,7 +349,7 @@ Backbone.Validation = (function(_){
|
|
280
349
|
// view becomes valid. Removes any error message.
|
281
350
|
// Should be overridden with custom functionality.
|
282
351
|
valid: function(view, attr, selector) {
|
283
|
-
view.$('[' + selector + '~=' + attr + ']')
|
352
|
+
view.$('[' + selector + '~="' + attr + '"]')
|
284
353
|
.removeClass('invalid')
|
285
354
|
.removeAttr('data-error');
|
286
355
|
},
|
@@ -289,7 +358,7 @@ Backbone.Validation = (function(_){
|
|
289
358
|
// Adds a error message.
|
290
359
|
// Should be overridden with custom functionality.
|
291
360
|
invalid: function(view, attr, error, selector) {
|
292
|
-
view.$('[' + selector + '~=' + attr + ']')
|
361
|
+
view.$('[' + selector + '~="' + attr + '"]')
|
293
362
|
.addClass('invalid')
|
294
363
|
.attr('data-error', error);
|
295
364
|
}
|
@@ -373,41 +442,26 @@ Backbone.Validation = (function(_){
|
|
373
442
|
// }
|
374
443
|
// });
|
375
444
|
label: function(attrName, model) {
|
376
|
-
return model.labels[attrName] || defaultLabelFormatters.sentenceCase(attrName, model);
|
445
|
+
return (model.labels && model.labels[attrName]) || defaultLabelFormatters.sentenceCase(attrName, model);
|
377
446
|
}
|
378
447
|
};
|
379
448
|
|
449
|
+
|
380
450
|
// Built in validators
|
381
451
|
// -------------------
|
382
452
|
|
383
453
|
var defaultValidators = Validation.validators = (function(){
|
384
454
|
// Use native trim when defined
|
385
455
|
var trim = String.prototype.trim ?
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
// Uses the configured label formatter to format the attribute name
|
397
|
-
// to make it more readable for the user
|
398
|
-
var formatLabel = function(attrName, model) {
|
399
|
-
return defaultLabelFormatters[defaultOptions.labelFormatter](attrName, model);
|
400
|
-
};
|
401
|
-
|
402
|
-
// Replaces nummeric placeholders like {0} in a string with arguments
|
403
|
-
// passed to the function
|
404
|
-
var format = function() {
|
405
|
-
var args = Array.prototype.slice.call(arguments);
|
406
|
-
var text = args.shift();
|
407
|
-
return text.replace(/\{(\d+)\}/g, function(match, number) {
|
408
|
-
return typeof args[number] !== 'undefined' ? args[number] : match;
|
409
|
-
});
|
410
|
-
};
|
456
|
+
function(text) {
|
457
|
+
return text === null ? '' : String.prototype.trim.call(text);
|
458
|
+
} :
|
459
|
+
function(text) {
|
460
|
+
var trimLeft = /^\s+/,
|
461
|
+
trimRight = /\s+$/;
|
462
|
+
|
463
|
+
return text === null ? '' : text.toString().replace(trimLeft, '').replace(trimRight, '');
|
464
|
+
};
|
411
465
|
|
412
466
|
// Determines whether or not a value is a number
|
413
467
|
var isNumber = function(value){
|
@@ -437,7 +491,7 @@ Backbone.Validation = (function(_){
|
|
437
491
|
return false; // overrides all other validators
|
438
492
|
}
|
439
493
|
if (isRequired && !hasValue(value)) {
|
440
|
-
return format(defaultMessages.required, formatLabel(attr, model));
|
494
|
+
return this.format(defaultMessages.required, this.formatLabel(attr, model));
|
441
495
|
}
|
442
496
|
},
|
443
497
|
|
@@ -446,7 +500,7 @@ Backbone.Validation = (function(_){
|
|
446
500
|
// `true` or 'true' are valid
|
447
501
|
acceptance: function(value, attr, accept, model) {
|
448
502
|
if(value !== 'true' && (!_.isBoolean(value) || value === false)) {
|
449
|
-
return format(defaultMessages.acceptance, formatLabel(attr, model));
|
503
|
+
return this.format(defaultMessages.acceptance, this.formatLabel(attr, model));
|
450
504
|
}
|
451
505
|
},
|
452
506
|
|
@@ -455,7 +509,7 @@ Backbone.Validation = (function(_){
|
|
455
509
|
// the min value specified
|
456
510
|
min: function(value, attr, minValue, model) {
|
457
511
|
if (!isNumber(value) || value < minValue) {
|
458
|
-
return format(defaultMessages.min, formatLabel(attr, model), minValue);
|
512
|
+
return this.format(defaultMessages.min, this.formatLabel(attr, model), minValue);
|
459
513
|
}
|
460
514
|
},
|
461
515
|
|
@@ -464,7 +518,7 @@ Backbone.Validation = (function(_){
|
|
464
518
|
// the max value specified
|
465
519
|
max: function(value, attr, maxValue, model) {
|
466
520
|
if (!isNumber(value) || value > maxValue) {
|
467
|
-
return format(defaultMessages.max, formatLabel(attr, model), maxValue);
|
521
|
+
return this.format(defaultMessages.max, this.formatLabel(attr, model), maxValue);
|
468
522
|
}
|
469
523
|
},
|
470
524
|
|
@@ -473,7 +527,7 @@ Backbone.Validation = (function(_){
|
|
473
527
|
// the two numbers specified
|
474
528
|
range: function(value, attr, range, model) {
|
475
529
|
if(!isNumber(value) || value < range[0] || value > range[1]) {
|
476
|
-
return format(defaultMessages.range, formatLabel(attr, model), range[0], range[1]);
|
530
|
+
return this.format(defaultMessages.range, this.formatLabel(attr, model), range[0], range[1]);
|
477
531
|
}
|
478
532
|
},
|
479
533
|
|
@@ -482,7 +536,7 @@ Backbone.Validation = (function(_){
|
|
482
536
|
// the length value specified
|
483
537
|
length: function(value, attr, length, model) {
|
484
538
|
if (!hasValue(value) || trim(value).length !== length) {
|
485
|
-
return format(defaultMessages.length, formatLabel(attr, model), length);
|
539
|
+
return this.format(defaultMessages.length, this.formatLabel(attr, model), length);
|
486
540
|
}
|
487
541
|
},
|
488
542
|
|
@@ -491,7 +545,7 @@ Backbone.Validation = (function(_){
|
|
491
545
|
// the min length value specified
|
492
546
|
minLength: function(value, attr, minLength, model) {
|
493
547
|
if (!hasValue(value) || trim(value).length < minLength) {
|
494
|
-
return format(defaultMessages.minLength, formatLabel(attr, model), minLength);
|
548
|
+
return this.format(defaultMessages.minLength, this.formatLabel(attr, model), minLength);
|
495
549
|
}
|
496
550
|
},
|
497
551
|
|
@@ -500,7 +554,7 @@ Backbone.Validation = (function(_){
|
|
500
554
|
// the max length value specified
|
501
555
|
maxLength: function(value, attr, maxLength, model) {
|
502
556
|
if (!hasValue(value) || trim(value).length > maxLength) {
|
503
|
-
return format(defaultMessages.maxLength, formatLabel(attr, model), maxLength);
|
557
|
+
return this.format(defaultMessages.maxLength, this.formatLabel(attr, model), maxLength);
|
504
558
|
}
|
505
559
|
},
|
506
560
|
|
@@ -509,7 +563,7 @@ Backbone.Validation = (function(_){
|
|
509
563
|
// the two numbers specified
|
510
564
|
rangeLength: function(value, attr, range, model) {
|
511
565
|
if(!hasValue(value) || trim(value).length < range[0] || trim(value).length > range[1]) {
|
512
|
-
return format(defaultMessages.rangeLength, formatLabel(attr, model), range[0], range[1]);
|
566
|
+
return this.format(defaultMessages.rangeLength, this.formatLabel(attr, model), range[0], range[1]);
|
513
567
|
}
|
514
568
|
},
|
515
569
|
|
@@ -518,7 +572,7 @@ Backbone.Validation = (function(_){
|
|
518
572
|
// the specified array. Case sensitive matching
|
519
573
|
oneOf: function(value, attr, values, model) {
|
520
574
|
if(!_.include(values, value)){
|
521
|
-
return format(defaultMessages.oneOf, formatLabel(attr, model), values.join(', '));
|
575
|
+
return this.format(defaultMessages.oneOf, this.formatLabel(attr, model), values.join(', '));
|
522
576
|
}
|
523
577
|
},
|
524
578
|
|
@@ -527,7 +581,7 @@ Backbone.Validation = (function(_){
|
|
527
581
|
// with the name specified
|
528
582
|
equalTo: function(value, attr, equalTo, model, computed) {
|
529
583
|
if(value !== computed[equalTo]) {
|
530
|
-
return format(defaultMessages.equalTo, formatLabel(attr, model), formatLabel(equalTo, model));
|
584
|
+
return this.format(defaultMessages.equalTo, this.formatLabel(attr, model), this.formatLabel(equalTo, model));
|
531
585
|
}
|
532
586
|
},
|
533
587
|
|
@@ -536,11 +590,11 @@ Backbone.Validation = (function(_){
|
|
536
590
|
// Can be a regular expression or the name of one of the built in patterns
|
537
591
|
pattern: function(value, attr, pattern, model) {
|
538
592
|
if (!hasValue(value) || !value.toString().match(defaultPatterns[pattern] || pattern)) {
|
539
|
-
return format(defaultMessages.pattern, formatLabel(attr, model), pattern);
|
593
|
+
return this.format(defaultMessages.pattern, this.formatLabel(attr, model), pattern);
|
540
594
|
}
|
541
595
|
}
|
542
596
|
};
|
543
597
|
}());
|
544
598
|
|
545
599
|
return Validation;
|
546
|
-
}(_));
|
600
|
+
}(_));
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: backbone-validation-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A wrapper for backbone.validation in the Rails asset pipeline
|
15
15
|
email:
|
@@ -43,7 +43,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
43
43
|
version: '0'
|
44
44
|
requirements: []
|
45
45
|
rubyforge_project:
|
46
|
-
rubygems_version: 1.8.
|
46
|
+
rubygems_version: 1.8.23
|
47
47
|
signing_key:
|
48
48
|
specification_version: 3
|
49
49
|
summary: Backbone Validation for Rails >= 3.1
|