2
votes

I have a web application written using ZK framework. I am currently testing this application for Americans With Disabilities Act compliance. I am using JAWS version 17 for screen reader testing in Firefox, Chrome, Safari and Internet Explorer.

When a user who is using Internet Explorer 11 navigates to the final(4th) page of the application, JAWS reads one line (red circle) first, and then jumps back to the top of the page and reads the entire page from top to bottom.

final page screenshot

The rest of the application reads from top to bottom, left to right, which is the desired effect.

If I remove the circled line, JAWS reads the 3rd line first, and then moves back to the top of the page. I tried putting some extra line breaks in the source around the 2nd label, but it has no effect.

Do you know what is wrong with this page and is causing this to happen? Or is there some way I can force JAWS to read the page from top to bottom?

Here is the offending .zul file:

<?init class="org.zkoss.zk.ui.util.Composition" arg0="/contents/theme/layout/template.zul"?>
<?page id="ConfirmRequest" title="Leave Application" contentType="text/html;charset=UTF-8"?>
<?root-attributes lang="en"?>
<?link href="contents/theme/css/main.css" rel="stylesheet" type="text/css"?>
<?script src="contents/scripts/utility.js" ?>

<?component name="caption" extends="caption" sclass="scaption"?>
<?component name="label" extends="label" sclass="slabel"?>
<?component name="elabel" extends="label" sclass="slabel elabel"?>
<?component name="textbox" extends="textbox" sclass="stextbox"?>

