gunnertechnology 0.0.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.
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);