backbone-validation-rails 0.6.2.1 → 0.7.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|