<zk xmlns:n="native" xmlns:ca="client/attribute"
    xmlns:w="http://www.zkoss.org/2005/zk/client">
    <script>

        <![CDATA[

        function exitpage() {

        var win = window.open('', '_self'); window.close(); win.close();
        getSession().invalidate(); return false;

        }

        (function($) { var oldHTML = $.fn.html;

        $.fn.formhtml = function() { if (arguments.length) return
        oldHTML.apply(this,arguments); $("input,button",
        this).each(function() { this.setAttribute('value',this.value);
        this.setAttribute('readonly',true); }); $("textarea",
        this).each(function() {

        this.innerHTML = this.value; }); $("input:radio,input:checkbox",
        this).each(function() {

        if (this.checked) this.setAttribute('checked', 'checked'); else
        this.removeAttribute('checked'); }); $("option",
        this).each(function() {

        if (this.selected) this.setAttribute('selected', 'selected');
        else this.removeAttribute('selected'); }); return
        oldHTML.apply(this); }; })(jQuery); ]]>

    </script>
    <window width="100%" id="win4" self="@define(content)" border="none"
        contentStyle="overflow:auto" apply="org.zkoss.bind.BindComposer"
        viewModel="@id('vm') @init('onlineLv.impl.LeaveController')"
        validationMessages="@id('vmsgs')"
        form="@id('fx4') @load(vm.user, before='submit')">
        <div id="printgrp">
            <vlayout spacing="10px">
                <!-- ****************************************** -->
                <!-- Confirmation Statement -->
                <!-- ****************************************** -->
                <div align="center">
                    <n:h1>Confirmation Statement</n:h1>
                </div>
                <div align="center">
                    <vlayout spacing="10px">
                        <label
                            value="Your Application Has Been Submitted!" class="submission" />
                        <hlayout>
                            <label value="Your request number is" class="confirmationImportant" />
                            <label id="confirmNumber"
                                style="font-weight: bold;" class="confirmationImportant"  />
                        </hlayout>
                        <hlayout>
                            <label
                                if="${!empty vm.user.empEmail}" value="Confirmation eMail has been sent to" />
                            <label id="empEmail"
                                if="${!empty vm.user.empEmail}" style="font-weight: bold;" value="@bind(vm.user.empEmail)"/>
                        </hlayout>
                        <label
                            value="Please print and keep this confirmation statement for your records." class="confirmationImportant" style="font-weight: bold;" />
                    </vlayout>
                </div>
                <div align="center" class="divReviewInfo">
                    <div>
                        <!-- ****************************************** -->
                        <!-- Employee Leave Information -->
                        <!-- ****************************************** -->
                        <div align="left" >
                            <div>
                                <n:h2>Employee Leave Information</n:h2>
                            </div>
                            <div>
                                <label value="First Name:"
                                    if="${vm.user.empFName!=null}" class="confirmationLabelHeader" />
                                <label sclass="empFName"
                                    if="${vm.user.empFName!=null}" class="confirmationLabel"
                                    value="@bind(vm.user.empFName)" />
                            </div>
                            <div>
                                <label value="Last Name:"
                                    if="${vm.user.empLName!=null}" class="confirmationLabelHeader" />
                                <label sclass="empLName"
                                    if="${vm.user.empLName!=null}" class="confirmationLabel"
                                    value="@bind(vm.user.empLName)" />
                            </div>
                            <div>
                                <label value="Employee ID:"
                                    if="${vm.user.empNum!=null}" class="confirmationLabelHeader" />
                                <label sclass="empNum"
                                    if="${vm.user.empNum!=null}" class="confirmationLabel"
                                    value="@bind(vm.user.empNum)" />
                            </div>
                            <div>
                                <label value="Leave Type:"
                                    if="${vm.user.lvType!=null}" class="confirmationLabelHeader" />
                                <label sclass="lvType"
                                    if="${vm.user.lvType!=null}" class="confirmationLabel"
                                    value="@bind(vm.user.lvType)" />
                            </div>
                            <div if="${vm.user.intermi=='yes'}">
                                <label id="linterm"
                                    if="${vm.user.intermi=='yes'}" value="Intermittent:"
                                    class="confirmationLabelHeader" />
                                <label id="interm"
                                    if="${vm.user.intermi=='yes'}" class="confirmationLabel"
                                    value="@bind(vm.user.intermittent)" />
                            </div>
                            <div>
                                <label value="Leave Start Date:"
                                    if="${vm.user.lvBegin!=null}" class="confirmationLabelHeader" />
                                <label id="lvBegin"
                                    if="${vm.user.lvBegin!=null}" class="confirmationLabel"
                                    value="@load(vm.user.lvBeginFormatted)" />
                            </div>
                            <div>
                                <label
                                    value="Estimated Return to Work Date:"
                                    if="${vm.user.estRTW!=null}" class="confirmationLabelHeader" />
                                <label id="estRTW"
                                    if="${vm.user.estRTW!=null}" class="confirmationLabel"
                                    value="@load(vm.user.estRTWFormatted)" />
                            </div>
                        </div>
                        <!-- ****************************************** -->
                        <!-- Leave Credit Information -->
                        <!-- ****************************************** -->
                        <div>
                            <div>
                                <n:h2>Leave Credit Information</n:h2>
                            </div>
                            <div>
                                <label id="coann" value="Annual:"
                                    class="confirmationLabelHeader" />
                                <label id="cann"
                                    class="confirmationLabel" 
                                    value="@load(vm.user.annualLeave.amountFormatted)" />
                            </div>
                            <div>
                                <label id="cobank" value="Banked:"
                                    class="confirmationLabelHeader" />
                                <label id="cbank"
                                    class="confirmationLabel" 
                                    value="@load(vm.user.bankedLeave.amountFormatted)" />
                            </div>
                            <div>
                                <label id="codeferred" value="Deferred:"
                                    class="confirmationLabelHeader" />
                                <label id="cdeferred"
                                    class="confirmationLabel" 
                                    value="@load(vm.user.deferredHours.amountFormatted)" />
                            </div>
                            <div>
                                <label id="cocomp" value="Comp:"
                                    class="confirmationLabelHeader" />
                                <label id="ccomp"
                                    class="confirmationLabel"
                                    value="@load(vm.user.compTime.amountFormatted)" />
                            </div>
                            <div>
                                <label id="cosick" value="Sick:"
                                    class="confirmationLabelHeader" />
                                <label id="csick"
                                    class="confirmationLabel" 
                                    value="@load(vm.user.sick_amount_formattedForReviewPage)" />
                            </div>
                        </div>
                    </div>
                </div>
                <div style="clear:both"></div>
                <!-- ****************************************** -->
                <!-- What's Next? -->
                <!-- ****************************************** -->
                <div align="center">
                    <n:h1>What's Next?</n:h1>
                </div>
                <div hflex="5">
                    <vlayout spacing="13px">
                        <div>
                            <hlayout spacing="15px">
                                <label value="1." />
                                <div>
                                    <label
                                        value="If you haven't already, have your healthcare provider complete and submit the appropriate"
                                        multiline="true" />
                                    <a
                                        href=""
                                        target="_blank">
                                        medical certification form.
                                    </a>
                                </div>
                            </hlayout>
                        </div>
                        <div>
                            <hlayout spacing="100px">
                                <hlayout spacing="15px">
                                    <label value="2." />
                                    <label
                                        value="If you are off work, continue to follow the standard call in procedure for your agency." />
                                </hlayout>
                            </hlayout>
                        </div>
                        <div>
                            <hlayout spacing="15px">

                                <label value="3." />
                                <div>
                                    <label
                                        value="You will receive a letter from the Disability Management Office regarding your"
                                        multiline="true" />
                                    <a
                                        href=""
                                        target="_blank">
                                        FMLA Entitlement.
                                    </a>
                                </div>

                            </hlayout>
                        </div>
                        <div>
                            <hlayout spacing="100px">
                                <hlayout spacing="15px">
                                    <label value="4." />
                                    <label
                                        value="Your request will be assigned to a Disability Management caseworker for review." />
                                </hlayout>
                            </hlayout>
                        </div>
                        <div>
                            <hlayout spacing="100px">
                                <hlayout spacing="15px">
                                    <label value="5." />
                                    <label
                                        value="Once required documents have been received, you will be notified by email and/or letter if your leave has been approved or denied." />
                                </hlayout>
                            </hlayout>
                        </div>
                    </vlayout>
                </div>
                <!-- ****************************************** -->
                <!-- Buttons -->
                <!-- ****************************************** -->
                <div align="center">
                    <hlayout spacing="20px">
                        <n:div id="divButtonPrint">
                            <button id="print"
                                image="button_print.png"
                                xmlns:w="http://www.zkoss.org/2005/zk/client"
                                w:onClick="window.print();" tooltiptext="Print" />
                            <label class="context">Print</label>
                        </n:div>
                    </hlayout>
                </div>
            </vlayout>
        </div>
        <zscript>
    confirmNumber.setValue(Executions.getCurrent().getParameter("srNum"));
        </zscript>
    </window>
    <script type="text/javascript">
        /* ********************************/
        // ADA functionality
        /* ********************************/
        zk.afterMount(function() {
            $('#divButtonPrint img').attr('alt','Print');
        });
    </script>
