I am adding accessibility to my web application. I have two required fields in a form that I wish to associate with two separate error messages, defined as spans. I am using aria-invalid to flag the fields when they are not present, and aria-describedby to identify the error message elements. The screen reader software (JAWS) is not reading the text of the associated error message elements when the input field gets focus.
<form id="kiosksform" action="loc/save" method="post">
<h1 class="title mt-2" id="registration-title">Create Kiosk</h1>
<div class="bg-3 text-left">
<table id="table" class="text-left table table-hover ml-0 table_edit mt-5">
<thead>
<tr>
<th class="text-center" scope="col"><u data-toggle="tooltip" title="Item"</u></th>
<th class="text-center" scope="col"><u data-toggle="tooltip" title="Enter the value">Value</u></th>
</tr>
</thead>
<tbody>
<tr>
<td class="kiosk-table-data">KIOSK Code</td>
<td class="kiosk_table_data">
<input type="text" name="kiosk_code" id="kiosk_code_id" value="" data-toggle="tooltip"
title="Enter kiosk code" class="pt1 p1-2" required
aria-describedby="kiosk_code_validation" aria-invalid="false"
onkeyup="validateFields()">
</td>
</tr>
<tr>
<td class="kiosk-table-data">KIOSK Name</td>
<td class="kiosk_table_data">
<input type="text" name="kiosk_name" id="kiosk_name_id" value="" data-toggle="tooltip"
title="Enter kiosk name" class="pt1 p1-2" required
aria-describedby="kiosk_name_validation" aria-invalid="false"
onkeyup="validateFields()">
</td>
</tr>
</tbody>
</table>
<div class="button-holder mt-3">
<button type="submit" onclick="return validateForm()" id="regButton"
class="btn btn-primary btn-width" data-toggle="tooltip"
title="Click to save your changes">Save</button>
<a href="/loc" id="regButtonCancel" class="btn btn-width text-decoration-none"
data-toggle="tooltip" title="Click to cancel transaction">Cancel</a>
</div>
<div class="container mt-3">
<span id="kiosk_code_validation" class="text-danger text-center m1"> </span>
<span id="kiosk_name_validation" class="text-danger text-center m1"> </span>
</div>
</div>
</form>
<script>
function validateFields() {
let formValidated = false
let kioskCodeValidated = false
let kioskNameValidated = false
let kioskCode = document.getElementById('kiosk_code_id');
let kioskName = document.getElementById('kiosk_name_id');
let kioskCodeValidation = document.getElementById('kiosk_code_validation');
let kioskNameValidation = document.getElementById('kiosk_name_validation');
document.getElementById("regButton").disabled = true
if (kioskCode.value.length < 2) {
kioskCodeValidation.innerHTML = "Kiosk Code must be at least two characters in length"
kioskCodeValidation.style.display="block"
kioskCode.setAttribute("aria-invalid", "true")
} else {
kioskCodeValidated = true
kioskCodeValidation.style.display="none"
kioskCodeValidation.innerHtml = ""
kioskCode.setAttribute("aria-invalid", "false")
}
if (kioskName.value.length < 2) {
kioskNameValidation.innerHTML = "Please enter a full Kiosk Name or location"
kioskNameValidation.style.display="block"
kioskName.setAttribute("aria-invalid", "true")
} else {
kioskNameValidated = true
kioskNameValidation.style.display="none"
kioskNameValidation.innerHtml = ""
kioskName.setAttribute("aria-invalid", "false")
}
if (kioskCodeValidated && kioskNameValidated) {
formValidated = true
document.getElementById("regButton").disabled = false;
}
}
validateFields();
Am I missing something to get JAWS to announce the error text when the field gets focus?
Manipulating contents or availability of elements that take part in the accessible name or description calculation has shaky support and often leads to errors like this.
The same goes for live regions and alert.
It is preferable to add the element itself, or the attribute that includes it in the calculation via the script.
Additionally to
kioskCodeValidation.innerHTML = "Kiosk Code must be at least two characters in length"
kioskCodeValidation.style.display="block"
kioskCode.setAttribute("aria-invalid", "true")
you would do this:
kioskCode.setAttribute("aria-invalid", "true")
kioskCode.setAttribute("aria-describedby", "kiosk_code_validation")
and of course remove the aria-describedby
attribute from the initial HTML.