gunnertechnology 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +4 -0
  3. data/README +0 -0
  4. data/Rakefile +2 -0
  5. data/gunnertechnology.gemspec +28 -0
  6. data/lib/generators/project/USAGE +8 -0
  7. data/lib/generators/project/project_generator.rb +61 -0
  8. data/lib/generators/project/templates/app/controllers/authentications_controller.rb +85 -0
  9. data/lib/generators/project/templates/app/models/authentication.rb +17 -0
  10. data/lib/generators/project/templates/app/views/layouts/application.html.erb +77 -0
  11. data/lib/generators/project/templates/app/views/shared/_facebook_init.html.erb +12 -0
  12. data/lib/generators/project/templates/app/views/shared/_flash_messages.html.erb +7 -0
  13. data/lib/generators/project/templates/app/views/shared/_footer.html.erb +15 -0
  14. data/lib/generators/project/templates/app/views/shared/_google_analytics.html.erb +11 -0
  15. data/lib/generators/project/templates/app/views/shared/_header.html.erb +23 -0
  16. data/lib/generators/project/templates/config/facebook_config.yml +29 -0
  17. data/lib/generators/project/templates/config/google_analytics_config.yml +8 -0
  18. data/lib/generators/project/templates/config/initializers/load_facebook_config.rb +2 -0
  19. data/lib/generators/project/templates/config/initializers/load_google_analytics_config.rb +2 -0
  20. data/lib/generators/project/templates/config/initializers/load_seo_config.rb +2 -0
  21. data/lib/generators/project/templates/config/initializers/omniauth.rb +91 -0
  22. data/lib/generators/project/templates/config/providers.yml +27 -0
  23. data/lib/generators/project/templates/config/seo_config.yml +8 -0
  24. data/lib/generators/project/templates/db/create_authentications.rb +21 -0
  25. data/lib/generators/project/templates/public/javascripts/libs/PIE.htc +73 -0
  26. data/lib/generators/project/templates/public/javascripts/libs/colorpicker.js +484 -0
  27. data/lib/generators/project/templates/public/javascripts/libs/dd_belatedpng.js +13 -0
  28. data/lib/generators/project/templates/public/javascripts/libs/eye.js +34 -0
  29. data/lib/generators/project/templates/public/javascripts/libs/head.js +8 -0
  30. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-en.js +130 -0
  31. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-es.js +124 -0
  32. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-fr.js +119 -0
  33. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-it.js +103 -0
  34. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-pt.js +125 -0
  35. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine-ro.js +126 -0
  36. data/lib/generators/project/templates/public/javascripts/libs/jquery.validationEngine.js +1137 -0
  37. data/lib/generators/project/templates/public/javascripts/libs/layout.js +67 -0
  38. data/lib/generators/project/templates/public/javascripts/libs/modernizr-1.6.min.js +30 -0
  39. data/lib/generators/project/templates/public/javascripts/libs/utils.js +252 -0
  40. data/lib/generators/project/templates/public/javascripts/mylibs/.gitignore +3 -0
  41. data/lib/generators/project/templates/public/javascripts/plugins.js +38 -0
  42. data/lib/generators/project/templates/public/javascripts/profiling/config.js +59 -0
  43. data/lib/generators/project/templates/public/javascripts/profiling/yahoo-profiling.min.js +39 -0
  44. data/lib/generators/project/templates/public/javascripts/script.js +46 -0
  45. data/lib/generators/project/templates/public/stylesheets/grids/1008_24_10_10.css +201 -0
  46. data/lib/generators/project/templates/public/stylesheets/grids/fluid.css +320 -0
  47. data/lib/generators/project/templates/public/stylesheets/handheld.css +8 -0
  48. data/lib/generators/project/templates/public/stylesheets/profiling/yahoo-profiling.css +7 -0
  49. data/lib/generators/project/templates/public/stylesheets/reset.css +53 -0
  50. data/lib/generators/project/templates/public/stylesheets/text.css +84 -0
  51. data/lib/generators/project/templates/public/stylesheets/validationEngine.jquery.css +142 -0
  52. data/lib/generators/project/templates/public/swfs/charts.swf +0 -0
  53. data/lib/gunnertechnology/version.rb +3 -0
  54. data/lib/gunnertechnology.rb +47 -0
  55. metadata +206 -0
