2
votes

I'm fairly new to ARIA and its functionality with screen readers but I've been trying to figure out why the popup is not being read. It gets changed when a user clicks a save button which refreshes the page to which a message will appear but then the screen reader doesn't pick up the change in message.

From what I've read both aria-live="assertive" and role="alert" should work

I've tried various positions for the tags and aria attributes without luck. It's only when I re-click the main content section will it read the alert.

I've tested on IE11 and Chrome (though it really only needs to work on IE)

FYI originally all the < p > were < c:out >

--Main Layout

<div class="body-content" style="padding: 4px 0">
 <a id="main_content" tabindex="-1" name="main_content"></a>

<!--                <h1>Main Content</h1> -->
<!--                <p>This is the main content area. -->


<tiles:insertAttribute name="body" />         


</div>

--Include message on every screen

<jsp:include page="messages.jsp" />

--messages.jsp <

div id="errorDiv" aria-live="assertive" class="error" role="alert">
<c:if test="${not empty errors}">
<c:set var="popupErr" value=""/>

        <c:forEach var="error" items="${errors}">

                    <p > ${error}</p>
                <br />
            <c:if test="${popupErr != ''}">
               <c:set var="popupErr">

                            <p > ${popupErr}</p>

                       <c:out value="${popupErr}" escapeXml="false" />\r\n

                   </c:set>
            </c:if>
            <c:set var="popupErr" >

                    <p> ${error}</p>

                <c:out value="${popupErr}" escapeXml="false"/><c:out value="${error}" escapeXml="false" />

            </c:set>
        </c:forEach>

    <c:remove var="errors" scope="session"/>

</c:if>

</div>
<div id="msgDiv" class="message" aria-live="assertive" role="alert">
<c:if test="${not empty message}">
<c:set var="popupMsg" value=""/>

        <c:forEach var="msg" items="${message}">

                <p > ${msg}</p>
                <br />  
            <c:if test="${popupMsg != ''}">
               <c:set var="popupMsg">

                <p > ${popupMsg}</p>

                  <c:out value="${popupMsg}" escapeXml="false"/>\r\n

               </c:set>
            </c:if>

            <c:set var="popupMsg">

                <p > ${popupMsg}</p>

                <c:out value="${popupMsg}" escapeXml="false"/><c:out value="${msg}" escapeXml="false"/>

            </c:set>              
        </c:forEach>


    <c:remove var="message" scope="session"/>

</c:if>

</div>

EDIT:

This is more of an issue of the page not being re-read once it refreshes after the save click

1

1 Answers

3
votes

The question is old, but if someone else stumbles upon it (like me):

Your application seems to be rendered on server side, hence is static as far as the browser is concerned (no JS involved changing the DOM at runtime). I think the following explains why this won't cause screenreaders to announce the message:

Assistive technologies will announce dynamic changes in the content of a live region. The live region must first be present (and usually empty), so that the browser and assistive technologies are aware of it. Any subsequent changes are then announced. https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions

Simply including an aria-live attribute or a specialized live region role (such as role="alert") in the initial markup as it's loaded will have no effect.

Or from another source:

Dynamically rendered alerts are automatically announced by most screen readers, and in some operating systems, they may trigger an alert sound. It is important to note that, at this time, screen readers do not inform users of alerts that are present on the page before page load completes.

https://www.w3.org/TR/wai-aria-practices/#alert