jquery-datatables-rails 0.1.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
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);