JAWS reads aria-label multiple times for a table with role="img", in MS Edge on Win10 - wai-aria

I have a table element that contains an HTML bar chart, and I want screen readers to read a text description of it, so I'm using this approach:
<table role="img" aria-label="table description">
In Voiceover on Mac, it reads the label and skips over the rest of the content in the table. However in JAWS with MS Edge on Windows 10 it reads "graphic table description" for each td in the table, and in nested tables too. Here's a simplified example:
<table role="img" aria-label="table description">
<tr>
<td>
row 1
</td>
</tr>
<tr>
<td>
row 2
</td>
</tr>
</table>
This problem doesn't happen with IE 11 on the same Windows computer; it reads "graphic table description" just once.
I also tried adding aria-hidden="true", tabindex="-1", and role="presentation" to the td and tr elements in the table, but none of those helped.
Am I doing this wrong? Is there a better way to achieve this? I'm wondering if this is a bug in JAWS...

Continuing from the comment section to the answer section because this might be a solution (and is too long to put in the comment).
The actual <table> has several nested tables in it
Ah, that could be part of the problem. If you use <table role="presentation">, the "presentation" status only conveys to table child elements (<thead>, <tbody>, <tfoot>, <tr>, <th>, <td>) but stops if it hits a nested table. The nested table would also need role="presentation".
If you apply that same logic to using role="img", the nested table would not be seen as an image and would, in fact, cause invalid html because an <img> cannot have any child DOM elements. role="img" on the outer table would make the entire table an image, so the nested <thead>, <tbody>, <tfoot>, <tr>, <th>, <td> elements would all be ignored, but once a nested <table> is seen, then you'd have problems.
I'm not sure if the following would be valid:
<table role="img" aria-label="chart description">
<!-- other table stuff -->
<!-- nested table -->
<table role="presentation">
</table>
</table>
The outer table would be an image and the inner table should be ignored, but you'd still have an element (inner table) inside an image. You'd have to run it through an html parser checker.
In addition to role="presentation" on the inner table, you could also add aria-hidden="true" to hide the table from screen readers, otherwise a screen reader user could navigate all the text elements (if any) inside the "presentation" table.

Related

Is it possible to put Images in table's **td** tag in mpdf Laravel library

I am trying to add an 100 X 100 pixel image in a table in mpdf. But the table disappears when I do so.
<table>
<tr>
<td><img src="https://someimage.jpg" width=100 height=100></td>
</tr>
</table>
But when I use tag outside table it fetches the image and shows it perfectly fine.
How do I put image in table in mpdf (is there any trick)?
From my experience when I tried to use MPDF with tables and images inside cells I couldn't manage to set the correct image sizes. I fixed it with div's instead of table. If possible try this solution
It is possible to put images in a table in mpdf. Earlier i was making syntax mistake. I had forgot a comma. Sorry for inconvineance.
<table>
<tr>
<td><img src="https://someimage.jpg" style="height:50px; width:100px;"></td>
</tr>
</table>

Choosing multiple elements by using a square bracket at the end vs enclosing the whole xpath in braces before sq brackets?

