Skip to content

Commit

Permalink
Fixed jquery-validation#177 - Fix validation of a single radio or che…
Browse files Browse the repository at this point in the history
…ckbox input

The validator element() method delegates to check(). When check() is
passed a radio or checkbox input element (call it 'A'), it instead
checks the first element with the same name in the form (call it 'B').

If element B is judged invalid, a bug occurs. Element A will have been
added to the currentElements array, but element B is what is added to
the errorList. So, when showErrors is called, element A will be in
validElements(), and will be unhighlighted.

This is fixed by having element() also change its target to be the
first element of the same name when passed a checkbox or radio input.

Signed-off-by: Eric Naeseth <eric@thumbtack.com>
  • Loading branch information
Eric Naeseth authored and jzaefferer committed Sep 13, 2011
1 parent 3f187a5 commit f2321e1
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -12,6 +12,7 @@
* Fixed swedish and norwedian translations, min/max messages got switched. Fixes #181
* Fixed #184 - resetForm: should unset lastElement
* Fixed #71 - improve existing time method and add time12h method for 12h am/pm time format
* Fixed #177 - Fix validation of a single radio or checkbox input

1.8.1
---
Expand Down
17 changes: 10 additions & 7 deletions jquery.validate.js
Expand Up @@ -349,7 +349,7 @@ $.extend($.validator, {

// http://docs.jquery.com/Plugins/Validation/Validator/element
element: function( element ) {
element = this.clean( element );
element = this.validationTargetFor( this.clean( element ) );
this.lastElement = element;
this.prepareElement( element );
this.currentElements = $(element);
Expand Down Expand Up @@ -493,12 +493,7 @@ $.extend($.validator, {
},

check: function( element ) {
element = this.clean( element );

// if radio/checkbox, validate first element in group instead
if (this.checkable(element)) {
element = this.findByName( element.name ).not(this.settings.ignore)[0];
}
element = this.validationTargetFor( this.clean( element ) );

var rules = $(element).rules();
var dependencyMismatch = false;
Expand Down Expand Up @@ -679,6 +674,14 @@ $.extend($.validator, {
return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
},

validationTargetFor: function(element) {
// if radio/checkbox, validate first element in group instead
if (this.checkable(element)) {
element = this.findByName( element.name ).not(this.settings.ignore)[0];
}
return element;
},

checkable: function( element ) {
return /radio|checkbox/i.test(element.type);
},
Expand Down
22 changes: 22 additions & 0 deletions test/test.js
Expand Up @@ -1113,6 +1113,28 @@ test("validate multiple checkbox on click", function() {
errors(1);
});

test("correct checkbox receives the error", function(){
function trigger(element) {
element.click();
// triggered click event screws up checked-state in 1.4
element.valid();
}
var e1 = $("#check1").attr("checked", false);
var e2 = $("#check1b").attr("checked", false);
var v = $("#form").find('[type=checkbox]').attr('checked', false).end().validate({
rules:{
check: {
required: true,
minlength: 2
}
}
});
equals(false, v.form());
trigger(e1);
equals(false, v.form());
ok(v.errorList[0].element.id === v.currentElements[0].id, "the proper checkbox has the error AND is present in currentElements");
});

test("validate radio on click", function() {
function errors(expected, message) {
equals(expected, v.size(), message );
Expand Down

0 comments on commit f2321e1

Please sign in to comment.