NVDA/JAWS: Always read a page from the beginning (even on a re-visit) - nvda

NVDA sometimes seems to remember the position until where I have read a page. When I re-visit that same page, the cursor is placed at this position.
While this may seem handy sometimes, it can lead to unpredictable behaviour e.g. when in a shopping cart and removing the last item. When the page is reloaded, the focus is stuck somewhere in the footer, because the last item isn't there anymore.
I want to disable this, e.g. I always want to have the cursor placed to the beginning of the page (except when the focus is explicitly placed using JavaScript). But I don't find the option for it.
In JAWS, there's a similar option, but I don't remember how it was called (something like "Skip visited elements" maybe?)
I have created a working demo of the problem here:
http://developer-guide.access4all.ch/en/examples/remember_position_when_revisiting_page_example

Related

Can't properly force a component on-screen with scrollComponentToVisible

On a given form, we replace one component with another.
The original component is a series of TextFields, and the new form is some informational text and a button. We hide the first one, and show the second one (the UI designer has both Containers within the form).
I tried using scrollRectToVisible with various values but it didn't seem to make any difference with the scrolling.
continueButtonContainer.setHidden(false);
f.forceRevalidate();
Button continueButton =
(Button)StateMachine.GetInstance().findByName("ButtonContinue", f);
f.scrollComponentToVisible(continueButtonContainer);
f.scrollComponentToVisible(continueButton);
I'm expecting the continue button to be near the top of the screen.
If the screen was scrolled before displaying the continue button, the button ends up right at the bottom of the screen (it was below the bottom of the screen before I put in the scrollComponentToVisible line(s).
After the user scrolls the screen, the button goes up to where it needs to be, and stays there.
If the screen is not scrolled, the button appears where it should be.
I know I can probably add some invisible containers underneath the button and force them onto the screen, but I would rather have a slightly more robust solution.
There are a few issues with this. First you are using forceRevalidate which should be used in very rare cases.
Second it seems that you are invoking this on a Form, this is a bit misleading. While it seems that:
f.add(myCmp);
Adds a component to the form it is really a synonym to:
f.getContentPane().add(myCmp);
That's important because you need to invoke the scrollComponentToVisible on the scrollable container which will actually do the work and ideally be the direct parent of said component. I'm assuming it's the content pane in your case but it depends on layout etc.
The last part is letting the layout do its job. If you are invoking this before the form is showing this might not work. Notice that doing it after a call to show is meaningless as the form might take time with transitions. You can use a show listener or override the laidOut callback method to perform things like this.

Angular Retain Proper Scroll Position when Transitioning Routes or Refreshing

I'm using ui-router.
A similar question has been asked on this a Number of times... But the solutions seem to be all over the place and either the question doesn't address a simple idea or the answer doesn't, either.
Here's my simple ui-view setup:
A master view has the navbar and footer
Children of the master view/route that can be activated include the Homepage, About Us page and Learn More page
Pretty simple...
By default, if the homepage is activated, and scrolled down 500px, and I click on a route to the "About Us" page, that page will be scrolled down 500px. Obviously this is not desired.
So... Everyone's solution is some variation of setting document.scrollTop(0) on every state change success. This is atrocious.
While it fixes the issue at hand, it clobbers the browser back button behavior. Here are some problems:
When a refresh is called, the standard browser behavior of refreshing to the current location is ruined
When the back button is clicked, the homepage would then scroll all the way to the top
If the back and forward button were clicked, I wouldn't retain the correct spot on the next page, either
This whole document.scrollTop(0) or any variation of it, really doesn't seem to be viable and I've yet to see a clear solution to this.

Accessibility: Page Loader indicator using aria-live

Issue: I have an accessibility issue that I am struggling with. I have an angular web application. A page loading spinner/indicator is shown when content is loading. And when the page content has loaded the spinner is hidden. This "div" is never removed from DOM.
Content of the loading div are not read (by NVDAor jaws) when the loading div is shown.
<div class='loading' aria-live='polite' aria-label='Do not refresh the page' tabindex="-1">Do not refresh the page</div>
I wouldn't like to change the structure of the application but work around using 'aria tags' to resolve this, just wondering if I will have to do anything more to make aria-live work?
Updated (27/July/2016)
Further clarification: I am not removing the content from DOM but using css to show/hide content (display: none to display: block and vice versa)
aria-live triggers screen readers when an element with aria-live (or text within an element with aria-live) is added or removed from the DOM. In contrast, when you unhide a hidden element, neither elements nor text are added or removed from the DOM, so the element's aria-live property doesn’t come into play.
To get screen readers to announce “Do not refresh the page”, either of these options should do the trick:
You can create the <div class='loading' aria-live='polite'> element and its text content from scratch and then add that element to the DOM.
Or you can start with an empty <div class='loading' aria-live='polite'> element and then populate its text content.
A few other tidbits:
As long as the text inside the element is what you want to be read aloud, you can omit the element’s aria-label='Do not refresh the page' attribute.
For icing on the cake, it can’t hurt to include a role attribute on the div that has aria-live. If you’re not sure which role to use, go with role="status"—that’s a pretty safe bet.
When or if the page is at a state where you no longer need to display "Do not refresh the page”, be sure to reverse the steps above. (That is, if you went with the first option and you added the whole element to the DOM, remove that entire element from the DOM. Or if you went with the second option and you populated the element’s text content, clear out the element’s text content.)
There are several issues with dynamically added or shown/hidden live-region.
Firstly a quote from MDN - 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.
Dynamically adding an element with an aria-live attribute or specialized role to the document also won't result in any announcement by assistive technologies (as, at that point, the browser/assistive technologies are not aware of the live region yet, so cannot monitor it for changes).
Always make sure that the live region is present in the document first, and only then dynamically add/change any content.
From my personal experience, even if a live regoin exists in the DOM on page load if you use show/hide then NVDA also has a bug which requires a small delay before a text update in a live region after it was shown initially. Apparently because the region didn't exist when the first text was added, so this isn't an "update". Regarding the timeout, you'd need to set it to something greater than the browser's refresh tick. I use 100ms. Disclaimer: I am strongly against such workarounds to make up for the issues with screen readers or browsers but it might be useful for someone in some cases.

Select control stops showing its drop down list with IE, AngularJS and some strangely-specific conditions

I have a weird problem whereby a <select> control stops showing its drop down list in IE11 using AngularJS after changing the value (twice).
Chrome (42) and FF (37) do not exhibit the issue.
Plunker: http://plnkr.co/edit/Ea0nMnPxXdqm8O59NyZS?p=preview
Fiddle: http://jsfiddle.net/xydvqo0q/
Steps:
Click the select to open its drop down list.
Select either of the two listed options. (It closes and a couple of other fields in the page update their values.)
Click to open again.
Select the other option. (It closes and the fields update again.)
Click to open the drop down list again. Will no longer open
Neither mouse click, nor Alt-downarrow will show the drop down once it gets into this state.
(Further, other selects on the same page also stop showing their drop down lists, and there appears to be a general control/windowing issue for the page - e.g. you can't select HTML text, and other controls won't show the focus or caret. Seems like IE loses the plot about which is the active "window" and it seems to be stuck inside the select. Pressing Tab a few times gets it out of this stuck state.)
Now, an IE control/windowing bug isn't unusual. But this is weird because of the specific set of requirements to reproduce. I've stripped back the example to what seems to be the minimum required to reproduce (yet you might think there's heaps of stuff in the page that should be irrelevant - afraid not).
The page needs the following for the issue to show:
The nested table (which lists "hello"s) must be there (and it must be nested - if it's not inside another table then the problem goes away). (I made it list hellos to eliminate it listing scope data to eliminate that as a cause.)
The table row which contains {{selecteditem.number}} must be there, and must be AFTER the nested table (moving it before removes the issue). I moved it to a separate table and the problem remains.
The selecteditem.number data must be different for the two items. If the "number" values are the same for the two items, it will not show the issue.
The number of "sub items" for each of the two items must be the SAME (meaning the nested table ends up with the same number of rows). If you add another sub-item to one of the items, the problem is fixed. If you add a sub-item to both (so they both have two) then the problem returns.
(Are you thinking I'm crazy yet? I thought I was. But wait there's more...)
The nested table must have the CSS property border-collapse: collapse. Without this property, or with a different value for this property, the issue doesn't occur. Note: the table can inherit this property from the parent table, or from a table CSS rule, or from a class (as the demo shows) and the issue still occurs. Removing it "live" using IE's F12 dev console and the issue gets fixed.
The TDs of the nested table - i.e. the "hellos" - must have a CSS border. They can inherit this, or obtain it from the class (as per the demo).
Basically, I have to tell the client they can have a collapsed-bordered table to show sub-items in the table of fields (there are usually many more than in the demo) or have a drop down list, but not both. (Or don't use IE, which isn't an option, or change the order of you form, which then would make no sense to the users.)
I tried not using ng-options (and instead ng-repeat-ing an option) but I get the same result (I'm limited to 2 links so here's the plnkr ID: 95XcM9j2eY70jUK10UrH).
I may dump the select entirely.

history and selection model questions

I am trying to build an app using Extjs 4.1. In general: it is a viewport with a tree panel on the west and a center panel that it is actually a tab-holder panel. When a user clicks on a tree node a tab is populating the center view. I had set an attribute in the tree panel that after selecting a node it gets deselected (deselectAll). The reason for this is that the user can open many tabs from different places (e.g. within each tab). But, when I set the above attribute it is producing an error (the “data” is undefined). The data that is undefined is the data related to the tree node. So, the question concerning selection model:
How can I address this problem (a solution may be to select the fist node, but I don’t want it)?
As for the history utility, I need to implement browser back button. Especially I want to disable browser’s refresh button. If user opens let’s say 15 tabs and accidentally click on browser refresh or “F5” he/she will lose everything. I had tried many things but with no luck. I am unable to understand “Ext history util”. So,
Is there any good example out there?
Could anybody guide me on how to do it?
Notice that the application is built respecting the new “MVC” architecture.
Stopping the refresh event is pretty easy - providing that your page has the focus. E.g.:
Ext.getDoc().on('keypress', function(event) {
if (event.getCharCode() == event.F5) {
event.stopEvent();
console.log('you stopped the refresh event');
}
});
If your page doesn't have the focus then there is nothing that can be done -- but most of the time your page loses the focus when a different browser tab is opened so F5 would be refreshing that one instead anyway.
I'm still trying to wrap my wits around the first part of your question, but I thought I would share that.
EDIT
Instead of trying to stop the default browser behavior (something which you can only do on a very limited basis), you should look into state management. ExtJS supports it on many components. Here is the ExtJS example.
Also here is the example of controlling browser history.

Resources