Skip to content

Commit 3013392

Browse files
Eric Naesethhdragomir
authored andcommitted
Fixed jquery-validation#177 - Fix validation of a single radio or checkbox 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>
1 parent 8387fdf commit 3013392

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Fixed swedish and norwedian translations, min/max messages got switched. Fixes #181
1313
* Fixed #184 - resetForm: should unset lastElement
1414
* Fixed #71 - improve existing time method and add time12h method for 12h am/pm time format
15+
* Fixed #177 - Fix validation of a single radio or checkbox input
1516

1617
1.8.1
1718
---

jquery.validate.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ $.extend($.validator, {
349349

350350
// http://docs.jquery.com/Plugins/Validation/Validator/element
351351
element: function( element ) {
352-
element = this.clean( element );
352+
element = this.validationTargetFor( this.clean( element ) );
353353
this.lastElement = element;
354354
this.prepareElement( element );
355355
this.currentElements = $(element);
@@ -493,12 +493,7 @@ $.extend($.validator, {
493493
},
494494

495495
check: function( element ) {
496-
element = this.clean( element );
497-
498-
// if radio/checkbox, validate first element in group instead
499-
if (this.checkable(element)) {
500-
element = this.findByName( element.name ).not(this.settings.ignore)[0];
501-
}
496+
element = this.validationTargetFor( this.clean( element ) );
502497

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

677+
validationTargetFor: function(element) {
678+
// if radio/checkbox, validate first element in group instead
679+
if (this.checkable(element)) {
680+
element = this.findByName( element.name ).not(this.settings.ignore)[0];
681+
}
682+
return element;
683+
},
684+
682685
checkable: function( element ) {
683686
return /radio|checkbox/i.test(element.type);
684687
},

test/test.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,28 @@ test("validate multiple checkbox on click", function() {
11131113
errors(1);
11141114
});
11151115

1116+
test("correct checkbox receives the error", function(){
1117+
function trigger(element) {
1118+
element.click();
1119+
// triggered click event screws up checked-state in 1.4
1120+
element.valid();
1121+
}
1122+
var e1 = $("#check1").attr("checked", false);
1123+
var e2 = $("#check1b").attr("checked", false);
1124+
var v = $("#form").find('[type=checkbox]').attr('checked', false).end().validate({
1125+
rules:{
1126+
check: {
1127+
required: true,
1128+
minlength: 2
1129+
}
1130+
}
1131+
});
1132+
equals(false, v.form());
1133+
trigger(e1);
1134+
equals(false, v.form());
1135+
ok(v.errorList[0].element.id === v.currentElements[0].id, "the proper checkbox has the error AND is present in currentElements");
1136+
});
1137+
11161138
test("validate radio on click", function() {
11171139
function errors(expected, message) {
11181140
equals(expected, v.size(), message );

0 commit comments

Comments
 (0)