jquery-datatables-rails 0.1.0 → 1.9.0

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 (31) hide show
  1. data/.gitignore +1 -0
  2. data/lib/jquery/datatables/rails/version.rb +1 -1
  3. data/vendor/assets/images/dataTables/back_disabled.png +0 -0
  4. data/vendor/assets/images/dataTables/back_enabled.png +0 -0
  5. data/vendor/assets/images/dataTables/back_enabled_hover.png +0 -0
  6. data/vendor/assets/images/dataTables/favicon.ico +0 -0
  7. data/vendor/assets/images/dataTables/forward_disabled.png +0 -0
  8. data/vendor/assets/images/dataTables/forward_enabled.png +0 -0
  9. data/vendor/assets/images/dataTables/forward_enabled_hover.png +0 -0
  10. data/vendor/assets/images/dataTables/sort_asc.png +0 -0
  11. data/vendor/assets/images/dataTables/sort_asc_disabled.png +0 -0
  12. data/vendor/assets/images/dataTables/sort_both.png +0 -0
  13. data/vendor/assets/images/dataTables/sort_desc.png +0 -0
  14. data/vendor/assets/images/dataTables/sort_desc_disabled.png +0 -0
  15. data/vendor/assets/javascripts/jquery.dataTables.editable.js +1017 -0
  16. data/vendor/assets/javascripts/jquery.dataTables.fnReloadAjax.js +4 -3
  17. data/vendor/assets/javascripts/jquery.dataTables.js +9882 -5617
  18. data/vendor/assets/javascripts/jquery.dataTables.min.js +141 -139
  19. data/vendor/assets/javascripts/jquery.jeditable.js +507 -0
  20. data/vendor/assets/javascripts/jquery.validate.js +1150 -0
  21. data/vendor/assets/stylesheets/dataTables/demo_page.css +107 -0
  22. data/vendor/assets/stylesheets/dataTables/demo_table.css +59 -22
  23. data/vendor/assets/stylesheets/dataTables/demo_table_jui.css +17 -16
  24. data/vendor/assets/stylesheets/dataTables/jquery.dataTables.css +219 -0
  25. data/vendor/assets/stylesheets/dataTables/jquery.dataTables_themeroller.css +243 -0
  26. metadata +18 -10
  27. data/vendor/assets/images/dataTables/back_disabled.jpg +0 -0
  28. data/vendor/assets/images/dataTables/back_enabled.jpg +0 -0
  29. data/vendor/assets/images/dataTables/forward_disabled.jpg +0 -0
  30. data/vendor/assets/images/dataTables/forward_enabled.jpg +0 -0
  31. data/vendor/assets/javascripts/jquery.dataTables.min.js.gz +0 -0
