canjs-rails 0.1.0 → 1.1.2

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.
@@ -1,374 +1,199 @@
1
- (function(can, window, undefined){
2
- //validations object is by property. You can have validations that
3
- //span properties, but this way we know which ones to run.
4
- // proc should return true if there's an error or the error message
5
- var validate = function(attrNames, options, proc) {
6
- // normalize argumetns
7
- if(!proc){
8
- proc = options;
9
- options = {};
10
- }
11
-
12
- options = options || {};
13
- attrNames = can.makeArray(attrNames)
14
-
15
- // run testIf if it exists
16
- if(options.testIf && !options.testIf.call(this)){
17
- return;
18
- }
19
-
20
- var self = this;
21
- can.each(attrNames, function(attrName) {
22
- // Add a test function for each attribute
23
- if(!self.validations[attrName]){
24
- self.validations[attrName] = [];
1
+ /*
2
+ * CanJS - 1.1.2 (2012-11-28)
3
+ * http://canjs.us/
4
+ * Copyright (c) 2012 Bitovi
5
+ * Licensed MIT
6
+ */
7
+ (function (can, window, undefined) {
8
+ // ## can/observe/validations/validations.js
9
+ //validations object is by property. You can have validations that
10
+ //span properties, but this way we know which ones to run.
11
+ // proc should return true if there's an error or the error message
12
+ var validate = function (attrNames, options, proc) {
13
+ // normalize argumetns
14
+ if (!proc) {
15
+ proc = options;
16
+ options = {};
25
17
  }
26
-
27
- self.validations[attrName].push(function(newVal){
28
- // if options has a message return that, otherwise, return the error
29
- var res = proc.call(this, newVal, attrName);
30
- return res === undefined ? undefined : (options.message || res);
31
- })
32
- });
33
- };
34
-
35
- var old = can.Observe.prototype.__set;
36
- can.Observe.prototype.__set = function(prop, value, current, success, error){
37
- var self = this,
38
- validations = self.constructor.validations,
39
- errorCallback = function( errors ) {
40
- var stub = error && error.call(self, errors);
41
-
42
- // if 'setter' is on the page it will trigger
43
- // the error itself and we dont want to trigger
44
- // the event twice. :)
45
- if(stub !== false){
46
- can.trigger(self, "error", [prop, errors], true);
47
- }
48
-
49
- return false;
50
- };
51
-
52
- old.call(self, prop, value, current, success, errorCallback);
53
-
54
- if (validations && validations[prop]){
55
- var errors = self.errors(prop);
56
- errors && errorCallback(errors)
57
- }
58
-
59
- return this;
60
- }
61
-
62
- can.each([ can.Observe, can.Model ], function(clss){
63
- // in some cases model might not be defined quite yet.
64
- if(clss === undefined){
65
- return;
66
- }
67
- var oldSetup = clss.setup;
68
-
69
- can.extend(clss, {
70
- setup : function(superClass){
71
- oldSetup.apply(this, arguments);
72
- if (!this.validations || superClass.validations === this.validations) {
73
- this.validations = {};
18
+
19
+ options = options || {};
20
+ attrNames = can.makeArray(attrNames)
21
+
22
+ // run testIf if it exists
23
+ if (options.testIf && !options.testIf.call(this)) {
24
+ return;
25
+ }
26
+
27
+ var self = this;
28
+ can.each(attrNames, function (attrName) {
29
+ // Add a test function for each attribute
30
+ if (!self.validations[attrName]) {
31
+ self.validations[attrName] = [];
74
32
  }
75
- },
76
- /**
77
- * @function can.Observe.static.validate
78
- * @parent can.Observe.validations
79
- * `validate(attrNames, [options,] validateProc(value, attrName) )` validates each of the
80
- * specified attributes with the given `validateProc` function. The function
81
- * should return a value if there is an error. By default, the return value is
82
- * the error message. Validations should be set in the Constructor's static init method.
83
- *
84
- * The following example validates that a person's age is a number:
85
- *
86
- * Person = can.Observe({
87
- * init : function(){
88
- * this.validate(["age"], function(val){
89
- * if( typeof val === 'number' ){
90
- * return "must be a number"
91
- * }
92
- * })
93
- * }
94
- * },{})
95
- *
96
- *
97
- * The error message can be overwritten with `options` __message__ property:
98
- *
99
- * Person = can.Observe({
100
- * init : function(){
101
- * this.validate(
102
- * "age",
103
- * {message: "must be a number"},
104
- * function(val){
105
- * if( typeof val === 'number' ){
106
- * return true
107
- * }
108
- * })
109
- * }
110
- * },{})
111
- *
112
- * @param {Array|String} attrNames Attribute name(s) to to validate
113
- *
114
- * @param {Object} [options] Options for the
115
- * validations. Valid options include 'message' and 'testIf'.
116
- *
117
- * @param {Function} validateProc(value,attrName) Function used to validate each
118
- * given attribute. Returns nothing if valid and an error message
119
- * otherwise. Function is called in the instance context and takes the
120
- * `value` and `attrName` to validate.
121
- *
122
- */
123
- validate: validate,
124
-
125
- /**
126
- * @attribute can.Observe.static.validationMessages
127
- * @parent can.Observe.validations
128
- *
129
- * `validationMessages` has the default validation error messages that will be returned by the builtin
130
- * validation methods. These can be overwritten by assigning new messages
131
- * to `can.Observe.validationMessages` in your application setup.
132
- *
133
- * The following messages (with defaults) are available:
134
- *
135
- * * format - "is invalid"
136
- * * inclusion - "is not a valid option (perhaps out of range)"
137
- * * lengthShort - "is too short"
138
- * * lengthLong - "is too long"
139
- * * presence - "can't be empty"
140
- * * range - "is out of range"
141
- *
142
- * It is important to steal can/observe/validations before
143
- * overwriting the messages, otherwise the changes will
144
- * be lost once steal loads it later.
145
- *
146
- * ## Example
147
- *
148
- * can.Observe.validationMessages.format = "is invalid dummy!"
149
- */
150
- validationMessages : {
151
- format : "is invalid",
152
- inclusion : "is not a valid option (perhaps out of range)",
153
- lengthShort : "is too short",
154
- lengthLong : "is too long",
155
- presence : "can't be empty",
156
- range : "is out of range"
157
- },
158
-
159
- /**
160
- * @function can.Observe.static.validateFormatOf
161
- * @parent can.Observe.validations
162
- *
163
- * `validateFormatOf(attrNames, regexp, options)` validates where the values of
164
- * specified attributes are of the correct form by
165
- * matching it against the regular expression provided.
166
- *
167
- * init : function(){
168
- * this.validateFormatOf(["email"],/[\w\.]+@]w+\.\w+/,{
169
- * message : "invalid email"
170
- * })
171
- * }
172
- *
173
- * @param {Array|String} attrNames Attribute name(s) to to validate
174
- * @param {RegExp} regexp Regular expression used to match for validation
175
- * @param {Object} [options] Options for the validations. Valid options include 'message' and 'testIf'.
176
- */
177
- validateFormatOf: function(attrNames, regexp, options) {
178
- validate.call(this, attrNames, options, function(value) {
179
- if( (typeof value != 'undefined' && value != '')
180
- && String(value).match(regexp) == null ) {
181
- return this.constructor.validationMessages.format;
182
- }
183
- });
184
- },
185
-
186
- /**
187
- * @function can.Observe.static.validateInclusionOf
188
- * @parent can.Observe.validations
189
- *
190
- * Validates whether the values of the specified attributes are available in a particular
191
- * array.
192
- *
193
- * init : function(){
194
- * this.validateInclusionOf(["salutation"],["Mr.","Mrs.","Dr."])
195
- * }
196
- *
197
- * @param {Array|String} attrNames Attribute name(s) to to validate
198
- * @param {Array} inArray Array of options to test for inclusion
199
- * @param {Object} [options] Options for the validations. Valid options include 'message' and 'testIf'.
200
- */
201
- validateInclusionOf: function(attrNames, inArray, options) {
202
- validate.call(this, attrNames, options, function(value) {
203
- if(typeof value == 'undefined'){
204
- return;
205
- }
206
33
 
207
- if(can.grep(inArray, function(elm) { return (elm == value); }).length == 0){
208
- return this.constructor.validationMessages.inclusion;
209
- }
210
- });
211
- },
212
-
213
- /**
214
- * @function can.Observe.static.validateLengthOf
215
- * @parent can.Observe.validations
216
- *
217
- * Validates that the specified attributes' lengths are in the given range.
218
- *
219
- * init : function(){
220
- * this.validateInclusionOf(["suffix"],3,5)
221
- * }
222
- *
223
- * @param {Number} min Minimum length (inclusive)
224
- * @param {Number} max Maximum length (inclusive)
225
- * @param {Object} [options] Options for the validations. Valid options include 'message' and 'testIf'.
226
- */
227
- validateLengthOf: function(attrNames, min, max, options) {
228
- validate.call(this, attrNames, options, function(value) {
229
- if((typeof value == 'undefined' && min > 0) || value.length < min){
230
- return this.constructor.validationMessages.lengthShort + " (min=" + min + ")";
231
- } else if(typeof value != 'undefined' && value.length > max){
232
- return this.constructor.validationMessages.lengthLong + " (max=" + max + ")";
233
- }
234
- });
235
- },
236
-
237
- /**
238
- * @function can.Observe.static.validatePresenceOf
239
- * @parent can.Observe.validations
240
- *
241
- * Validates that the specified attributes are not blank.
242
- *
243
- * init : function(){
244
- * this.validatePresenceOf(["name"])
245
- * }
246
- *
247
- * @param {Array|String} attrNames Attribute name(s) to to validate
248
- * @param {Object} [options] Options for the validations. Valid options include 'message' and 'testIf'.
249
- */
250
- validatePresenceOf: function(attrNames, options) {
251
- validate.call(this, attrNames, options, function(value) {
252
- if(typeof value == 'undefined' || value == "" || value === null){
253
- return this.constructor.validationMessages.presence;
254
- }
255
- });
256
- },
257
-
258
- /**
259
- * @function can.Observe.static.validateRangeOf
260
- * @parent can.Observe.validations
261
- *
262
- * Validates that the specified attributes are in the given numeric range.
263
- *
264
- * init : function(){
265
- * this.validateRangeOf(["age"],21, 130);
266
- * }
267
- *
268
- * @param {Array|String} attrNames Attribute name(s) to to validate
269
- * @param {Number} low Minimum value (inclusive)
270
- * @param {Number} hi Maximum value (inclusive)
271
- * @param {Object} [options] (optional) Options for the validations. Valid options include 'message' and 'testIf'.
272
- */
273
- validateRangeOf: function(attrNames, low, hi, options) {
274
- validate.call(this, attrNames, options, function(value) {
275
- if(typeof value != 'undefined' && value < low || value > hi){
276
- return this.constructor.validationMessages.range + " [" + low + "," + hi + "]";
34
+ self.validations[attrName].push(function (newVal) {
35
+ // if options has a message return that, otherwise, return the error
36
+ var res = proc.call(this, newVal, attrName);
37
+ return res === undefined ? undefined : (options.message || res);
38
+ })
39
+ });
40
+ };
41
+
42
+ var old = can.Observe.prototype.__set;
43
+ can.Observe.prototype.__set = function (prop, value, current, success, error) {
44
+ var self = this,
45
+ validations = self.constructor.validations,
46
+ errorCallback = function (errors) {
47
+ var stub = error && error.call(self, errors);
48
+
49
+ // if 'setter' is on the page it will trigger
50
+ // the error itself and we dont want to trigger
51
+ // the event twice. :)
52
+ if (stub !== false) {
53
+ can.trigger(self, "error", [prop, errors], true);
277
54
  }
278
- });
279
- }
280
- });
281
- });
282
-
283
- can.extend(can.Observe.prototype, {
284
-
285
- /**
286
- * @function can.Observe.prototype.errors
287
- * @parent can.Observe.validations
288
- *
289
- * Runs the validations on this observe. You can
290
- * also pass it an array of attributes to run only those attributes.
291
- * It returns nothing if there are no errors, or an object
292
- * of errors by attribute.
293
- *
294
- * To use validations, it's suggested you use the
295
- * observe/validations plugin.
296
- *
297
- * can.Observe("Task",{
298
- * init : function(){
299
- * this.validatePresenceOf("dueDate")
300
- * }
301
- * },{});
302
- *
303
- * var task = new Task(),
304
- * errors = task.errors()
305
- *
306
- * errors.dueDate[0] //-> "can't be empty"
307
- *
308
- * @param {Array|String} [attrs] An optional list of attributes to get errors for:
309
- *
310
- * task.errors(['dueDate','name']);
311
- *
312
- * Or it can take a single attr name like:
313
- *
314
- * task.errors('dueDate')
315
- *
316
- * @param {Object} [newVal] An optional new value to test setting
317
- * on the observe. If `newVal` is provided,
318
- * it returns the errors on the observe if `newVal` was set.
319
- *
320
- * @return {Object} an object of attributeName : [errors] like:
321
- *
322
- * task.errors() // -> {dueDate: ["cant' be empty"]}
323
- *
324
- * or `null` if there are no errors.
325
- */
326
- errors: function( attrs , newVal) {
327
- // convert attrs to an array
328
- if ( attrs ) {
329
- attrs = can.isArray(attrs) ? attrs : [attrs];
55
+
56
+ return false;
57
+ };
58
+
59
+ old.call(self, prop, value, current, success, errorCallback);
60
+
61
+ if (validations && validations[prop]) {
62
+ var errors = self.errors(prop);
63
+ errors && errorCallback(errors)
330
64
  }
331
-
332
- var errors = {},
333
- self = this,
334
- attr,
335
- // helper function that adds error messages to errors object
336
- // attr - the name of the attribute
337
- // funcs - the validation functions
338
- addErrors = function( attr, funcs ) {
339
- can.each(funcs, function( func ) {
340
- var res = func.call(self, isTest ? ( self.__convert ?
341
- self.__convert(attr,newVal) :
342
- newVal ): self[attr]);
343
- if ( res ) {
344
- if (!errors[attr] ) {
345
- errors[attr] = [];
346
- }
347
- errors[attr].push(res);
65
+
66
+ return this;
67
+ }
68
+
69
+ can.each([can.Observe, can.Model], function (clss) {
70
+ // in some cases model might not be defined quite yet.
71
+ if (clss === undefined) {
72
+ return;
73
+ }
74
+ var oldSetup = clss.setup;
75
+
76
+ can.extend(clss, {
77
+ setup: function (superClass) {
78
+ oldSetup.apply(this, arguments);
79
+ if (!this.validations || superClass.validations === this.validations) {
80
+ this.validations = {};
81
+ }
82
+ },
83
+
84
+ validate: validate,
85
+
86
+
87
+ validationMessages: {
88
+ format: "is invalid",
89
+ inclusion: "is not a valid option (perhaps out of range)",
90
+ lengthShort: "is too short",
91
+ lengthLong: "is too long",
92
+ presence: "can't be empty",
93
+ range: "is out of range"
94
+ },
95
+
96
+
97
+ validateFormatOf: function (attrNames, regexp, options) {
98
+ validate.call(this, attrNames, options, function (value) {
99
+ if ((typeof value != 'undefined' && value != '') && String(value).match(regexp) == null) {
100
+ return this.constructor.validationMessages.format;
348
101
  }
102
+ });
103
+ },
104
+
349
105
 
106
+ validateInclusionOf: function (attrNames, inArray, options) {
107
+ validate.call(this, attrNames, options, function (value) {
108
+ if (typeof value == 'undefined') {
109
+ return;
110
+ }
111
+
112
+ if (can.grep(inArray, function (elm) {
113
+ return (elm == value);
114
+ }).length == 0) {
115
+ return this.constructor.validationMessages.inclusion;
116
+ }
350
117
  });
351
118
  },
352
- validations = this.constructor.validations,
353
- isTest = attrs && attrs.length === 1 && arguments.length === 2;
354
-
355
- // go through each attribute or validation and
356
- // add any errors
357
- can.each(attrs || validations || {}, function( funcs, attr ) {
358
- // if we are iterating through an array, use funcs
359
- // as the attr name
360
- if ( typeof attr == 'number' ) {
361
- attr = funcs;
362
- funcs = validations[attr];
119
+
120
+
121
+ validateLengthOf: function (attrNames, min, max, options) {
122
+ validate.call(this, attrNames, options, function (value) {
123
+ if ((typeof value == 'undefined' && min > 0) || value.length < min) {
124
+ return this.constructor.validationMessages.lengthShort + " (min=" + min + ")";
125
+ } else if (typeof value != 'undefined' && value.length > max) {
126
+ return this.constructor.validationMessages.lengthLong + " (max=" + max + ")";
127
+ }
128
+ });
129
+ },
130
+
131
+
132
+ validatePresenceOf: function (attrNames, options) {
133
+ validate.call(this, attrNames, options, function (value) {
134
+ if (typeof value == 'undefined' || value === "" || value === null) {
135
+ return this.constructor.validationMessages.presence;
136
+ }
137
+ });
138
+ },
139
+
140
+
141
+ validateRangeOf: function (attrNames, low, hi, options) {
142
+ validate.call(this, attrNames, options, function (value) {
143
+ if (typeof value != 'undefined' && value < low || value > hi) {
144
+ return this.constructor.validationMessages.range + " [" + low + "," + hi + "]";
145
+ }
146
+ });
363
147
  }
364
- // add errors to the
365
- addErrors(attr, funcs || []);
366
148
  });
367
-
368
- // return errors as long as we have one
369
- return can.isEmptyObject(errors) ? null : isTest ? errors[attrs[0]] : errors;
370
- }
371
-
372
- });
149
+ });
150
+
151
+ can.extend(can.Observe.prototype, {
152
+
153
+
154
+ errors: function (attrs, newVal) {
155
+ // convert attrs to an array
156
+ if (attrs) {
157
+ attrs = can.isArray(attrs) ? attrs : [attrs];
158
+ }
159
+
160
+ var errors = {},
161
+ self = this,
162
+ attr,
163
+ // helper function that adds error messages to errors object
164
+ // attr - the name of the attribute
165
+ // funcs - the validation functions
166
+ addErrors = function (attr, funcs) {
167
+ can.each(funcs, function (func) {
168
+ var res = func.call(self, isTest ? (self.__convert ? self.__convert(attr, newVal) : newVal) : self[attr]);
169
+ if (res) {
170
+ if (!errors[attr]) {
171
+ errors[attr] = [];
172
+ }
173
+ errors[attr].push(res);
174
+ }
175
+
176
+ });
177
+ },
178
+ validations = this.constructor.validations,
179
+ isTest = attrs && attrs.length === 1 && arguments.length === 2;
180
+
181
+ // go through each attribute or validation and
182
+ // add any errors
183
+ can.each(attrs || validations || {}, function (funcs, attr) {
184
+ // if we are iterating through an array, use funcs
185
+ // as the attr name
186
+ if (typeof attr == 'number') {
187
+ attr = funcs;
188
+ funcs = validations[attr];
189
+ }
190
+ // add errors to the
191
+ addErrors(attr, funcs || []);
192
+ });
193
+
194
+ // return errors as long as we have one
195
+ return can.isEmptyObject(errors) ? null : isTest ? errors[attrs[0]] : errors;
196
+ }
197
+ });
373
198
 
374
- })(this.can, this )
199
+ })(can, this);