Skip to content

Commit

Permalink
Initial ARIA-Required implementation
Browse files Browse the repository at this point in the history
Add aria-required tags to any of the data, static or class required elements.
Dynamic validation for rules added through the form.validate rules object do not get picked up till first run.
  • Loading branch information
nschonni authored and jzaefferer committed Oct 7, 2013
1 parent 4f8a631 commit bf3cfb2
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 16 deletions.
10 changes: 9 additions & 1 deletion src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ $.extend($.fn, {
switch(command) {
case "add":
$.extend(existingRules, $.validator.normalizeRule(argument));
// remove messages from rules, but allow them to be set separetely
// remove messages from rules, but allow them to be set separately
delete existingRules.messages;
staticRules[element.name] = existingRules;
if ( argument.messages ) {
Expand All @@ -144,6 +144,9 @@ $.extend($.fn, {
$.each(argument.split(/\s/), function( index, method ) {
filtered[method] = existingRules[method];
delete existingRules[method];
if ( method === "required" ) {
$(element).removeAttr("aria-required");
}
});
return filtered;
}
Expand All @@ -163,6 +166,7 @@ $.extend($.fn, {
var param = data.required;
delete data.required;
data = $.extend({required: param}, data);
$(element).attr("aria-required", "true");
}

return data;
Expand Down Expand Up @@ -345,6 +349,10 @@ $.extend($.validator, {
if ( this.settings.invalidHandler ) {
$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
}

// Add aria-required to any Static/Data/Class required fields before first validation
// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
$(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true");
},

// http://jqueryvalidation.org/Validator.form/
Expand Down
62 changes: 48 additions & 14 deletions test/aria.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,76 @@
module("aria");

test("Invalid field adds aria-invalid=true", function() {
var ariafirstname = $('#ariafirstname');
var ariaInvalidFirstName = $('#ariaInvalidFirstName');
var form = $('#ariaInvalid');
form.validate({
rules: {
ariafirstname: 'required'
ariaInvalidFirstName: 'required'
}
});
ariafirstname.val('');
ariafirstname.valid();
equal(ariafirstname.attr('aria-invalid'), "true");
ariaInvalidFirstName.val('');
ariaInvalidFirstName.valid();
equal(ariaInvalidFirstName.attr('aria-invalid'), "true");
});

test("Valid field adds aria-invalid=false", function() {
var ariafirstname = $('#ariafirstname');
var ariaInvalidFirstName = $('#ariaInvalidFirstName');
var form = $("#ariaInvalid");
form.validate({
rules: {
ariafirstname: "required"
ariaInvalidFirstName: "required"
}
});
ariafirstname.val('not empty');
ariafirstname.valid();
equal(ariafirstname.attr("aria-invalid"), "false");
ariaInvalidFirstName.val('not empty');
ariaInvalidFirstName.valid();
equal(ariaInvalidFirstName.attr("aria-invalid"), "false");
equal($("#ariaInvalid [aria-invalid=false]").length, 1);
});

test("resetForm(): removes all aria-invalid attributes", function() {
var ariafirstname = $('#ariafirstname');
var ariaInvalidFirstName = $('#ariaInvalidFirstName');
var form = $("#ariaInvalid");
var validator = form.validate({
rules: {
ariafirstname: "required"
ariaInvalidFirstName: "required"
}
});
ariafirstname.val('not empty');
ariafirstname.valid();
ariaInvalidFirstName.val('not empty');
ariaInvalidFirstName.valid();
validator.resetForm();
equal($("#ariaInvalid [aria-invalid]").length, 0, "resetForm() should remove any aria-invalid attributes");
});

test("Static required field adds aria-required", function() {
var ariaRequiredStatic = $('#ariaRequiredStatic');
var form = $("#ariaRequired");
form.validate();
equal(ariaRequiredStatic.attr("aria-required"), "true");
});

test("Data required field adds aria-required", function() {
var ariaRequiredData = $('#ariaRequiredData');
var form = $("#ariaRequired");
form.validate();
equal(ariaRequiredData.attr("aria-required"), "true");
});

test("Class required field adds aria-required", function() {
var ariaRequiredClass = $('#ariaRequiredClass');
var form = $("#ariaRequired");
form.validate();
equal(ariaRequiredClass.attr("aria-required"), "true");
});

test("Dynamically required field adds aria-required after valid()", function() {
var ariaRequiredDynamic = $('#ariaRequiredDynamic');
var form = $("#ariaRequired");
form.resetForm();
form.validate({
rules: {
ariaRequiredDynamic: "required"
}
});
ariaRequiredDynamic.valid();
equal(ariaRequiredDynamic.attr("aria-required"), "true");
});
9 changes: 8 additions & 1 deletion test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,14 @@ <h3></h3>
</form>

<form id="ariaInvalid">
<input type="text" name="ariafirstname" id="ariafirstname" />
<input type="text" name="ariaInvalidFirstName" id="ariaInvalidFirstName" />
</form>

<form id="ariaRequired">
<input type="text" name="ariaRequiredDynamic" id="ariaRequiredDynamic" />
<input type="text" name="ariaRequiredStatic" id="ariaRequiredStatic" required="" />
<input type="text" name="ariaRequiredData" id="ariaRequiredData" data-rule-required="true" />
<input type="text" name="ariaRequiredClass" id="ariaRequiredClass" class="required" />
</form>
</div>

Expand Down

0 comments on commit bf3cfb2

Please sign in to comment.