I've come across cases when there are lots of links on the page and the following xpath works for choosing the first one:
//tag[#...]/div/a[1]
There are other cases when the above xpath doesn't work and then I need to use it the following way:
(//tag[#...]/div/a)[1]
As I write lengthier xpaths to code in business logic for which elements to select, this difference starts getting all the more complicated where the same xpath has multiple combinations of both of these.
What is the difference exactly between writing xpaths in these two ways? I've seen that for any particular occasion one of them works and the other doesn't.
Consider this sample HTML:
<table>
<tbody>
<tr>
<td>1.1</td>
<td>1.2</td>
<td>1.3</td>
</tr>
<tr>
<td>2.1</td>
<td>2.2</td>
<td>2.3</td>
</tr>
<tr>
<td>3.1</td>
<td>3.2</td>
<td>3.3</td>
</tr>
</tbody>
</table>
Here you can use //table/tbody/tr/td[index] to go through <td> elements of only first row <tr>. //table/tbody/tr will return the first match, which is your first row and then indexing is done only on the <td> elements in first row. So valid indexes are 1,2,3.
But you can use (//table/tbody/tr/td)[index] if you want to go through all <td> values in the table. Here the indexing applies on the whole xpath which is same for all the <td> elements. So valid indexes are 1,2,3,..9.

View component of MVC. Should I pre generate HTML tag elements in the Controller for the View?

I'am currently creating a MVC Java Web App with Struts2.
One element of my app is searching for some results via form. When the user submits the form an Action gets the necessary values from the database and populates a Map:
Map<Integer,List<String>> values = new HashMap<Integer,List<String>>();
Which has a list of column values for each row.
By Following this approach I can have generic JSP for displaying the results of any resultbox:
<s:div cssClass='resultContainer'
cssStyle=' min-height: 150px; max-height:%{header}px; overflow: auto; %{display}; '
theme="qxhtml">
<table id='resultTable'>
<tr id='tableHeader'>
<s:iterator value="headers">
<th><s:property /></th>
</s:iterator>
</tr>
<s:iterator value="values">
<tr class='results'>
<s:iterator value="value">
<td><s:property escape="false" /></td>
</s:iterator>
</tr>
</s:iterator>
</table>
I feel now that this is a bad approach. Instead I should change the Map to a List of ResultBoxRow objects. Each ResultBox will have its own View Jsp instead of one generic one allowing me to iterate over the objects and output for example:
<s:iterator value="value">
<td><s:property name="firstname" /></td>
<td><s:property name="lastname" /></td>
etc.
In the case of the table headers I may need to give certain headers individual style properties. I feel these should be defined in the JSP itself rather than get the JSP to reference a value from the controller containing the style for that header.
I think my overall question is how much should the controller control the style/display of elements of the View? I feel it should just generate the individual elements displayed in the tags but not the values to put in the "style" tag of the row for example. Even if this does sacrifice a simple single JSP to handle every result box.
It would be great to get your opinions.
The controller should have nothing to do with the display mechanism: that's the point of MVC, to completely separate the data from its presentation.
You can still DRY up the view layer via custom tags, includes, templates, etc. Styles may be passed as attributes, while the underlying DOM would be created by a single page or template.
It also matters what the nature of the attributes you want to pass. If they're semantic that could logically from from the model or controller that's fine. If they're purely presentational, like colors, widths, etc. then it has no business in the model or controller.

Selenium IDE and xpath - find text / row in table and select radio box

I've been using Selenium IDE and getting some good results. I've done a lot of reading about following-sibling and preceding-sibling but I can't locate the right radio button.
Essentially I want to find the row in a table with the word 'testing' and then click the radio button in the cell.
So far I can find the input button
//input[#type='radio']
and find the text testing
//a[contains(text(),'testing')]
I've been trying to use this in the ide
check | //input[#type='radio']/following-sibling::td[1]/a[contains(text(),'testing')]
but I get the error [error] locator not found: //input[#type='radio']/following-sibling::a[contains(text()[1],'testing')]
Any help to change this is really appreciated :)
Cheers
Damien
here's the bare basic table ...
<tbody id="list">
<tr>
<th>
<label class="radio">
<input class="presentation_radio" type="radio" value="1" name="presentation_radio">
</label>
</th>
<td>
testing
</td>
<td>testing</td>
<td>Joe Acme</td>
<td>Presentation</td>
<td>03 May 2012</td>
<td>5 (1)</td>
</tr>
</tbody>
The problem with your xpath is that td and input are not sibling (they don't have common parent) and even if you change your xpath to more correct version:
//input[#type='radio']/following::td[1]/a[contains(text(),'testing')]
it will find a that have preceding checkbox instead of checkbox itself. So correct xpath will be:
//a[contains(text(),'testing')]/preceding::input[#type='radio'][1]
or
//tr[descendant::a[contains(.,'testing')]]//input[#type='radio']
For xpath axis tutorial read this: http://msdn.microsoft.com/en-us/library/ms256456.aspx

Absolute positioning works fine in Chrome and IE, it doesn't in FF

I am trying to set the position of a div within a table cell (with a relative position) to absolute and it works great in Chrome and IE, but in FF it seems as if it's just positioned absolute in relation to the entire body.
I'm trying to get my div to display in the top left of the cell (the link is just used to position another element in my code, but that should be positioned in the upper right of the cell). However in FF the div is displayed in the top left of the entire screen and the (element positioned by the) link in the top right of the entire screen.
Here's the relevant code:
<TD ID="EVENT" style="position:relative;">
<div id="detail" style="position:absolute;top:0;left:0;width:100%;z-index:10;">
content
</div>
</TD>
I'm not sure if this is relevant to the problem, but you're missing a quote mark in your table cell:
<TD ID="EVENT style="position:relative;">
Should read:
<TD ID="EVENT" style="position:relative;">
That sort of thing has caused problems for me in the past, although if it's ok in other browsers maybe that isn't causing the problem.
EDIT: Try using a container div inside the table cell.
<TD ID="EVENT">
<div id="container" style="position:relative;">
<div id="detail" style="position:absolute;top:0;left:0;width:100%;z-index:10;">
content
</div>
</div>
</TD>

Resources