</zk>

TLDR: Using Jaws 17 and IE 11, label 2 in the "What's next?" region is read before any other content on the page. How can I get the page to read from top to bottom?

1
Just a test, does it still happen when you remove you zk.afterMount script?chillworld
@chillworld I tested your theory. Removing the zk.afterMount seems to make it become an intermittent problem. What I mean is that 3 out of 4 times running through it, the page read in the proper order. The third run through was back to reading line 2 first. This is quite perplexing as we have included a zk.aftermount on all four pages, and it seems to only be causing a problem on the 4th page. To be clear, with the zk.aftermount included on the 4th page, the page reads out of order every time, without it included it reads out of order intermittently.rogerdeuce
I suggest try adding a focus on your first element in the aftermount. I'm not sure of it, but testing can't harmchillworld
@chillworld We have a div in the header with id="pageHeader". I added $('#pageHeader').focus();` to our zk.afterMount function. I was able to successfully go through the application 7 times with Jaws reading the page from top to bottom. On attempt 8 and 9 Jaws went back to reading line 2 first again. It seems to be getting better, but is still inconsistent. Any other ideas?rogerdeuce
Mhhh, I'm almost out of idea's, because I can't test it myself. If I could debug, I think I'll try removing as much I can, and still having the problem, so we know what code is good. Or adding a hidden textbox in the top, set the tabindex to 0 or 1 and in the script focus on that.chillworld

1 Answers

0
votes

In order to overcome this issue we have decided to delay the rendering of the content in the What's Next? section by half a second. To delay the rendering we used the Renderdefer property in the div for that section like this:

            <!-- ****************************************** -->
            <!-- What's Next? -->
            <!-- ****************************************** -->
            <div align="center">
                <n:h1>What's Next?</n:h1>
            </div>
            <div hflex="5" Renderdefer="500">
                <vlayout spacing="13px">
                    <div>
                        <hlayout spacing="15px">
                            <label value="1." />
                            <div>
                                <label......

This also required a couple aria tags to be added to the div that encompasses the page:

<div id="printgrp" ca:aria-live="Assertive" ca:aria-atomic="True">

These tags let the screen reader know that the content may be updated, and to read the changes.

sources: