Aria-Live="Assertive" is not read by JAWS - html

Hello Stackoverflow community. This is my first question, but I will try to be as concise and detailed as possible.
I have been tasked with updating our ASP.NET web applications to be section 508 compliant. This is all very new to me, and I'm having trouble getting things to work as expected.
We have a page where the user gets additional information about a link via an onmouseover event. Obviously this doesn't work for non-sighted users. So we are providing them with a "More information" button that displays the same "tooltip" div that the sighted user gets.
I added aria-live="assertive to the "tooltip" div with the understanding that if the div was hidden when the page loads and then shown via the button, it would be read by JAWS. To my dismay, this wasn't the case.
The tooltip div looks like this:
<div id='tooltip' aria-live='assertive' style='display:none;'>
<span id='tooltip_message'>This is my tooltip text</span>
</div>
It is shown via the click event of the button with the following JavaScript code:
function ShowTooltip(ttID)
{
var tt = $('#' + ttID);
tt.css('display', '');
}
The button to show the tooltip div looks like this:
<button id='ttBtn' onclick="ShowToolTip('tooltip'); return false;">
More information
</button>
I had success getting JAWS to read the tooltip by adding role="alert" to the tooltip div, but I'd like to avoid using the alert role for non-alert purposes. Mainly because it reads "Alert, this is my tooltip text." to the user.
I'd like to know what is the proper method to get jaws to read the tooltip when it becomes visible?
I am using IE 11 and JAWS 16. Internet Explorer and JAWS are requirements that I cannot change.
Thanks!
-Ray
UPDATE
I thought I'd post the solution we used in case others have the same problem. This is a simplified version of our code that shows just what's necessary to get the tooltip visible and read when it is displayed. This is a server control, so many of the ID's are based off of the control's ClientID property and have known suffixes (_tootip, _tooltipcontainer, etc.)
JavaScript:
//handles showing/hiding of the tooltip
function ShowToolTip(ttID)
{
var tt = $('#' + ttID + '_ToolTip');
var ttContainer = $('#' + ttID + '_ToolTipContainer');
var ttClone = tt.clone();
tt.remove();
ttClone.css('display', '');
ttContainer.append(ttClone);
}
//Closes the tooltip and returns focus to the hidden (from sighted users) button that shows it.
function CloseToolTip(ttID)
{
var tt = $('#' + ttID + '_ToolTip');
tt.css('display', 'none');
}";
Markup:
<button id="tooltip1_508KeyboardButton" class="hidden" onclick="ShowToolTip('tooltip1'); return false;" onblur="CloseToolTip('tooltip1');">Click for overview</button>
<div id='tooltip1_ToolTipContainer' aria-live='polite' aria-atomic='true'>
<div id='tooltip1_ToolTip' class='section tooltip' style='display:none;'>
<span id='tooltip1_Msg'>This is my tooltip's text.</span>
</div>
</div>
I hope this is of use to someone in the future. As I think about it, I could have easily placed an aria-live region that stays visible somewhere off screen that changes it's text when the tooltip is "shown". So there are many ways to skin this particular cat.

As a quick hack, the following seems to work for me with IE11 + JAWS 15
function ShowTooltip(ttID)
{
setTimeout(function(){
$('#' + ttID).css('display', 'block');
}, 100)
}
You could also try the following:
Push the text of your tooltips to an aria-live region that is always available "on screen" to screen readers
Shift the user's focus dynamically to the tooltip. (I'd be very careful about doing this, though. It can be confusing to your users.)

Related

Is there a way to search for searchable text in <map...><area ... title="searchable text" /></map> and <img alt="searchable text" />?