@@ -0,0 +1,1137 @@
1
+ /*
2
+ * Inline Form Validation Engine 2.0 Beta, jQuery plugin
3
+ *
4
+ * Copyright(c) 2010, Cedric Dugas
5
+ * http://www.position-absolute.com
6
+ *
7
+ * 2.0 Rewrite by Olivier Refalo
8
+ * http://www.crionics.com
9
+ *
10
+ * Form validation engine allowing custom regex rules to be added.
11
+ * Licensed under the MIT License
12
+ */
13
+ (function($) {
14
+
15
+ var methods = {
16
+
17
+ /**
18
+ * Kind of the constructor, called before any action
19
+ * @param {Map} user options
20
+ */
21
+ init: function(options) {
22
+
23
+ var form = this;
24
+ if (form.data('jqv') === undefined || form.data('jqv') == null ) {
25
+ methods._saveOptions(form, options);
26
+
27
+ // bind all formError elements to close on click
28
+ $(".formError").live("click", function() {
29
+ $(this).fadeOut(150, function() {
30
+
31
+ // remove prompt once invisible
32
+ $(this).remove();
33
+ });
34
+ });
35
+ }
36
+ },
37
+ /**
38
+ * Attachs jQuery.validationEngine to form.submit and field.blur events
39
+ * Takes an optional params: a list of options
40
+ * ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});
41
+ */
42
+ attach: function(userOptions) {
43
+ var form = this;
44
+
45
+ var options;
46
+
47
+ if(userOptions)
48
+ options = methods._saveOptions(form, userOptions);
49
+ else
50
+ options = form.data('jqv');
51
+
52
+ if (!options.binded) {
53
+ if(options.bindMethod == "bind"){
54
+ // bind fields
55
+ form.find("[class*=validate]").not("[type=checkbox]").bind(options.validationEventTrigger, methods._onFieldEvent);
56
+ form.find("[class*=validate][type=checkbox]").bind("click", methods._onFieldEvent);
57
+
58
+ // bind form.submit
59
+ form.bind("submit", methods._onSubmitEvent);
60
+ }else if(options.bindMethod == "live"){
61
+ // bind fields with LIVE (for persistant state)
62
+ form.find("[class*=validate]").not("[type=checkbox]").live(options.validationEventTrigger, methods._onFieldEvent);
63
+ form.find("[class*=validate][type=checkbox]").live("click", methods._onFieldEvent);
64
+
65
+ // bind form.submit
66
+ form.live("submit", methods._onSubmitEvent);
67
+ }
68
+
69
+ options.binded = true;
70
+ }
71
+
72
+ },
73
+ /**
74
+ * Unregisters any bindings that may point to jQuery.validaitonEngine
75
+ */
76
+ detach: function() {
77
+ var form = this;
78
+ var options = form.data('jqv');
79
+ if (options.binded) {
80
+
81
+ // unbind fields
82
+ form.find("[class*=validate]").not("[type=checkbox]").unbind(options.validationEventTrigger, methods._onFieldEvent);
83
+ form.find("[class*=validate][type=checkbox]").unbind("click", methods._onFieldEvent);
84
+ // unbind form.submit
85
+ form.unbind("submit", methods.onAjaxFormComplete);
86
+
87
+
88
+ // unbind live fields (kill)
89
+ form.find("[class*=validate]").not("[type=checkbox]").die(options.validationEventTrigger, methods._onFieldEvent);
90
+ form.find("[class*=validate][type=checkbox]").die("click", methods._onFieldEvent);
91
+ // unbind form.submit
92
+ form.die("submit", methods.onAjaxFormComplete);
93
+
94
+ form.removeData('jqv');
95
+ }
96
+ },
97
+ /**
98
+ * Validates the form fields, shows prompts accordingly.
99
+ * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
100
+ *
101
+ * @return true if the form validates, false if it fails
102
+ */
103
+ validate: function() {
104
+ return methods._validateFields(this);
105
+ },
106
+ /**
107
+ * Validates one field, shows prompt accordingly.
108
+ * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
109
+ *
110
+ * @return true if the form validates, false if it fails
111
+ */
112
+ validateField: function(el) {
113
+ var options = $(this).data('jqv');
114
+ return methods._validateField($(el), options);
115
+ },
116
+ /**
117
+ * Validates the form fields, shows prompts accordingly.
118
+ * Note: this methods performs fields and form ajax validations(if setup)
119
+ *
120
+ * @return true if the form validates, false if it fails, undefined if ajax is used for form validation
121
+ */
122
+ validateform: function() {
123
+ return methods._onSubmitEvent(this);
124
+ },
125
+ /**
126
+ * Displays a prompt on a element.
127
+ * Note that the element needs an id!
128
+ *
129
+ * @param {String} promptText html text to display type
130
+ * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
131
+ * @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
132
+ */
133
+ showPrompt: function(promptText, type, promptPosition, showArrow) {
134
+
135
+ var form = this.closest('form');
136
+ var options = form.data('jqv');
137
+
138
+ if(!promptPosition)
139
+ options.promptPosition=promptPosition;
140
+ options.showArrow = showArrow===true;
141
+
142
+ methods._showPrompt(this, promptText, type, false, options);
143
+ },
144
+ /**
145
+ * Closes all error prompts on the page
146
+ */
147
+ hidePrompt: function() {
148
+ var promptClass = "."+ $(this).attr("id") + "formError"
149
+ $(promptClass).fadeTo("fast", 0.3, function() {
150
+ $(this).remove();
151
+ });
152
+ },
153
+ /**
154
+ * Closes form error prompts
155
+ */
156
+ hide: function() {
157
+ var form = this;
158
+ form.find('.formError').fadeTo("fast", 0.3, function() {
159
+ $(this).remove();
160
+ });
161
+ },
162
+ /**
163
+ * Closes all error prompts on the page
164
+ */
165
+ hideAll: function() {
166
+ $('.formError').fadeTo("fast", 0.3, function() {
167
+ $(this).remove();
168
+ });
169
+ },
170
+ /**
171
+ * Typically called when user exists a field using tab or a mouse click, triggers a field
172
+ * validation
173
+ */
174
+ _onFieldEvent: function() {
175
+ var field = $(this);
176
+ var form = field.closest('form');
177
+ var options = form.data('jqv');
178
+ // validate the current field
179
+ methods._validateField(field, options);
180
+ },
181
+ /**
182
+ * Called when the form is submited, shows prompts accordingly
183
+ *
184
+ * @param {jqObject}
185
+ * form
186
+ * @return false if form submission needs to be cancelled
187
+ */
188
+ _onSubmitEvent: function() {
189
+
190
+ var form = $(this);
191
+ var r=methods._validateFields(form, true);
192
+
193
+ var options = form.data('jqv');
194
+ // validate the form using AJAX
195
+ if (r && options.ajaxFormValidation) {
196
+
197
+ methods._validateFormWithAjax(form, options);
198
+ return false;
199
+ }
200
+
201
+ if(options.onValidationComplete) {
202
+ options.onValidationComplete(form, r);
203
+ return false;
204
+ }
205
+ return r;
206
+ },
207
+ /**
208
+ * Return true if the ajax field validations passed so far
209
+ * @param {Object} options
210
+ * @return true, is all ajax validation passed so far (remember ajax is async)
211
+ */
212
+ _checkAjaxStatus: function(options) {
213
+ var status = true;
214
+ $.each(options.ajaxValidCache, function(key, value) {
215
+ if (value === false) {
216
+ status = false;
217
+ // break the each
218
+ return false;
219
+ }
220
+ });
221
+ return status;
222
+ },
223
+ /**
224
+ * Validates form fields, shows prompts accordingly
225
+ *
226
+ * @param {jqObject}
227
+ * form
228
+ * @return true if form is valid, false if not, undefined if ajax form validation is done
229
+ */
230
+ _validateFields: function(form, skipAjaxFieldValidation) {
231
+
232
+ var options = form.data('jqv');
233
+
234
+ // this variable is set to true if an error is found
235
+ var errorFound = false;
236
+
237
+ // first, evaluate status of non ajax fields
238
+ form.find('[class*=validate]').not(':hidden').each( function() {
239
+ var field = $(this);
240
+ // fields being valiated though ajax are marked with 'ajaxed',
241
+ // skip them
242
+ if (!field.hasClass("ajaxed"))
243
+ errorFound |= methods._validateField(field, options, skipAjaxFieldValidation);
244
+ });
245
+ // second, check to see if all ajax calls completed ok
246
+ errorFound |= !methods._checkAjaxStatus(options);
247
+
248
+ // thrird, check status and scroll the container accordingly
249
+ if (errorFound) {
250
+ if (options.scroll) {
251
+
252
+ // get the position of the first error, there should be at least one, no need to check this
253
+ //var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
254
+
255
+ // look for the visually top prompt
256
+ var destination = Number.MAX_VALUE;
257
+
258
+ var lst = $(".formError:not('.greenPopup')");
259
+ for (var i = 0; i < lst.length; i++) {
260
+ var d = $(lst[i]).offset().top;
261
+ if (d < destination)
262
+ destination = d;
263
+ }
264
+
265
+ if (!options.isOverflown)
266
+ $("html:not(:animated),body:not(:animated)").animate({
267
+ scrollTop: destination
268
+ }, 1100);
269
+ else {
270
+ var overflowDIV = $(options.overflownDIV);
271
+ var scrollContainerScroll = overflowDIV.scrollTop();
272
+ var scrollContainerPos = -parseInt(overflowDIV.offset().top);
273
+
274
+ destination += scrollContainerScroll + scrollContainerPos - 5;
275
+ var scrollContainer = $(options.overflownDIV + ":not(:animated)");
276
+
277
+ scrollContainer.animate({
278
+ scrollTop: destination
279
+ }, 1100);
280
+ }
281
+ }
282
+ return false;
283
+ }
284
+ return true;
285
+ },
286
+ /**
287
+ * This method is called to perform an ajax form validation.
288
+ * During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
289
+ *
290
+ * @param {jqObject} form
291
+ * @param {Map} options
292
+ */
293
+ _validateFormWithAjax: function(form, options) {
294
+
295
+ var data = form.serialize();
296
+
297
+ $.ajax({
298
+ type: "GET",
299
+ url: form.attr("action"),
300
+ cache: false,
301
+ dataType: "json",
302
+ data: data,
303
+ form: form,
304
+ methods: methods,
305
+ options: options,
306
+ beforeSend: function() {
307
+ return options.onBeforeAjaxFormValidation(form, options);
308
+ },
309
+ error: function(data, transport) {
310
+ methods._ajaxError(data, transport);
311
+ },
312
+ success: function(json) {
313
+
314
+ if (json !== true) {
315
+
316
+ // getting to this case doesn't necessary means that the form is invalid
317
+ // the server may return green or closing prompt actions
318
+ // this flag helps figuring it out
319
+ var errorInForm=false;
320
+ for (var i = 0; i < json.length; i++) {
321
+ var value = json[i];
322
+
323
+ var errorFieldId = value[0];
324
+ var errorField = $($("#" + errorFieldId)[0]);
325
+
326
+ // make sure we found the element
327
+ if (errorField.length == 1) {
328
+
329
+ // promptText or selector
330
+ var msg = value[2];
331
+
332
+ if (value[1] === true) {
333
+
334
+ if (msg == "")
335
+ // if for some reason, status==true and error="", just close the prompt
336
+ methods._closePrompt(errorField);
337
+ else {
338
+ // the field is valid, but we are displaying a green prompt
339
+ if (options.allrules[msg]) {
340
+ var txt = options.allrules[msg].alertTextOk;
341
+ if (txt)
342
+ msg = txt;
343
+ }
344
+ methods._showPrompt(errorField, msg, "pass", false, options);
345
+ }
346
+ } else {
347
+ // the field is invalid, show the red error prompt
348
+ errorInForm|=true;
349
+ if (options.allrules[msg]) {
350
+ var txt = options.allrules[msg].alertText;
351
+ if (txt)
352
+ msg = txt;
353
+ }
354
+ methods._showPrompt(errorField, msg, "", false, options);
355
+ }
356
+ }
357
+ }
358
+ options.onAjaxFormComplete(!errorInForm, form, json, options);
359
+ } else
360
+ options.onAjaxFormComplete(true, form, "", options);
361
+ }
362
+ });
363
+
364
+ },
365
+ /**
366
+ * Validates field, shows prompts accordingly
367
+ *
368
+ * @param {jqObject}
369
+ * field
370
+ * @param {Array[String]}
371
+ * field's validation rules
372
+ * @param {Map}
373
+ * user options
374
+ * @return true if field is valid
375
+ */
376
+ _validateField: function(field, options, skipAjaxFieldValidation) {
377
+
378
+ if (!field.attr("id"))
379
+ $.error("jQueryValidate: an ID attribute is required for this field: " + field.attr("name") + " class:" +
380
+ field.attr("class"));
381
+
382
+ var rulesParsing = field.attr('class');
383
+ var getRules = /\[(.*)\]/.exec(rulesParsing);
384
+ if (getRules === null)
385
+ return false;
386
+ var str = getRules[1];
387
+ var rules = str.split(/\[|,|\]/);
388
+
389
+ // true if we ran the ajax validation, tells the logic to stop messing with prompts
390
+ var isAjaxValidator = false;
391
+ var fieldName = field.attr("name");
392
+ var promptText = "";
393
+ var required = false;
394
+ options.isError = false;
395
+ options.showArrow = true;
396
+
397
+ for (var i = 0; i < rules.length; i++) {
398
+
399
+ var errorMsg = undefined;
400
+ switch (rules[i]) {
401
+
402
+ case "required":
403
+ required = true;
404
+ errorMsg = methods._required(field, rules, i, options);
405
+ break;
406
+ case "custom":
407
+ errorMsg = methods._customRegex(field, rules, i, options);
408
+ break;
409
+ case "ajax":
410
+ if(!skipAjaxFieldValidation) {
411
+ // ajax has its own prompts handling technique
412
+ methods._ajax(field, rules, i, options);
413
+ isAjaxValidator = true;
414
+ }
415
+ break;
416
+ case "minSize":
417
+ errorMsg = methods._minSize(field, rules, i, options);
418
+ break;
419
+ case "maxSize":
420
+ errorMsg = methods._maxSize(field, rules, i, options);
421
+ break;
422
+ case "min":
423
+ errorMsg = methods._min(field, rules, i, options);
424
+ break;
425
+ case "max":
426
+ errorMsg = methods._max(field, rules, i, options);
427
+ break;
428
+ case "past":
429
+ errorMsg = methods._past(field, rules, i, options);
430
+ break;
431
+ case "future":
432
+ errorMsg = methods._future(field, rules, i, options);
433
+ break;
434
+ case "maxCheckbox":
435
+ errorMsg = methods._maxCheckbox(field, rules, i, options);
436
+ field = $($("input[name='" + fieldName + "']"));
437
+ break;
438
+ case "minCheckbox":
439
+ errorMsg = methods._minCheckbox(field, rules, i, options);
440
+ field = $($("input[name='" + fieldName + "']"));
441
+ break;
442
+ case "equals":
443
+ errorMsg = methods._equals(field, rules, i, options);
444
+ break;
445
+ case "funcCall":
446
+ errorMsg = methods._funcCall(field, rules, i, options);
447
+ break;
448
+ default:
449
+ //$.error("jQueryValidator rule not found"+rules[i]);
450
+ }
451
+
452
+ if (errorMsg !== undefined) {
453
+ promptText += errorMsg + "<br/>";
454
+ options.isError = true;
455
+ }
456
+
457
+ }
458
+ // If the rules required is not added, an empty field is not validated
459
+ if(!required){
460
+ if(field.val() == "") options.isError = false;
461
+ }
462
+ // Hack for radio/checkbox group button, the validation go into the
463
+ // first radio/checkbox of the group
464
+ var fieldType = field.attr("type");
465
+
466
+ if ((fieldType == "radio" || fieldType == "checkbox") && $("input[name='" + fieldName + "']").size() > 1) {
467
+ field = $($("input[name='" + fieldName + "'][type!=hidden]:first"));
468
+ options.showArrow = false;
469
+ }
470
+
471
+ if (!isAjaxValidator) {
472
+ if (options.isError) {
473
+ methods._showPrompt(field, promptText, "", false, options);
474
+ } else {
475
+ if(options.showOK && field.attr("type") != "radio" && field.attr("type") != "checkbox" && field.get("0").tagName.toLowerCase() != "select") {
476
+ methods._showPrompt(field, options.alertTextOKText, "pass", true, options);
477
+ } else {
478
+ methods._closePrompt(field);
479
+ }
480
+ }
481
+
482
+ }
483
+ return options.isError;
484
+ },
485
+ /**
486
+ * Required validation
487
+ *
488
+ * @param {jqObject} field
489
+ * @param {Array[String]} rules
490
+ * @param {int} i rules index
491
+ * @param {Map}
492
+ * user options
493
+ * @return an error string if validation failed
494
+ */
495
+ _required: function(field, rules, i, options) {
496
+
497
+ switch (field.attr("type")) {
498
+ case "text":
499
+ case "password":
500
+ case "textarea":
501
+ if (!field.val())
502
+ return options.allrules[rules[i]].alertText;
503
+ break;
504
+ case "radio":
505
+ case "checkbox":
506
+ var name = field.attr("name");
507
+ if ($("input[name='" + name + "']:checked").size() === 0) {
508
+
509
+ if ($("input[name='" + name + "']").size() === 1)
510
+ return options.allrules[rules[i]].alertTextCheckboxe;
511
+ else
512
+ return options.allrules[rules[i]].alertTextCheckboxMultiple;
513
+ }
514
+ break;
515
+ // required for <select>
516
+ case "select-one":
517
+ // added by paul@kinetek.net for select boxes, Thank you
518
+ if (!field.val())
519
+ return options.allrules[rules[i]].alertText;
520
+ break;
521
+ case "select-multiple":
522
+ // added by paul@kinetek.net for select boxes, Thank you
523
+ if (!field.find("option:selected").val())
524
+ return options.allrules[rules[i]].alertText;
525
+ break;
526
+ }
527
+ },
528
+ /**
529
+ * Validate Regex rules
530
+ *
531
+ * @param {jqObject} field
532
+ * @param {Array[String]} rules
533
+ * @param {int} i rules index
534
+ * @param {Map}
535
+ * user options
536
+ * @return an error string if validation failed
537
+ */
538
+ _customRegex: function(field, rules, i, options) {
539
+ var customRule = rules[i + 1];
540
+ var pattern = new RegExp(options.allrules[customRule].regex);
541
+
542
+ if (!pattern.test(field.attr('value')))
543
+ return options.allrules[customRule].alertText;
544
+ },
545
+ /**
546
+ * Validate custom function outside of the engine scope
547
+ *
548
+ * @param {jqObject} field
549
+ * @param {Array[String]} rules
550
+ * @param {int} i rules index
551
+ * @param {Map}
552
+ * user options
553
+ * @return an error string if validation failed
554
+ */
555
+ _funcCall: function(field, rules, i, options) {
556
+ var functionName = rules[i + 1];
557
+ var fn = window[functionName];
558
+ if (typeof(fn) === 'function')
559
+ return fn(field, rules, i, options);
560
+
561
+ },
562
+ /**
563
+ * Field match
564
+ *
565
+ * @param {jqObject} field
566
+ * @param {Array[String]} rules
567
+ * @param {int} i rules index
568
+ * @param {Map}
569
+ * user options
570
+ * @return an error string if validation failed
571
+ */
572
+ _equals: function(field, rules, i, options) {
573
+ var equalsField = rules[i + 1];
574
+
575
+ if (field.attr('value') != $("#" + equalsField).attr('value'))
576
+ return options.allrules.equals.alertText;
577
+ },
578
+ /**
579
+ * Check the maximum size (in characters)
580
+ *
581
+ * @param {jqObject} field
582
+ * @param {Array[String]} rules
583
+ * @param {int} i rules index
584
+ * @param {Map}
585
+ * user options
586
+ * @return an error string if validation failed
587
+ */
588
+ _maxSize: function(field, rules, i, options) {
589
+ var max = rules[i + 1];
590
+ var len = field.attr('value').length;
591
+
592
+ if (len > max) {
593
+ var rule = options.allrules.maxSize;
594
+ return rule.alertText + max + rule.alertText2;
595
+ }
596
+ },
597
+ /**
598
+ * Check the minimum size (in characters)
599
+ *
600
+ * @param {jqObject} field
601
+ * @param {Array[String]} rules
602
+ * @param {int} i rules index
603
+ * @param {Map}
604
+ * user options
605
+ * @return an error string if validation failed
606
+ */
607
+ _minSize: function(field, rules, i, options) {
608
+ var min = rules[i + 1];
609
+ var len = field.attr('value').length;
610
+
611
+ if (len < min) {
612
+ var rule = options.allrules.minSize;
613
+ return rule.alertText + min + rule.alertText2;
614
+ }
615
+ },
616
+ /**
617
+ * Check number minimum value
618
+ *
619
+ * @param {jqObject} field
620
+ * @param {Array[String]} rules
621
+ * @param {int} i rules index
622
+ * @param {Map}
623
+ * user options
624
+ * @return an error string if validation failed
625
+ */
626
+ _min: function(field, rules, i, options) {
627
+ var min = parseFloat(rules[i + 1]);
628
+ var len = parseFloat(field.attr('value'));
629
+
630
+ if (len < min) {
631
+ var rule = options.allrules.min;
632
+ return rule.alertText + min;
633
+ }
634
+ },
635
+ /**
636
+ * Check number maximum value
637
+ *
638
+ * @param {jqObject} field
639
+ * @param {Array[String]} rules
640
+ * @param {int} i rules index
641
+ * @param {Map}
642
+ * user options
643
+ * @return an error string if validation failed
644
+ */
645
+ _max: function(field, rules, i, options) {
646
+ var max = parseFloat(rules[i + 1]);
647
+ var len = parseFloat(field.attr('value'));
648
+
649
+ if (len >max ) {
650
+ var rule = options.allrules.max;
651
+ //orefalo: to review, also do the translations
652
+ return rule.alertText + max;
653
+ }
654
+ },
655
+ /**
656
+ * Checks date is in the past
657
+ *
658
+ * @param {jqObject} field
659
+ * @param {Array[String]} rules
660
+ * @param {int} i rules index
661
+ * @param {Map}
662
+ * user options
663
+ * @return an error string if validation failed
664
+ */
665
+ _past: function(field, rules, i, options) {
666
+
667
+ var p=rules[i + 1];
668
+ var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
669
+ var vdate = methods._parseDate(field.attr('value'));
670
+
671
+ if (vdate > pdate ) {
672
+ var rule = options.allrules.past;
673
+ return rule.alertText + methods._dateToString(pdate);
674
+ }
675
+ },
676
+ /**
677
+ * Checks date is in the past
678
+ *
679
+ * @param {jqObject} field
680
+ * @param {Array[String]} rules
681
+ * @param {int} i rules index
682
+ * @param {Map}
683
+ * user options
684
+ * @return an error string if validation failed
685
+ */
686
+ _future: function(field, rules, i, options) {
687
+
688
+ var p=rules[i + 1];
689
+ var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
690
+ var vdate = methods._parseDate(field.attr('value'));
691
+
692
+ if (vdate < pdate ) {
693
+ var rule = options.allrules.future;
694
+ return rule.alertText + methods._dateToString(pdate);
695
+ }
696
+ },
697
+ /**
698
+ * Max number of checkbox selected
699
+ *
700
+ * @param {jqObject} field
701
+ * @param {Array[String]} rules
702
+ * @param {int} i rules index
703
+ * @param {Map}
704
+ * user options
705
+ * @return an error string if validation failed
706
+ */
707
+ _maxCheckbox: function(field, rules, i, options) {
708
+
709
+ var nbCheck = rules[i + 1];
710
+ var groupname = field.attr("name");
711
+ var groupSize = $("input[name='" + groupname + "']:checked").size();
712
+ if (groupSize > nbCheck) {
713
+ options.showArrow = false;
714
+ return options.allrules.maxCheckbox.alertText;
715
+ }
716
+ },
717
+ /**
718
+ * Min number of checkbox selected
719
+ *
720
+ * @param {jqObject} field
721
+ * @param {Array[String]} rules
722
+ * @param {int} i rules index
723
+ * @param {Map}
724
+ * user options
725
+ * @return an error string if validation failed
726
+ */
727
+ _minCheckbox: function(field, rules, i, options) {
728
+
729
+ var nbCheck = rules[i + 1];
730
+ var groupname = field.attr("name");
731
+ var groupSize = $("input[name='" + groupname + "']:checked").size();
732
+ if (groupSize < nbCheck) {
733
+ options.showArrow = false;
734
+ return options.allrules.minCheckbox.alertText + " " + nbCheck + " " +
735
+ options.allrules.minCheckbox.alertText2;
736
+ }
737
+ },
738
+ /**
739
+ * Ajax field validation
740
+ *
741
+ * @param {jqObject} field
742
+ * @param {Array[String]} rules
743
+ * @param {int} i rules index
744
+ * @param {Map}
745
+ * user options
746
+ * @return nothing! the ajax validator handles the prompts itself
747
+ */
748
+ _ajax: function(field, rules, i, options) {
749
+
750
+ var errorSelector = rules[i + 1];
751
+ var rule = options.allrules[errorSelector];
752
+ var extraData = rule.extraData;
753
+
754
+ if (!extraData)
755
+ extraData = "";
756
+
757
+ if (!options.isError) {
758
+ $.ajax({
759
+ type: "GET",
760
+ url: rule.url,
761
+ cache: false,
762
+ dataType: "json",
763
+ data: "fieldId=" + field.attr("id") + "&fieldValue=" + field.attr("value") + "&extraData=" + extraData,
764
+ field: field,
765
+ rule: rule,
766
+ methods: methods,
767
+ options: options,
768
+ beforeSend: function() {
769
+ // build the loading prompt
770
+ var loadingText = rule.alertTextLoad;
771
+ if (loadingText)
772
+ methods._showPrompt(field, loadingText, "load", true, options);
773
+ },
774
+ error: function(data, transport) {
775
+ methods._ajaxError(data, transport);
776
+ },
777
+ success: function(json) {
778
+
779
+ // asynchronously called on success, data is the json answer from the server
780
+ var errorFieldId = json[0];
781
+ var errorField = $($("#" + errorFieldId)[0]);
782
+ // make sure we found the element
783
+ if (errorField.length == 1) {
784
+
785
+ var status = json[1];
786
+
787
+ if (status === false) {
788
+ // Houston we got a problem
789
+ options.ajaxValidCache[errorFieldId] = false;
790
+ options.isError = true;
791
+ var promptText = rule.alertText;
792
+ methods._showPrompt(errorField, promptText, "", true, options);
793
+ } else {
794
+ if (options.ajaxValidCache[errorFieldId] !== undefined)
795
+ options.ajaxValidCache[errorFieldId] = true;
796
+
797
+ // see if we should display a green prompt
798
+ var alertTextOk = rule.alertTextOk;
799
+ if (alertTextOk)
800
+ methods._showPrompt(errorField, alertTextOk, "pass", true, options);
801
+ else
802
+ methods._closePrompt(errorField);
803
+ }
804
+ }
805
+ }
806
+ });
807
+ }
808
+ },
809
+ /**
810
+ * Common method to handle ajax errors
811
+ *
812
+ * @param {Object} data
813
+ * @param {Object} transport
814
+ */
815
+ _ajaxError: function(data, transport) {
816
+ if(data.status === 0 && transport === null)
817
+ alert("The page is not served from a server! ajax call failed");
818
+ else if(console)
819
+ console.log("Ajax error: " + data.status + " " + transport);
820
+ },
821
+ /**
822
+ * date -> string
823
+ *
824
+ * @param {Object} date
825
+ */
826
+ _dateToString: function(date) {
827
+
828
+ return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
829
+ },
830
+ /**
831
+ * Parses an ISO date
832
+ * @param {String} d
833
+ */
834
+ _parseDate: function(d) {
835
+
836
+ var dateParts = d.split("-");
837
+ if(dateParts!==d)
838
+ dateParts = d.split("/");
839
+ return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
840
+ },
841
+ /**
842
+ * Builds or updates a prompt with the given information
843
+ *
844
+ * @param {jqObject} field
845
+ * @param {String} promptText html text to display type
846
+ * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
847
+ * @param {boolean} ajaxed - use to mark fields than being validated with ajax
848
+ * @param {Map} options user options
849
+ */
850
+ _showPrompt: function(field, promptText, type, ajaxed, options) {
851
+ var prompt = methods._getPrompt(field);
852
+ if (prompt)
853
+ methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
854
+ else
855
+ methods._buildPrompt(field, promptText, type, ajaxed, options);
856
+ },
857
+ /**
858
+ * Builds and shades a prompt for the given field.
859
+ *
860
+ * @param {jqObject} field
861
+ * @param {String} promptText html text to display type
862
+ * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
863
+ * @param {boolean} ajaxed - use to mark fields than being validated with ajax
864
+ * @param {Map} options user options
865
+ */
866
+ _buildPrompt: function(field, promptText, type, ajaxed, options) {
867
+
868
+ // create the prompt
869
+ var prompt = $('<div>');
870
+ prompt.addClass(field.attr("id") + "formError");
871
+ prompt.addClass("formError");
872
+
873
+ switch (type) {
874
+ case "pass":
875
+ prompt.addClass("greenPopup");
876
+ break;
877
+ case "load":
878
+ prompt.addClass("blackPopup");
879
+ }
880
+ if (ajaxed)
881
+ prompt.addClass("ajaxed");
882
+
883
+ // create the prompt content
884
+ var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
885
+
886
+ // create the css arrow pointing at the field
887
+ // note that there is no triangle on max-checkbox and radio
888
+ if (options.showArrow) {
889
+ var arrow = $('<div>').addClass("formErrorArrow");
890
+
891
+ switch (options.promptPosition) {
892
+ case "bottomLeft":
893
+ case "bottomRight":
894
+ prompt.find(".formErrorContent").before(arrow);
895
+ arrow.addClass("formErrorArrowBottom").html('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
896
+ break;
897
+ case "topLeft":
898
+ case "topRight":
899
+ arrow.html('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');
900
+ prompt.append(arrow);
901
+ break;
902
+ }
903
+ }
904
+
905
+ //Cedric: Needed if a container is in position:relative
906
+ // insert prompt in the form or in the overflown container?
907
+ if (options.isOverflown)
908
+ field.before(prompt);
909
+ else
910
+ $("body").append(prompt);
911
+
912
+ var pos = methods._calculatePosition(field, prompt, options);
913
+ prompt.css({
914
+ "top": pos.callerTopPosition,
915
+ "left": pos.callerleftPosition,
916
+ "marginTop": pos.marginTopSize,
917
+ "opacity": 0
918
+ });
919
+
920
+ return prompt.animate({
921
+ "opacity": 0.87
922
+ });
923
+
924
+ },
925
+ /**
926
+ * Updates the prompt text field - the field for which the prompt
927
+ * @param {jqObject} field
928
+ * @param {String} promptText html text to display type
929
+ * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
930
+ * @param {boolean} ajaxed - use to mark fields than being validated with ajax
931
+ * @param {Map} options user options
932
+ */
933
+ _updatePrompt: function(field, prompt, promptText, type, ajaxed, options) {
934
+
935
+ if (prompt) {
936
+ if (type == "pass")
937
+ prompt.addClass("greenPopup");
938
+ else
939
+ prompt.removeClass("greenPopup");
940
+
941
+ if (type == "load")
942
+ prompt.addClass("blackPopup");
943
+ else
944
+ prompt.removeClass("blackPopup");
945
+
946
+ if (ajaxed)
947
+ prompt.addClass("ajaxed");
948
+ else
949
+ prompt.removeClass("ajaxed");
950
+
951
+ prompt.find(".formErrorContent").html(promptText);
952
+
953
+ var pos = methods._calculatePosition(field, prompt, options);
954
+ prompt.animate({
955
+ "top": pos.callerTopPosition,
956
+ "marginTop": pos.marginTopSize
957
+ });
958
+ }
959
+ },
960
+ /**
961
+ * Closes the prompt associated with the given field
962
+ *
963
+ * @param {jqObject}
964
+ * field
965
+ */
966
+ _closePrompt: function(field) {
967
+
968
+ var prompt = methods._getPrompt(field);
969
+ if (prompt)
970
+ prompt.fadeTo("fast", 0, function() {
971
+ prompt.remove();
972
+ });
973
+ },
974
+ /**
975
+ * Returns the error prompt matching the field if any
976
+ *
977
+ * @param {jqObject}
978
+ * field
979
+ * @return undefined or the error prompt (jqObject)
980
+ */
981
+ _getPrompt: function(field) {
982
+
983
+ var className = "." + field.attr("id") + "formError";
984
+ var match = $(className)[0];
985
+ if (match)
986
+ return $(match);
987
+ },
988
+ /**
989
+ * Calculates prompt position
990
+ *
991
+ * @param {jqObject}
992
+ * field
993
+ * @param {jqObject}
994
+ * the prompt
995
+ * @param {Map}
996
+ * options
997
+ * @return positions
998
+ */
999
+ _calculatePosition: function(field, promptElmt, options) {
1000
+
1001
+ var promptTopPosition, promptleftPosition, marginTopSize;
1002
+ var fieldWidth = field.width();
1003
+ var promptHeight = promptElmt.height();
1004
+
1005
+ var overflow = options.isOverflown;
1006
+ if (overflow) {
1007
+ // is the form contained in an overflown container?
1008
+ promptTopPosition = promptleftPosition = 0;
1009
+ // compensation for the arrow
1010
+ marginTopSize = -promptHeight;
1011
+ } else {
1012
+ var offset = field.offset();
1013
+ promptTopPosition = offset.top;
1014
+ promptleftPosition = offset.left;
1015
+ marginTopSize = 0;
1016
+ }
1017
+
1018
+ switch (options.promptPosition) {
1019
+
1020
+ default:
1021
+ case "topRight":
1022
+ if (overflow)
1023
+ // Is the form contained in an overflown container?
1024
+ promptleftPosition += fieldWidth - 30;
1025
+ else {
1026
+ promptleftPosition += fieldWidth - 30;
1027
+ promptTopPosition += -promptHeight;
1028
+ }
1029
+ break;
1030
+ case "topLeft":
1031
+ promptTopPosition += -promptHeight - 10;
1032
+ break;
1033
+ case "centerRight":
1034
+ promptleftPosition += fieldWidth + 13;
1035
+ break;
1036
+ case "bottomLeft":
1037
+ promptTopPosition = promptTopPosition + field.height() + 15;
1038
+ break;
1039
+ case "bottomRight":
1040
+ promptleftPosition += fieldWidth - 30;
1041
+ promptTopPosition += field.height() + 5;
1042
+ }
1043
+
1044
+ return {
1045
+ "callerTopPosition": promptTopPosition + "px",
1046
+ "callerleftPosition": promptleftPosition + "px",
1047
+ "marginTopSize": marginTopSize + "px"
1048
+ };
1049
+ },
1050
+ /**
1051
+ * Saves the user options and variables in the form.data
1052
+ *
1053
+ * @param {jqObject}
1054
+ * form - the form where the user option should be saved
1055
+ * @param {Map}
1056
+ * options - the user options
1057
+ * @return the user options (extended from the defaults)
1058
+ */
1059
+ _saveOptions: function(form, options) {
1060
+
1061
+ // is there a language localisation ?
1062
+ if ($.validationEngineLanguage)
1063
+ var allRules = $.validationEngineLanguage.allRules;
1064
+ else
1065
+ $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
1066
+
1067
+ var userOptions = $.extend({
1068
+
1069
+ // Name of the event triggering field validation
1070
+ validationEventTrigger: "blur",
1071
+ // Automatically scroll viewport to the first error
1072
+ scroll: true,
1073
+ // Opening box position, possible locations are: topLeft,
1074
+ // topRight, bottomLeft, centerRight, bottomRight
1075
+ promptPosition: "topRight",
1076
+ bindMethod:"bind",
1077
+
1078
+ // if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
1079
+ ajaxFormValidation: false,
1080
+ // Ajax form validation callback method: boolean onComplete(form, status, errors, options)
1081
+ // retuns false if the form.submit event needs to be canceled.
1082
+ onAjaxFormComplete: $.noop,
1083
+ // called right before the ajax call, may return false to cancel
1084
+ onBeforeAjaxFormValidation: $.noop,
1085
+ // Stops form from submitting and execute function assiciated with it
1086
+ onValidationComplete: false,
1087
+
1088
+ // Used when the form is displayed within a scrolling DIV
1089
+ isOverflown: false,
1090
+ overflownDIV: "",
1091
+
1092
+ // --- Internals DO NOT TOUCH or OVERLOAD ---
1093
+ // validation rules and i18
1094
+ allrules: allRules,
1095
+ // true when form and fields are binded
1096
+ binded: false,
1097
+ // set to true, when the prompt arrow needs to be displayed
1098
+ showArrow: true,
1099
+ // did one of the validation fail ? kept global to stop further ajax validations
1100
+ isError: false,
1101
+ // Caches field validation status, typically only bad status are created.
1102
+ // the array is used during ajax form validation to detect issues early and prevent an expensive submit
1103
+ ajaxValidCache: {}
1104
+
1105
+ }, options);
1106
+
1107
+ form.data('jqv', userOptions);
1108
+ return userOptions;
1109
+ }
1110
+ };
1111
+
1112
+ /**
1113
+ * Plugin entry point.
1114
+ * You may pass an action as a parameter or a list of options.
1115
+ * if none, the init and attach methods are being called.
1116
+ * Remember: if you pass options, the attached method is NOT called automatically
1117
+ *
1118
+ * @param {String}
1119
+ * method (optional) action
1120
+ */
1121
+ $.fn.validationEngine = function(method) {
1122
+
1123
+ var form = $(this);
1124
+ if(!form[0]) return false; // stop here if the form do not exist
1125
+
1126
+ if (typeof(method) === 'string' && method.charAt(0) != '_' && methods[method]) {
1127
+ // make sure init is being called at least once
1128
+ methods.init.apply(form);
1129
+ return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
1130
+ } else if (typeof method === 'object' || !method) {
1131
+ methods.init.apply(form, arguments);
1132
+ return methods.attach.apply(form);
1133
+ } else {
1134
+ $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
1135
+ }
1136
+ };
1137
+ })(jQuery);