@@ -0,0 +1,1150 @@
1
+ /*
2
+ * Note: While Microsoft is not the author of this file, Microsoft is
3
+ * offering you a license subject to the terms of the Microsoft Software
4
+ * License Terms for Microsoft ASP.NET Model View Controller 3.
5
+ * Microsoft reserves all other rights. The notices below are provided
6
+ * for informational purposes only and are not the license terms under
7
+ * which Microsoft distributed this file.
8
+ *
9
+ * jQuery validation plug-in 1.7
10
+ *
11
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
12
+ * http://docs.jquery.com/Plugins/Validation
13
+ *
14
+ * Copyright (c) 2006 - 2008 Jörn Zaefferer
15
+ *
16
+ * $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $
17
+ *
18
+ */
19
+
20
+ (function($) {
21
+
22
+ $.extend($.fn, {
23
+ // http://docs.jquery.com/Plugins/Validation/validate
24
+ validate: function( options ) {
25
+
26
+ // if nothing is selected, return nothing; can't chain anyway
27
+ if (!this.length) {
28
+ options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
29
+ return;
30
+ }
31
+
32
+ // check if a validator for this form was already created
33
+ var validator = $.data(this[0], 'validator');
34
+ if ( validator ) {
35
+ return validator;
36
+ }
37
+
38
+ validator = new $.validator( options, this[0] );
39
+ $.data(this[0], 'validator', validator);
40
+
41
+ if ( validator.settings.onsubmit ) {
42
+
43
+ // allow suppresing validation by adding a cancel class to the submit button
44
+ this.find("input, button").filter(".cancel").click(function() {
45
+ validator.cancelSubmit = true;
46
+ });
47
+
48
+ // when a submitHandler is used, capture the submitting button
49
+ if (validator.settings.submitHandler) {
50
+ this.find("input, button").filter(":submit").click(function() {
51
+ validator.submitButton = this;
52
+ });
53
+ }
54
+
55
+ // validate the form on submit
56
+ this.submit( function( event ) {
57
+ if ( validator.settings.debug )
58
+ // prevent form submit to be able to see console output
59
+ event.preventDefault();
60
+
61
+ function handle() {
62
+ if ( validator.settings.submitHandler ) {
63
+ if (validator.submitButton) {
64
+ // insert a hidden input as a replacement for the missing submit button
65
+ var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
66
+ }
67
+ validator.settings.submitHandler.call( validator, validator.currentForm );
68
+ if (validator.submitButton) {
69
+ // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
70
+ hidden.remove();
71
+ }
72
+ return false;
73
+ }
74
+ return true;
75
+ }
76
+
77
+ // prevent submit for invalid forms or custom submit handlers
78
+ if ( validator.cancelSubmit ) {
79
+ validator.cancelSubmit = false;
80
+ return handle();
81
+ }
82
+ if ( validator.form() ) {
83
+ if ( validator.pendingRequest ) {
84
+ validator.formSubmitted = true;
85
+ return false;
86
+ }
87
+ return handle();
88
+ } else {
89
+ validator.focusInvalid();
90
+ return false;
91
+ }
92
+ });
93
+ }
94
+
95
+ return validator;
96
+ },
97
+ // http://docs.jquery.com/Plugins/Validation/valid
98
+ valid: function() {
99
+ if ( $(this[0]).is('form')) {
100
+ return this.validate().form();
101
+ } else {
102
+ var valid = true;
103
+ var validator = $(this[0].form).validate();
104
+ this.each(function() {
105
+ valid &= validator.element(this);
106
+ });
107
+ return valid;
108
+ }
109
+ },
110
+ // attributes: space seperated list of attributes to retrieve and remove
111
+ removeAttrs: function(attributes) {
112
+ var result = {},
113
+ $element = this;
114
+ $.each(attributes.split(/\s/), function(index, value) {
115
+ result[value] = $element.attr(value);
116
+ $element.removeAttr(value);
117
+ });
118
+ return result;
119
+ },
120
+ // http://docs.jquery.com/Plugins/Validation/rules
121
+ rules: function(command, argument) {
122
+ var element = this[0];
123
+
124
+ if (command) {
125
+ var settings = $.data(element.form, 'validator').settings;
126
+ var staticRules = settings.rules;
127
+ var existingRules = $.validator.staticRules(element);
128
+ switch(command) {
129
+ case "add":
130
+ $.extend(existingRules, $.validator.normalizeRule(argument));
131
+ staticRules[element.name] = existingRules;
132
+ if (argument.messages)
133
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
134
+ break;
135
+ case "remove":
136
+ if (!argument) {
137
+ delete staticRules[element.name];
138
+ return existingRules;
139
+ }
140
+ var filtered = {};
141
+ $.each(argument.split(/\s/), function(index, method) {
142
+ filtered[method] = existingRules[method];
143
+ delete existingRules[method];
144
+ });
145
+ return filtered;
146
+ }
147
+ }
148
+
149
+ var data = $.validator.normalizeRules(
150
+ $.extend(
151
+ {},
152
+ $.validator.metadataRules(element),
153
+ $.validator.classRules(element),
154
+ $.validator.attributeRules(element),
155
+ $.validator.staticRules(element)
156
+ ), element);
157
+
158
+ // make sure required is at front
159
+ if (data.required) {
160
+ var param = data.required;
161
+ delete data.required;
162
+ data = $.extend({required: param}, data);
163
+ }
164
+
165
+ return data;
166
+ }
167
+ });
168
+
169
+ // Custom selectors
170
+ $.extend($.expr[":"], {
171
+ // http://docs.jquery.com/Plugins/Validation/blank
172
+ blank: function(a) {return !$.trim("" + a.value);},
173
+ // http://docs.jquery.com/Plugins/Validation/filled
174
+ filled: function(a) {return !!$.trim("" + a.value);},
175
+ // http://docs.jquery.com/Plugins/Validation/unchecked
176
+ unchecked: function(a) {return !a.checked;}
177
+ });
178
+
179
+ // constructor for validator
180
+ $.validator = function( options, form ) {
181
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
182
+ this.currentForm = form;
183
+ this.init();
184
+ };
185
+
186
+ $.validator.format = function(source, params) {
187
+ if ( arguments.length == 1 )
188
+ return function() {
189
+ var args = $.makeArray(arguments);
190
+ args.unshift(source);
191
+ return $.validator.format.apply( this, args );
192
+ };
193
+ if ( arguments.length > 2 && params.constructor != Array ) {
194
+ params = $.makeArray(arguments).slice(1);
195
+ }
196
+ if ( params.constructor != Array ) {
197
+ params = [ params ];
198
+ }
199
+ $.each(params, function(i, n) {
200
+ source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
201
+ });
202
+ return source;
203
+ };
204
+
205
+ $.extend($.validator, {
206
+
207
+ defaults: {
208
+ messages: {},
209
+ groups: {},
210
+ rules: {},
211
+ errorClass: "error",
212
+ validClass: "valid",
213
+ errorElement: "label",
214
+ focusInvalid: true,
215
+ errorContainer: $( [] ),
216
+ errorLabelContainer: $( [] ),
217
+ onsubmit: true,
218
+ ignore: [],
219
+ ignoreTitle: false,
220
+ onfocusin: function(element) {
221
+ this.lastActive = element;
222
+
223
+ // hide error label and remove error class on focus if enabled
224
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
225
+ this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
226
+ this.errorsFor(element).hide();
227
+ }
228
+ },
229
+ onfocusout: function(element) {
230
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
231
+ this.element(element);
232
+ }
233
+ },
234
+ onkeyup: function(element) {
235
+ if ( element.name in this.submitted || element == this.lastElement ) {
236
+ this.element(element);
237
+ }
238
+ },
239
+ onclick: function(element) {
240
+ // click on selects, radiobuttons and checkboxes
241
+ if ( element.name in this.submitted )
242
+ this.element(element);
243
+ // or option elements, check parent select in that case
244
+ else if (element.parentNode.name in this.submitted)
245
+ this.element(element.parentNode);
246
+ },
247
+ highlight: function( element, errorClass, validClass ) {
248
+ $(element).addClass(errorClass).removeClass(validClass);
249
+ },
250
+ unhighlight: function( element, errorClass, validClass ) {
251
+ $(element).removeClass(errorClass).addClass(validClass);
252
+ }
253
+ },
254
+
255
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
256
+ setDefaults: function(settings) {
257
+ $.extend( $.validator.defaults, settings );
258
+ },
259
+
260
+ messages: {
261
+ required: "This field is required.",
262
+ remote: "Please fix this field.",
263
+ email: "Please enter a valid email address.",
264
+ url: "Please enter a valid URL.",
265
+ date: "Please enter a valid date.",
266
+ dateISO: "Please enter a valid date (ISO).",
267
+ number: "Please enter a valid number.",
268
+ digits: "Please enter only digits.",
269
+ creditcard: "Please enter a valid credit card number.",
270
+ equalTo: "Please enter the same value again.",
271
+ accept: "Please enter a value with a valid extension.",
272
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
273
+ minlength: $.validator.format("Please enter at least {0} characters."),
274
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
275
+ range: $.validator.format("Please enter a value between {0} and {1}."),
276
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
277
+ min: $.validator.format("Please enter a value greater than or equal to {0}.")
278
+ },
279
+
280
+ autoCreateRanges: false,
281
+
282
+ prototype: {
283
+
284
+ init: function() {
285
+ this.labelContainer = $(this.settings.errorLabelContainer);
286
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
287
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
288
+ this.submitted = {};
289
+ this.valueCache = {};
290
+ this.pendingRequest = 0;
291
+ this.pending = {};
292
+ this.invalid = {};
293
+ this.reset();
294
+
295
+ var groups = (this.groups = {});
296
+ $.each(this.settings.groups, function(key, value) {
297
+ $.each(value.split(/\s/), function(index, name) {
298
+ groups[name] = key;
299
+ });
300
+ });
301
+ var rules = this.settings.rules;
302
+ $.each(rules, function(key, value) {
303
+ rules[key] = $.validator.normalizeRule(value);
304
+ });
305
+
306
+ function delegate(event) {
307
+ var validator = $.data(this[0].form, "validator"),
308
+ eventType = "on" + event.type.replace(/^validate/, "");
309
+ validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
310
+ }
311
+ $(this.currentForm)
312
+ .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
313
+ .validateDelegate(":radio, :checkbox, select, option", "click", delegate);
314
+
315
+ if (this.settings.invalidHandler)
316
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
317
+ },
318
+
319
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
320
+ form: function() {
321
+ this.checkForm();
322
+ $.extend(this.submitted, this.errorMap);
323
+ this.invalid = $.extend({}, this.errorMap);
324
+ if (!this.valid())
325
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
326
+ this.showErrors();
327
+ return this.valid();
328
+ },
329
+
330
+ checkForm: function() {
331
+ this.prepareForm();
332
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
333
+ this.check( elements[i] );
334
+ }
335
+ return this.valid();
336
+ },
337
+
338
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
339
+ element: function( element ) {
340
+ element = this.clean( element );
341
+ this.lastElement = element;
342
+ this.prepareElement( element );
343
+ this.currentElements = $(element);
344
+ var result = this.check( element );
345
+ if ( result ) {
346
+ delete this.invalid[element.name];
347
+ } else {
348
+ this.invalid[element.name] = true;
349
+ }
350
+ if ( !this.numberOfInvalids() ) {
351
+ // Hide error containers on last error
352
+ this.toHide = this.toHide.add( this.containers );
353
+ }
354
+ this.showErrors();
355
+ return result;
356
+ },
357
+
358
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
359
+ showErrors: function(errors) {
360
+ if(errors) {
361
+ // add items to error list and map
362
+ $.extend( this.errorMap, errors );
363
+ this.errorList = [];
364
+ for ( var name in errors ) {
365
+ this.errorList.push({
366
+ message: errors[name],
367
+ element: this.findByName(name)[0]
368
+ });
369
+ }
370
+ // remove items from success list
371
+ this.successList = $.grep( this.successList, function(element) {
372
+ return !(element.name in errors);
373
+ });
374
+ }
375
+ this.settings.showErrors
376
+ ? this.settings.showErrors.call( this, this.errorMap, this.errorList )
377
+ : this.defaultShowErrors();
378
+ },
379
+
380
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
381
+ resetForm: function() {
382
+ if ( $.fn.resetForm )
383
+ $( this.currentForm ).resetForm();
384
+ this.submitted = {};
385
+ this.prepareForm();
386
+ this.hideErrors();
387
+ this.elements().removeClass( this.settings.errorClass );
388
+ },
389
+
390
+ numberOfInvalids: function() {
391
+ return this.objectLength(this.invalid);
392
+ },
393
+
394
+ objectLength: function( obj ) {
395
+ var count = 0;
396
+ for ( var i in obj )
397
+ count++;
398
+ return count;
399
+ },
400
+
401
+ hideErrors: function() {
402
+ this.addWrapper( this.toHide ).hide();
403
+ },
404
+
405
+ valid: function() {
406
+ return this.size() == 0;
407
+ },
408
+
409
+ size: function() {
410
+ return this.errorList.length;
411
+ },
412
+
413
+ focusInvalid: function() {
414
+ if( this.settings.focusInvalid ) {
415
+ try {
416
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
417
+ .filter(":visible")
418
+ .focus()
419
+ // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
420
+ .trigger("focusin");
421
+ } catch(e) {
422
+ // ignore IE throwing errors when focusing hidden elements
423
+ }
424
+ }
425
+ },
426
+
427
+ findLastActive: function() {
428
+ var lastActive = this.lastActive;
429
+ return lastActive && $.grep(this.errorList, function(n) {
430
+ return n.element.name == lastActive.name;
431
+ }).length == 1 && lastActive;
432
+ },
433
+
434
+ elements: function() {
435
+ var validator = this,
436
+ rulesCache = {};
437
+
438
+ // select all valid inputs inside the form (no submit or reset buttons)
439
+ // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
440
+ return $([]).add(this.currentForm.elements)
441
+ .filter(":input")
442
+ .not(":submit, :reset, :image, [disabled]")
443
+ .not( this.settings.ignore )
444
+ .filter(function() {
445
+ !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);
446
+
447
+ // select only the first element for each name, and only those with rules specified
448
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
449
+ return false;
450
+
451
+ rulesCache[this.name] = true;
452
+ return true;
453
+ });
454
+ },
455
+
456
+ clean: function( selector ) {
457
+ return $( selector )[0];
458
+ },
459
+
460
+ errors: function() {
461
+ return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
462
+ },
463
+
464
+ reset: function() {
465
+ this.successList = [];
466
+ this.errorList = [];
467
+ this.errorMap = {};
468
+ this.toShow = $([]);
469
+ this.toHide = $([]);
470
+ this.currentElements = $([]);
471
+ },
472
+
473
+ prepareForm: function() {
474
+ this.reset();
475
+ this.toHide = this.errors().add( this.containers );
476
+ },
477
+
478
+ prepareElement: function( element ) {
479
+ this.reset();
480
+ this.toHide = this.errorsFor(element);
481
+ },
482
+
483
+ check: function( element ) {
484
+ element = this.clean( element );
485
+
486
+ // if radio/checkbox, validate first element in group instead
487
+ if (this.checkable(element)) {
488
+ element = this.findByName( element.name )[0];
489
+ }
490
+
491
+ var rules = $(element).rules();
492
+ var dependencyMismatch = false;
493
+ for( method in rules ) {
494
+ var rule = { method: method, parameters: rules[method] };
495
+ try {
496
+ var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );
497
+
498
+ // if a method indicates that the field is optional and therefore valid,
499
+ // don't mark it as valid when there are no other rules
500
+ if ( result == "dependency-mismatch" ) {
501
+ dependencyMismatch = true;
502
+ continue;
503
+ }
504
+ dependencyMismatch = false;
505
+
506
+ if ( result == "pending" ) {
507
+ this.toHide = this.toHide.not( this.errorsFor(element) );
508
+ return;
509
+ }
510
+
511
+ if( !result ) {
512
+ this.formatAndAdd( element, rule );
513
+ return false;
514
+ }
515
+ } catch(e) {
516
+ this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
517
+ + ", check the '" + rule.method + "' method", e);
518
+ throw e;
519
+ }
520
+ }
521
+ if (dependencyMismatch)
522
+ return;
523
+ if ( this.objectLength(rules) )
524
+ this.successList.push(element);
525
+ return true;
526
+ },
527
+
528
+ // return the custom message for the given element and validation method
529
+ // specified in the element's "messages" metadata
530
+ customMetaMessage: function(element, method) {
531
+ if (!$.metadata)
532
+ return;
533
+
534
+ var meta = this.settings.meta
535
+ ? $(element).metadata()[this.settings.meta]
536
+ : $(element).metadata();
537
+
538
+ return meta && meta.messages && meta.messages[method];
539
+ },
540
+
541
+ // return the custom message for the given element name and validation method
542
+ customMessage: function( name, method ) {
543
+ var m = this.settings.messages[name];
544
+ return m && (m.constructor == String
545
+ ? m
546
+ : m[method]);
547
+ },
548
+
549
+ // return the first defined argument, allowing empty strings
550
+ findDefined: function() {
551
+ for(var i = 0; i < arguments.length; i++) {
552
+ if (arguments[i] !== undefined)
553
+ return arguments[i];
554
+ }
555
+ return undefined;
556
+ },
557
+
558
+ defaultMessage: function( element, method) {
559
+ return this.findDefined(
560
+ this.customMessage( element.name, method ),
561
+ this.customMetaMessage( element, method ),
562
+ // title is never undefined, so handle empty string as undefined
563
+ !this.settings.ignoreTitle && element.title || undefined,
564
+ $.validator.messages[method],
565
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
566
+ );
567
+ },
568
+
569
+ formatAndAdd: function( element, rule ) {
570
+ var message = this.defaultMessage( element, rule.method ),
571
+ theregex = /\$?\{(\d+)\}/g;
572
+ if ( typeof message == "function" ) {
573
+ message = message.call(this, rule.parameters, element);
574
+ } else if (theregex.test(message)) {
575
+ message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
576
+ }
577
+ this.errorList.push({
578
+ message: message,
579
+ element: element
580
+ });
581
+
582
+ this.errorMap[element.name] = message;
583
+ this.submitted[element.name] = message;
584
+ },
585
+
586
+ addWrapper: function(toToggle) {
587
+ if ( this.settings.wrapper )
588
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
589
+ return toToggle;
590
+ },
591
+
592
+ defaultShowErrors: function() {
593
+ for ( var i = 0; this.errorList[i]; i++ ) {
594
+ var error = this.errorList[i];
595
+ this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
596
+ this.showLabel( error.element, error.message );
597
+ }
598
+ if( this.errorList.length ) {
599
+ this.toShow = this.toShow.add( this.containers );
600
+ }
601
+ if (this.settings.success) {
602
+ for ( var i = 0; this.successList[i]; i++ ) {
603
+ this.showLabel( this.successList[i] );
604
+ }
605
+ }
606
+ if (this.settings.unhighlight) {
607
+ for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
608
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
609
+ }
610
+ }
611
+ this.toHide = this.toHide.not( this.toShow );
612
+ this.hideErrors();
613
+ this.addWrapper( this.toShow ).show();
614
+ },
615
+
616
+ validElements: function() {
617
+ return this.currentElements.not(this.invalidElements());
618
+ },
619
+
620
+ invalidElements: function() {
621
+ return $(this.errorList).map(function() {
622
+ return this.element;
623
+ });
624
+ },
625
+
626
+ showLabel: function(element, message) {
627
+ var label = this.errorsFor( element );
628
+ if ( label.length ) {
629
+ // refresh error/success class
630
+ label.removeClass().addClass( this.settings.errorClass );
631
+
632
+ // check if we have a generated label, replace the message then
633
+ label.attr("generated") && label.html(message);
634
+ } else {
635
+ // create label
636
+ label = $("<" + this.settings.errorElement + "/>")
637
+ .attr({"for": this.idOrName(element), generated: true})
638
+ .addClass(this.settings.errorClass)
639
+ .html(message || "");
640
+ if ( this.settings.wrapper ) {
641
+ // make sure the element is visible, even in IE
642
+ // actually showing the wrapped element is handled elsewhere
643
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
644
+ }
645
+ if ( !this.labelContainer.append(label).length )
646
+ this.settings.errorPlacement
647
+ ? this.settings.errorPlacement(label, $(element) )
648
+ : label.insertAfter(element);
649
+ }
650
+ if ( !message && this.settings.success ) {
651
+ label.text("");
652
+ typeof this.settings.success == "string"
653
+ ? label.addClass( this.settings.success )
654
+ : this.settings.success( label );
655
+ }
656
+ this.toShow = this.toShow.add(label);
657
+ },
658
+
659
+ errorsFor: function(element) {
660
+ var name = this.idOrName(element);
661
+ return this.errors().filter(function() {
662
+ return $(this).attr('for') == name;
663
+ });
664
+ },
665
+
666
+ idOrName: function(element) {
667
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
668
+ },
669
+
670
+ checkable: function( element ) {
671
+ return /radio|checkbox/i.test(element.type);
672
+ },
673
+
674
+ findByName: function( name ) {
675
+ // select by name and filter by form for performance over form.find("[name=...]")
676
+ var form = this.currentForm;
677
+ return $(document.getElementsByName(name)).map(function(index, element) {
678
+ return element.form == form && element.name == name && element || null;
679
+ });
680
+ },
681
+
682
+ getLength: function(value, element) {
683
+ switch( element.nodeName.toLowerCase() ) {
684
+ case 'select':
685
+ return $("option:selected", element).length;
686
+ case 'input':
687
+ if( this.checkable( element) )
688
+ return this.findByName(element.name).filter(':checked').length;
689
+ }
690
+ return value.length;
691
+ },
692
+
693
+ depend: function(param, element) {
694
+ return this.dependTypes[typeof param]
695
+ ? this.dependTypes[typeof param](param, element)
696
+ : true;
697
+ },
698
+
699
+ dependTypes: {
700
+ "boolean": function(param, element) {
701
+ return param;
702
+ },
703
+ "string": function(param, element) {
704
+ return !!$(param, element.form).length;
705
+ },
706
+ "function": function(param, element) {
707
+ return param(element);
708
+ }
709
+ },
710
+
711
+ optional: function(element) {
712
+ return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
713
+ },
714
+
715
+ startRequest: function(element) {
716
+ if (!this.pending[element.name]) {
717
+ this.pendingRequest++;
718
+ this.pending[element.name] = true;
719
+ }
720
+ },
721
+
722
+ stopRequest: function(element, valid) {
723
+ this.pendingRequest--;
724
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
725
+ if (this.pendingRequest < 0)
726
+ this.pendingRequest = 0;
727
+ delete this.pending[element.name];
728
+ if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
729
+ $(this.currentForm).submit();
730
+ this.formSubmitted = false;
731
+ } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
732
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
733
+ this.formSubmitted = false;
734
+ }
735
+ },
736
+
737
+ previousValue: function(element) {
738
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
739
+ old: null,
740
+ valid: true,
741
+ message: this.defaultMessage( element, "remote" )
742
+ });
743
+ }
744
+
745
+ },
746
+
747
+ classRuleSettings: {
748
+ required: {required: true},
749
+ email: {email: true},
750
+ url: {url: true},
751
+ date: {date: true},
752
+ dateISO: {dateISO: true},
753
+ dateDE: {dateDE: true},
754
+ number: {number: true},
755
+ numberDE: {numberDE: true},
756
+ digits: {digits: true},
757
+ creditcard: {creditcard: true}
758
+ },
759
+
760
+ addClassRules: function(className, rules) {
761
+ className.constructor == String ?
762
+ this.classRuleSettings[className] = rules :
763
+ $.extend(this.classRuleSettings, className);
764
+ },
765
+
766
+ classRules: function(element) {
767
+ var rules = {};
768
+ var classes = $(element).attr('class');
769
+ classes && $.each(classes.split(' '), function() {
770
+ if (this in $.validator.classRuleSettings) {
771
+ $.extend(rules, $.validator.classRuleSettings[this]);
772
+ }
773
+ });
774
+ return rules;
775
+ },
776
+
777
+ attributeRules: function(element) {
778
+ var rules = {};
779
+ var $element = $(element);
780
+
781
+ for (method in $.validator.methods) {
782
+ var value = $element.attr(method);
783
+ if (value) {
784
+ rules[method] = value;
785
+ }
786
+ }
787
+
788
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
789
+ if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
790
+ delete rules.maxlength;
791
+ }
792
+
793
+ return rules;
794
+ },
795
+
796
+ metadataRules: function(element) {
797
+ if (!$.metadata) return {};
798
+
799
+ var meta = $.data(element.form, 'validator').settings.meta;
800
+ return meta ?
801
+ $(element).metadata()[meta] :
802
+ $(element).metadata();
803
+ },
804
+
805
+ staticRules: function(element) {
806
+ var rules = {};
807
+ var validator = $.data(element.form, 'validator');
808
+ if (validator.settings.rules) {
809
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
810
+ }
811
+ return rules;
812
+ },
813
+
814
+ normalizeRules: function(rules, element) {
815
+ // handle dependency check
816
+ $.each(rules, function(prop, val) {
817
+ // ignore rule when param is explicitly false, eg. required:false
818
+ if (val === false) {
819
+ delete rules[prop];
820
+ return;
821
+ }
822
+ if (val.param || val.depends) {
823
+ var keepRule = true;
824
+ switch (typeof val.depends) {
825
+ case "string":
826
+ keepRule = !!$(val.depends, element.form).length;
827
+ break;
828
+ case "function":
829
+ keepRule = val.depends.call(element, element);
830
+ break;
831
+ }
832
+ if (keepRule) {
833
+ rules[prop] = val.param !== undefined ? val.param : true;
834
+ } else {
835
+ delete rules[prop];
836
+ }
837
+ }
838
+ });
839
+
840
+ // evaluate parameters
841
+ $.each(rules, function(rule, parameter) {
842
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
843
+ });
844
+
845
+ // clean number parameters
846
+ $.each(['minlength', 'maxlength', 'min', 'max'], function() {
847
+ if (rules[this]) {
848
+ rules[this] = Number(rules[this]);
849
+ }
850
+ });
851
+ $.each(['rangelength', 'range'], function() {
852
+ if (rules[this]) {
853
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
854
+ }
855
+ });
856
+
857
+ if ($.validator.autoCreateRanges) {
858
+ // auto-create ranges
859
+ if (rules.min && rules.max) {
860
+ rules.range = [rules.min, rules.max];
861
+ delete rules.min;
862
+ delete rules.max;
863
+ }
864
+ if (rules.minlength && rules.maxlength) {
865
+ rules.rangelength = [rules.minlength, rules.maxlength];
866
+ delete rules.minlength;
867
+ delete rules.maxlength;
868
+ }
869
+ }
870
+
871
+ // To support custom messages in metadata ignore rule methods titled "messages"
872
+ if (rules.messages) {
873
+ delete rules.messages;
874
+ }
875
+
876
+ return rules;
877
+ },
878
+
879
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
880
+ normalizeRule: function(data) {
881
+ if( typeof data == "string" ) {
882
+ var transformed = {};
883
+ $.each(data.split(/\s/), function() {
884
+ transformed[this] = true;
885
+ });
886
+ data = transformed;
887
+ }
888
+ return data;
889
+ },
890
+
891
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
892
+ addMethod: function(name, method, message) {
893
+ $.validator.methods[name] = method;
894
+ $.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
895
+ if (method.length < 3) {
896
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
897
+ }
898
+ },
899
+
900
+ methods: {
901
+
902
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
903
+ required: function(value, element, param) {
904
+ // check if dependency is met
905
+ if ( !this.depend(param, element) )
906
+ return "dependency-mismatch";
907
+ switch( element.nodeName.toLowerCase() ) {
908
+ case 'select':
909
+ // could be an array for select-multiple or a string, both are fine this way
910
+ var val = $(element).val();
911
+ return val && val.length > 0;
912
+ case 'input':
913
+ if ( this.checkable(element) )
914
+ return this.getLength(value, element) > 0;
915
+ default:
916
+ return $.trim(value).length > 0;
917
+ }
918
+ },
919
+
920
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
921
+ remote: function(value, element, param) {
922
+ if ( this.optional(element) )
923
+ return "dependency-mismatch";
924
+
925
+ var previous = this.previousValue(element);
926
+ if (!this.settings.messages[element.name] )
927
+ this.settings.messages[element.name] = {};
928
+ previous.originalMessage = this.settings.messages[element.name].remote;
929
+ this.settings.messages[element.name].remote = previous.message;
930
+
931
+ param = typeof param == "string" && {url:param} || param;
932
+
933
+ if ( previous.old !== value ) {
934
+ previous.old = value;
935
+ var validator = this;
936
+ this.startRequest(element);
937
+ var data = {};
938
+ data[element.name] = value;
939
+ $.ajax($.extend(true, {
940
+ url: param,
941
+ mode: "abort",
942
+ port: "validate" + element.name,
943
+ dataType: "json",
944
+ data: data,
945
+ success: function(response) {
946
+ validator.settings.messages[element.name].remote = previous.originalMessage;
947
+ var valid = response === true;
948
+ if ( valid ) {
949
+ var submitted = validator.formSubmitted;
950
+ validator.prepareElement(element);
951
+ validator.formSubmitted = submitted;
952
+ validator.successList.push(element);
953
+ validator.showErrors();
954
+ } else {
955
+ var errors = {};
956
+ var message = (previous.message = response || validator.defaultMessage( element, "remote" ));
957
+ errors[element.name] = $.isFunction(message) ? message(value) : message;
958
+ validator.showErrors(errors);
959
+ }
960
+ previous.valid = valid;
961
+ validator.stopRequest(element, valid);
962
+ }
963
+ }, param));
964
+ return "pending";
965
+ } else if( this.pending[element.name] ) {
966
+ return "pending";
967
+ }
968
+ return previous.valid;
969
+ },
970
+
971
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
972
+ minlength: function(value, element, param) {
973
+ return this.optional(element) || this.getLength($.trim(value), element) >= param;
974
+ },
975
+
976
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
977
+ maxlength: function(value, element, param) {
978
+ return this.optional(element) || this.getLength($.trim(value), element) <= param;
979
+ },
980
+
981
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
982
+ rangelength: function(value, element, param) {
983
+ var length = this.getLength($.trim(value), element);
984
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
985
+ },
986
+
987
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
988
+ min: function( value, element, param ) {
989
+ return this.optional(element) || value >= param;
990
+ },
991
+
992
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
993
+ max: function( value, element, param ) {
994
+ return this.optional(element) || value <= param;
995
+ },
996
+
997
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
998
+ range: function( value, element, param ) {
999
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
1000
+ },
1001
+
1002
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
1003
+ email: function(value, element) {
1004
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1005
+ return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
1006
+ },
1007
+
1008
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
1009
+ url: function(value, element) {
1010
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1011
+ return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1012
+ },
1013
+
1014
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
1015
+ date: function(value, element) {
1016
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
1017
+ },
1018
+
1019
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1020
+ dateISO: function(value, element) {
1021
+ return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
1022
+ },
1023
+
1024
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
1025
+ number: function(value, element) {
1026
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
1027
+ },
1028
+
1029
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1030
+ digits: function(value, element) {
1031
+ return this.optional(element) || /^\d+$/.test(value);
1032
+ },
1033
+
1034
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1035
+ // based on http://en.wikipedia.org/wiki/Luhn
1036
+ creditcard: function(value, element) {
1037
+ if ( this.optional(element) )
1038
+ return "dependency-mismatch";
1039
+ // accept only digits and dashes
1040
+ if (/[^0-9-]+/.test(value))
1041
+ return false;
1042
+ var nCheck = 0,
1043
+ nDigit = 0,
1044
+ bEven = false;
1045
+
1046
+ value = value.replace(/\D/g, "");
1047
+
1048
+ for (var n = value.length - 1; n >= 0; n--) {
1049
+ var cDigit = value.charAt(n);
1050
+ var nDigit = parseInt(cDigit, 10);
1051
+ if (bEven) {
1052
+ if ((nDigit *= 2) > 9)
1053
+ nDigit -= 9;
1054
+ }
1055
+ nCheck += nDigit;
1056
+ bEven = !bEven;
1057
+ }
1058
+
1059
+ return (nCheck % 10) == 0;
1060
+ },
1061
+
1062
+ // http://docs.jquery.com/Plugins/Validation/Methods/accept
1063
+ accept: function(value, element, param) {
1064
+ param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
1065
+ return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
1066
+ },
1067
+
1068
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1069
+ equalTo: function(value, element, param) {
1070
+ // bind to the blur event of the target in order to revalidate whenever the target field is updated
1071
+ // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1072
+ var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1073
+ $(element).valid();
1074
+ });
1075
+ return value == target.val();
1076
+ }
1077
+
1078
+ }
1079
+
1080
+ });
1081
+
1082
+ // deprecated, use $.validator.format instead
1083
+ $.format = $.validator.format;
1084
+
1085
+ })(jQuery);
1086
+
1087
+ // ajax mode: abort
1088
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1089
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1090
+ ;(function($) {
1091
+ var ajax = $.ajax;
1092
+ var pendingRequests = {};
1093
+ $.ajax = function(settings) {
1094
+ // create settings for compatibility with ajaxSetup
1095
+ settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings));
1096
+ var port = settings.port;
1097
+ if (settings.mode == "abort") {
1098
+ if ( pendingRequests[port] ) {
1099
+ pendingRequests[port].abort();
1100
+ }
1101
+ return (pendingRequests[port] = ajax.apply(this, arguments));
1102
+ }
1103
+ return ajax.apply(this, arguments);
1104
+ };
1105
+ })(jQuery);
1106
+
1107
+ // provides cross-browser focusin and focusout events
1108
+ // IE has native support, in other browsers, use event caputuring (neither bubbles)
1109
+
1110
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1111
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1112
+ ;(function($) {
1113
+ // only implement if not provided by jQuery core (since 1.4)
1114
+ // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
1115
+ if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
1116
+ $.each({
1117
+ focus: 'focusin',
1118
+ blur: 'focusout'
1119
+ }, function( original, fix ){
1120
+ $.event.special[fix] = {
1121
+ setup:function() {
1122
+ this.addEventListener( original, handler, true );
1123
+ },
1124
+ teardown:function() {
1125
+ this.removeEventListener( original, handler, true );
1126
+ },
1127
+ handler: function(e) {
1128
+ arguments[0] = $.event.fix(e);
1129
+ arguments[0].type = fix;
1130
+ return $.event.handle.apply(this, arguments);
1131
+ }
1132
+ };
1133
+ function handler(e) {
1134
+ e = $.event.fix(e);
1135
+ e.type = fix;
1136
+ return $.event.handle.call(this, e);
1137
+ }
1138
+ });
1139
+ };
1140
+ $.extend($.fn, {
1141
+ validateDelegate: function(delegate, type, handler) {
1142
+ return this.bind(type, function(event) {
1143
+ var target = $(event.target);
1144
+ if (target.is(delegate)) {
1145
+ return handler.apply(target, arguments);
1146
+ }
1147
+ });
1148
+ }
1149
+ });
1150
+ })(jQuery);