Using Ctrl-F in most browsers will allow you to search for text, but only in only the text areas. I would like to search for text in what should be accessible areas that are not necessarily text rendered areas such as <map ...><area title="searchable text" /></map> and <img alt="searchable text" />. Is there a browser or addon that will do what I'm asking for? This stuff is here for accessibility, but it doesn't seem to be really all that accessible (except by mouse hover, which again isn't all that accessible).
NOTE
An answer that is required, does not use something that is decoupled from the view. I.e. searching through the source code isn't an option as this is largely difficult to read (esp on complex pages) and doesn't show where the information is located on the rendered page.
Is there a browser or addon that will do what I'm asking for?
Oh yes. Lynx browser does it.
But I guess it's not a solution ;-)
If your question is so, there is no way to override what CTRL+F is doing in your browser.
You can design a custom plugin inside your website, or an addon for your browser. This would be quite easy... but will require other shortcut.
If your main problem is to locate tags based on their alt or title attributes content, this is quite easy in javascript:
var search='enter image';
var nodes=document.querySelectorAll("[alt*='"+search+"'],[title*='"+search+"']");
You can then highlight the matching nodes using jquery or what you want.
for (i in nodes) {
nodes[i].className+=' resultHighlighted';
}
and scroll to the first result:
nodes[0].scrollIntoView();
If you intend to create a browser plugin, you can create your custom a bookmarklet or a custom plugin, and associate a shortcut to this bookmark (see https://github.com/iSunilSV/Chrome-Bookmark-Shortcut)
A simple bookmarklet to find the first match by title or alt attribute and scroll to it will be something like that:
javascript:text=prompt("search inside alt or title attribute");
document.querySelector("[alt*='"+text+"'],[title*='"+text+"']").scrollIntoView();
In your browser, use the "View Source" or "Source Code" function, and then within that window that pops up, use the Ctrl-F for Find.
You can also use the "Inspect Element" directly on an element to split the screen into two windows- one for code and one that's rendered.
For more information, here's a sample article for Chrome:
https://support.google.com/adsense/answer/181951?hl=en
Would something like the Web Developer browser plugin work? It's available for Chrome, FF and Opera. There are a few features that toggle the display of various attributes such as title, alt and even ARIA roles. This injects the attribute text inline with the element.
In my opinion, it's not a bug; they were just not designed for this use.
As I'm sure you are aware, the alt attribute replaces the image when it's not available. So how could you scroll to something that is not always displayed? Whereas you seem to be after a permanent description; a figcaption would be more appropriate for this.
As for the title attribute, it was intended to merely clarify the purpose of a link. There should not be any new information to the user in the title; therefore I think it would be redundant to have two lots of the same information highlighted in one place.
The purpose of searching is to find text on screen, seeing as neither title or alt are always displayed I think the user would be more confused by the fact that nothing is highlighted, and that they are just taken to an image or random link/area. If the image has a figcaption that becomes highlighted, then it would make sense to them. Besides, how are they going to search for the title if they don't know what to search for? Title and alt do not come up in text displayed by search engines; the user will never know about it unless they've been to your site before, in which case they'll know where to look.
Also you state the following:
This stuff is here for accessibility, but it doesn't seem to be really all that accessible
Which, understandably, seems true to you as you probably do not need it. However alt and title are read out to those who use screen readers so isn't entirely useless.
Idea 1
I assume you have Windows and Firefox installed
I have my Firefox installed with 2 add-ons.
Install a add-on called Tile Tabs, it make it possible for example left side is web view and the same page on right side with source code.
Install add-on called Web page to source code & viceversa that make it possible to toggle between view and source code by pressing on CTRL+SHIFT+S
Since what you required is not a default thing in all nowadays browses as far as I know.
Screen shot of the solution:
Idea 2
Install FireBug, you can view/edit/debug source codes and view HTML live and what you highlight on the code will be also highlighted on the view.
Screen shot:
Note: Btw idea 1 is not only good for view / source code but it is also good to compare two views or read article to the right and answer question to the left.
You can use the search funktion in Chrome's developer tools "Elements" Tab (Press F12 -> Tab "Elements" -> Press CTRL + F) and use XPath on your searches. Example:
//*[#title="Google"]
Matches will be shown with a yellow background in the code and when you hover it, its position will be hightlited in the view.
Dev Tools "Element" Search with XPath
It is coupled with the view, allows you to see the element's position and it's also an out-of-the-box solution in Chrome (tested in Chromium 45 for Ubuntu).
Hope it helps!
Regards
EDIT
Forgot - If you want to use wildcards on your searches, you can also do it like this:
//*[contains(#title, 'Google')]
EDIT 2
For the posterity! Further research shows that your goal might be possible to achieve using the Firefox-Addon Greasemonkey, which allows you to customize the way a web page displays or behaves, by using small bits of JavaScript.
I performed several tests with this addon and could achieve a nice effect with simple images (display the ALT attribute as a DIV overlapping the image), but with area sections the thing gets a lot more complicated, as area regions can be squares, circles, and polygons with infinite coordinates plus retrieving the exact positioning of the area itself can be a bit tricky but maybe gives you or someone else a start point.
Based on the ALT Tooltips Script (http://greasemonkey-user-scripts.arantius.com/alt-tooltips-for-firefox), I created the following script and defined it in Greasemonkey:
// ==UserScript==
// #name Alt Tooltips 2
// #namespace http://www.biterion.com
// #description Alt Tooltips 2
// #include *
// #grant all
// ==/UserScript==
function getPosition(element) {
var xPosition = 0;
var yPosition = 0;
while(element) {
xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
yPosition += (element.offsetTop - element.scrollTop + element.clientTop);
element = element.offsetParent;
}
return { x: xPosition, y: yPosition };
}
function getAreaPosition(element) {
var position = element.coords.split(',');
xPosition = position[0];
yPosition = position[1];
return { x: xPosition, y: yPosition}
}
var res = document.evaluate("//img",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i, el;
for (i=0; el=res.snapshotItem(i); i++) {
if(el.alt) {
alternate = el.alt
} else {
alternate = "No alt text";
}
position = getPosition(el);
var newDIV = document.createElement ('div');
newDIV.innerHTML = "<div style='position:absolute;background:yellow;color:black;top:" + position["y"] + ";left:" + position["x"] + "' id=" + i + ">" + alternate + "</div>";
document.body.appendChild(newDIV);
}
var res2 = document.evaluate("//area",document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
var i2, el2;
for (i2=0; el2=res2.snapshotItem(i2); i2++) {
if(el2.alt) {
alternate2 = el2.alt
} else {
alternate2 = "No alt text";
}
position2 = getAreaPosition(el2);
var newDIV2 = document.createElement('div');
newDIV2.innerHTML = "<div style='position:absolute;background:yellow;color:black;top:" + position2["y"] + ";left:" + position2["x"] + "' id=" + i2 + ">" + alternate2 + "</div>";
document.body.appendChild(newDIV2);
}
As you can see, the script firstly detects all "img" and "area" elements, extracts its positioning and creates a new DIV element containing the "alt" attribute, which is then positioned on the upper left corner of the image.
As stated, the problem with areas is, that the positioning should be relative to the parent image and not absolute like in the script, plus the coordinates should be extracted accordingly to the type of area shape (currently only extracting the two first coordinates of each area, which will work for squares but will surely fail for other shapes).
Hope this will help someone :-D
Regards

How to hide link information at the bottom left/right of the browser on hover

How can I create a link that doesn't show its information at the bottom left or right (this depends on the link's position) when you hovering a hyperlink?
Lets say that we have a link like this:
Users
and we want to hide its information or more precisely its hyperlink information that's displayed at the bottom left corner of the browser, like the example on the image below:
Now, I know this is possible because Stack Exchange network sites itself uses this for the "Welcome Banner" displayed on the front page for the very first time you visit each site.
If you hover any of the links:
Anybody can ask a question
Anybody can answer
The best answers are voted up and rise to the top
You'll see that no hyperlink information is displayed. Check out image below to see "Welcome Banner"
It cannot be done with pure html and css. You would have to use javascript for this. Showing the link of an anchor tag is just how most browsers work. Also the user expects to be able to see where he will be redirected.
But it can be done: you can avoid using an anchor tag. Then have another attribute hold the href - like "data-href". Then bind a click event on the a tag that redirects based on this attribute.
I would however, not do this - as I am uncertain if crawlers would see the link.
This is how it can be done, but note that snippets cannot redirect outside SO :)
var aTags = document.querySelectorAll('span[data-href]');
for(var i = 0; i < aTags.length; i++){
var aTag = aTags[i];
aTag.addEventListener('click', function(e){
var ele = e.target;
window.location.replace(ele.getAttribute('data-href'));
});
}
span[data-href]{
cursor:pointer;
}
<span data-href="http://www.google.com">test</span>
After digging even more deeper, I've found a more simpler and easier solution for it on this w3schools article and also with the help of this question in SO I could manage it to open on a new window:
<button id="anchorID" >Go to page</button>
$("#anchorID").click(function() {
window.open(
'http://www.w3schools.com',
'_blank' // <- This makes it open in a new window.
);
});
Jsfiddle live example: http://jsfiddle.net/6sLzghhm/
Remove the href="whatever" from the link and open link by calling a function. This completely removes the link preview on the bottom left of the page.
HTML-
<a (click)="openUrl('https://google.com')">
JS-
openUrl(url: string): void {
window.open(url, '_blank');
}
The stackoverflows Anybody can ask a question-Link is not a hyperlink. Its a HTML Element (in this case a li-Element):
<li id="q">Anybody can ask a question
</li>
with the CSS cursor: pointer; and a click-Eventlistener.
The easiest answer is just use-
<p onclick="window.open('Your Link')">Blah Blah Blah</p>
Easy!
You can also open more links at a time-
HTML:
<p onclick="OpenTwoLinks()">Google And StackOverFlow</p>
Javascript:
function OpenTwoLinks() {
window.open('https://google.com');
window.open('https://stackoverflow.com');
}

TabIndex - hitting tab moves me to Address Bar - unable to work around this using Focus or +tab indexes

I read several threads that talk about how the Address Bar in IE is basically the first one to get focus when using TAB (MSDN's own docs talk about this).
Yet, I have seen situations where this doesn't always have to be the case....
I have a master page and inside my content area is a formView.
It defaults to INSERT view and can never leave it (they can only insert not edit and reading is handled elsewhere)
So on my page load for the page I have:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If fvwLogEntry.CurrentMode = FormViewMode.Insert = True Then
'Set the default field to position the cursor there...hopefully
Dim FCtxtHrEmployeeId As TextBox
FCtxtHrEmployeeId = CType(fvwLogEntry.FindControl("txtHrEmployeeId"), TextBox)
Page.SetFocus(FCtxtHrEmployeeId.ClientID.ToString)
End If
Now that works, when the page loads it sets the cursor to the employeeID text box inside the formview's INSERT template.
HOWEVER, when I hit TAB it takes me to the address bar and THEN if I hit tab again it takes me through the rest of the items on the page.
I set the tab index of the first item to 11 and then incrimented from there (I had read that IE's toolbars have tab indexes too so I thought perhaps using a higher number would bypass those, but again that doesn't REALLY make sense since it would still start at the lowest number, but I gave it a shot thinking it would move forward from where the focus was set.) If I click on the textbox and then hit TAB it DOES move through the page like I would expect.
It is just when the page loads and gets the focus set to the employeeID textbox that hitting tab moves it to the address bar.
I also tried setting the other controls to -1 (those I didn't want it to tab to), still no luck there.
So... what can I do to get around this?
There MUST be a simple way to set the focus to the employeeID textbox and ensure that pressing TAB after that moves to the next control in the formview's insert template and does NOT jump up to the address bar?
The following jquery code seems to be working fine for me..
$(window).load(function () {
$('.myClass :visible:input:enabled:first').focus();
});
$('body').on('keydown', '.myClass :visible:input:enabled:first', function (e) {
if ((e.which == 9) || (e.keyCode == 9)) {
$('.myClass :visible:input:enabled:first').focus();
}
});
I found another better option which is fastest as of what I tried.
Here's the code for that
function handleTabOrder() {
$('.myClass :visible:input:enabled').each(function (index) {
$(this).attr('tabindex', index + 10);
});
$('.myClass :visible:input:enabled:first').keydown(function (e) {
if (e.keyCode == 9 || e.which == 9) {
$("[tabindex=10]").focus();
}
});
}
What I have done here is to assign Tab order to all the visible controls on the page, then I have handled the key down event of only first control(that shifts the control to address bar) and now it shifts the control to next visible input item on the screen..
Its just a work around but works faster than any of the other things mentioned in the thread.
Just write the above function and all it in on-load event of page.
I was having this issue as well. For me, it was being caused by the use of the .select() method in order to bring focus automatically on a text field as soon as the page loaded. I changed my code to instead use JQuery's .focus() method and that resolved the issue.
I faced similar problem in IE. After some analysis I found that, this problem occurs if there is any HTML content outside form.
for example:
<html>
<div id="1">
</div>
<form>
//other code
</form>
</html>
It worked for me, after I moved all HTML inside form tag.
<html>
<form>
<div id="1">
</div>
//other code
</form>
</html>
Have a look at: http://www.w3schools.com/tags/att_global_tabindex.asp
Your txtHrEmployeeId element should have tabindex 1 and all other elements should have higher values.
-1 is not valid
Also verify that the tabindex are correct in the html that gets rendered (right-click in page and "view source").
I realize this is an old post, but an even simpler method is to add a "tab-stop" attribute to the form element with the last tabindex. Then bind a keydown listener and force focus to the first tabindex when the tab-stop is encountered.
Here's a simple example:
<input type="text" tab-stop />
$document.bind("keydown", function(event) {
var attrs = event.currentTarget.activeElement.attributes;
if (attrs['tab-stop']) {
angular.element.find('select')[0].focus();
event.preventDefault();
}
});
};
The answer mentioned in my other post works fine but it made the page take a huge performance hit because with every key press on the page the whole DOM was being searched for the elements.
So I found a new more optimized solution
var myNameSpace = function(){
this.selector = '.myClass :visible:input:enabled:first';
this.myElement = $(selector);
this._body = $('body');
var _self= this;
this._body.on('keydown',_self.selector,function(e){
if ((e.which == 9) || (e.keyCode == 9)) {
_self.myElement.focus();
}
});
};
The general idea being to 'cache' the node to be accessed. No need to traverse the DOM again and again for just selecting.
I had this same problem. It turns out mine was related to the ajax modal popup extenders. a modal popup was being shown, even though technically i could not see it because it was wrapped inside a parent div that was hidden. if you are using modal popup extenders, this could be causing an issue like this.
If you are using JSF or Primefaces, you can make use of:
<p:focus for"formname"></p:focus>

HTML: How to make a readonly textarea copyable in iOS-devices

How do I make a textarea and input type="text" highlightable and copyable on iOS-devices?
This does not work:
<textarea readonly="readonly">Totally readonly, cannot be copied</textarea>
Neither does:
<textarea disabled="disabled">Totally readonly, cannot be copied</textarea>
EDIT: The text-area is constantly being updated, so a one-off transformation of it won't work.
The content of the textarea can also be HTML.
I have a JSFiddle that I tested this on: http://jsfiddle.net/sebnilsson/jfvWZ/
One solution could be to find all the readonly textareas on the page and render a div with the contents in place of the read only field. I have written some very simple JS to demonstrate this.
Something along the lines of
$('textarea[readonly]').removeAttr('readonly').each(function () {
var $this = $(this);
$this.hide().after('<div data-textarea="' + $this.attr('id')
+ '" class="textarea">' + $this.val() + '</div>');
}).on('textareachange', function () {
var $this = $(this);
$('[data-textarea="' + $this.attr('id') + '"]').html($this.val());
});
You will also need to trigger the event when you update the textarea value.
For example
$('textarea').val('test').trigger('textareachange');
There's a more extensive example here with examples on the styling etc.
http://jsfiddle.net/ssfUx/3/
I've successfull select some text on my iPhone, but needs many try.
<textarea readonly onfocus="this.blur();">Totally readonly, CAN BE copied</textarea>
and the last : http://jsfiddle.net/jfvWZ/6/
<div>
<label>Plain div</label><br />
<div id="plain-div" onFocus="this.blur();">
Plain div
</div>
</div>
Easy to select the text on iPhone
Likewise ran into this issue.
Not sure if the following is a decent, correct or semantic alternative, but it worked for me.
I simply changed the textarea to a div readonly, same styles applied.
The one drawback is that in JavaScript I couldn't target the div with this['myForm']. It doesn't appear to be a child of the form element in DOM.
Instead I had to get the element by id and set it's innerHTML, rather than set the value as with textarea.
It worked on Ipad 1 IOS5 and Iphone 4s IOS7 I am now able to select and copy text to clipboard.

Page moves on link submit

I was wondering if anyone knew how, when on link submit the page does not move i.e
If it was 2 page lengths down it would shoot up to the top.
If you have attached event to HTML control through jQuery then you can use return false like
$("#myDiv").delegate("tr", "click", function() {
enter code here
return false;
});
No need to replace anchors, as your own answer to the question states.
This will work just as well:
<a href="#" onclick="yourOwnSubmitFunction(); return false;">
In short, just make sure that whatever function is in the onClick handler returns boolean false.
Whilst having the link's onclick handler return false; is the correct way to stop a link being followed, it's a bit of a hack to use a link this way, because what you've got is an action and not a link. You can't do the usual link-like things to your link, like right-click-bookmark, or middle-click-for-new-tab and so on, so it shouldn't really have that affordance.
An alternative (that eg. SO uses) is to put the onclick on a non-link element instead, eg.:
<span id="potato">Do something</span>
<script type="text/javascript">
document.getElementById('potato').onclick= function() {
// do something
};
</script>
This is cleaner, but has a drawback in is that the link can't be focused and activated by the usual keyboard tabbing method.
Arguably better is to use an <input type="button"> or <button type="button">, which are the right markup to represent an action. Of course these look quite different, but you can use CSS to style them so that they look like a link instead of a button if you like. The one drawback of this method is that good old silly IE cannot completely restyle a button; you will get a few pixels of unremovable extra padding in this browser.
If you are using .net 2.0
There is a
MaintainScrollPositionOnPostback
property in #page directive that you can use to maintain the scroll position of the page.
Gets or sets a value indicating
whether to return the user to the same
position in the client browser after
postback. This property replaces the
obsolete SmartNavigation property.
When Web pages are posted back to the
server, the user is returned to the
top of the page. On long Web pages,
this means that the user has to scroll
the page back to the last position on
the page.
When the
MaintainScrollPositionOnPostback()()()
property is set to true, the user is
instead returned to the last position
on the page.
If you can't use this then set location.href to an anchor tag at the specified position after the submit.
location.href = "#anchAtPos";
where anchAtPos is the id of the anchor tag at a specified position.
I solved this using:
function anchorReplace()
{
$("#reportWrapper a").each(function(i){
var anchorElement = $(this);
var newAnchorElement = $('<a href="#link' + i + '" name="#link' + i + '">'
+ anchorElement.text() + '</a>').insertBefore(anchorElement);
anchorElement.remove();
});
}
I've fixed this before by putting
onclick='return false;'
Inside the link
<a href="#" onclick='return false;' id='attachAlistenertothisID'>This link doesn't jump to the top!</a>
I use this for my links that have click listeners attached them via jQuery.
Hope this helps someone!