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