JSF datatable not complying to WCAG due to unsupported aria-label attribute - jsf

I am using JSF to code my application and it has a datatable.
Each row of the datatable has a checkbox in the first column, and some text in the rest of the columns.
My application needs to comply to the WCAG 2.0 and I'm using a Chrome Extension "Axe" to scan my application.
The "Axe" tool flagged out that the datatable with the checkboxes is not complying to the clause "Ensure every form element has a label" and the proposed solution is to add the "aria-label" attribute.
However JSF datatable does not have the "aria-label" attribute.
Would need to ask if any experts out there have any solution?

JSF 2.2 Support pass through attributes. So it's easy to add customized attributes into the primefaces tag.
Add tag reference at the top:
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough"
Declare it inside the primefaces tag:
p:inputText value="#{bean.value}" pt:aria-label="Whatever you want"

A checkbox needs a label, whether visible or not, in order for screen readers to announce the checkbox properly. For sighted users, having a column header in your table is sufficient as the label for the checkboxes below it. However, for screen reader users, unless you associate the column header with each checkbox, it won't be announced. Ignoring JSF for a moment, if you are writing straight html, you could have something like this:
<table border="1" style="border-collapse: collapse">
<tr>
<th scope="col" id="check_label">select me</th>
<th scope="col">some other value</th>
</tr>
<tr>
<td>
<input type="checkbox" aria-labelledby="check_label">
</td>
<td>hello</td>
</tr>
<tr>
<td>
<input type="checkbox" aria-labelledby="check_label">
</td>
<td>there</td>
</tr>
</table>
Each checkbox has an aria-labelledby attribute pointing to the column header ("check_label"). This works pretty well for most screen readers, but there are some cases where the checkbox label is not read, for example in NVDA if you are using the table navigation keys (ctrl+alt+arrow) and navigate down the checkbox column, the name is not read for the checkboxes. That could be a bug with NVDA, I'm not sure.
An alternative to the above is to have a visually hidden <label> specifically associated with each checkbox. This works whether you navigate the table using the TAB key or ctrl+alt+arrow.
<table border="1" style="border-collapse: collapse">
<tr>
<th scope="col">select me</th>
<th scope="col">some other value</th>
</tr>
<tr>
<td>
<input type="checkbox" id="check1">
<label for="check1" class="sr-only">select me</span>
</td>
<td>hello</td>
</tr>
<tr>
<td>
<input type="checkbox" id="check2">
<label for="check2" class="sr-only">select me</span>
</td>
<td>there</td>
</tr>
</table>
Now, getting back to JSF, of which I knew nothing about until I read this question, it looks like there are two ways to specify a checkbox, https://docs.oracle.com/javaee/5/tutorial/doc/bnaqd.html#bnaqh.
selectBooleanCheckbox
selectManyCheckbox
selectBooleanCheckbox, by default, does not have a label associated with the checkbox where as selectManyCheckbox does. However, you can also specify an <h:outputLabel> to be paired with the selectBooleanCheckbox so I think that's your answer. See the example in the selectBooleanCheckbox doc.
And with more recent versions of JSF you can also add the aria related attributes by using JSF Passtrough attributes (Spec)
So provided you add the right namespacedeclaration, you can do
<h:selectBooleanCheckbox pt:aria-labbeledby="check_label" ...>
But it can also be put on a datatable
<h:datatable pt:aria-labbeledby="check_label" ...>

Related

Primefaces Organigram - Add table into node

I am using the organigram from Primefaces. And I am trying to integrate a html table into a organigram node.
This worked fine. But the table is shown in another place of the page too.
I also tried to use a primefaces table or primefaces panel. But there is the same problem. I get the element in the node AND on another place in the page.
<p:organigramNode type="mit" skipLeafHandling="true" >
<table>
<tr style="background-color: #E6E6E6">
<td><h:outputText value="Name" /></td>
<td><h:outputText value="#{node.name}" /></td>
</tr>
<tr>
<td><h:outputText value="Functions" /></td>
<td><h:outputText value="#node.functions}" /></td>
</tr>
</table>
</p:organigramNode>
How is it possible to integrate a table into a organigram node?
Same problem here. I couldn't find the root cause (possibly a PF defect). A simple workaround is to use CSS means to remove the duplicate elements from the DOM tree by assigning the property "display: none" to it. Not elegant, but working.
So, you have to give your table an CLASS (or ID) tag and then remove it from the DOM tree via:
#organigramPanel_content > .YourTableClassName{
display: none !important;
}
Supposed to work like a charm.

What is the use of defining <ui:fragment> tag in jsf

I am new to JSF. I read about tag. But I find only examples not about when to use and what if we don't use it?
I want to know what is the real requirement for use of <ui:fragment> tag.
Is it really necessary at any point?
Can some body explain me with and without this what could be the output?
This is what i found by observing my existing project. Anybody can correct me if I am wrong.
I think this can be used, if you want to display some component based on the condition. So inside <ui:fragment> attribute 'rendered' can be used to control the display of fragment.
<ui:fragment rendered="#{rowStatus.index % 2 == 0}">
<tr>
<td width="16%">#{slots.dateStr}</td>
<td width="65%">Day #{rowStatus.index + 1} (#{dailySlots.weekStr})</td>
<td width="4%">PM</td>
</tr>
</ui:fragment>

Stop generation tables and fieldset tag in output of Check box / Radio button Group control

When using a checkbox group XPage generates fieldset and table tags around it. Is there a way to not generate that? For e.g. if my XPage source looks like this -
<xp:checkBoxGroup id="checkBoxGroup" disableTheme="true" value="#{document1.CheckboxGroup}">
<xp:selectItems>
<xp:this.value><![CDATA[#{javascript:new Array("Option 1", "Option 2", "Option 3");}]]></xp:this.value>
</xp:selectItems>
</xp:checkBoxGroup>
Then my generated code is
<fieldset id="view:_id1:checkBoxGroup">
<table>
<tr>
<td>
<label><input name="view:_id1:checkBoxGroup" value="Option 1" type="checkbox"> Option 1</input></label>
</td>
<td>
<label><input name="view:_id1:checkBoxGroup" value="Option 2" type="checkbox"> Option 2</input></label>
</td>
<td>
<label><input name="view:_id1:checkBoxGroup" value="Option 3" type="checkbox"> Option 3</input></label>
</td>
</tr>
</table>
</fieldset>
That's a lot of code for three checkboxes. And it messes up my CSS as putting any CSS for table tag puts it on the checkbox group also. The also goes for radio button group. I tried setting disableTheme property to true but that also didn't work.
If you want to fundamentally change the structure of the HTML representation of a component, you can use the Extensibility API to create an alternate renderer. This allows you full control over what markup is sent to the browser for a specific component instance without changing how any other components are rendered. Register the renderer with the same component-family as the default renderer (javax.faces.SelectMany), but assign it a custom renderer-type; if you then assign that custom value to the rendererType property of a specific checkbox group, Domino will use your custom renderer class to emit the HTML instead of the default renderer class.
You can also use the xp:radio control instead of the xp:radioGroup control and then group several radio buttons using the groupName property. Radio buttons rendered from xp:radio are not surrounded with fieldset and table.

What is the JSF 2.0 code for handling user authentication?

The standard tutorials for J2EE 6 show the handling of user authentication as follows:
<form method="POST" action="j_security_check">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td align="right">Username: </td>
<td>
<input type="text" name="j_username">
</td>
</tr>
<tr>
<td align="right">Password: </td>
<td>
<input type="password" name="j_password">
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="Login">
</td>
</tr>
</table>
</form>
The approach uses the special container function "j_security_check" with special fields "j_username" and "j_password".
* Would this be possible to do in JSF 2.0 ?
* Are the j_username/j_password fields available after successful authentication? More precisely, how do I identify the user after they have authenticated?
Any simple, example code snippets would be much appreciated.
Would this be possible to do in JSF 2.0 ?
Yes. It's after all just a bunch of HTML and the container is the one who's doing the authentication, not JSF itself. An alternative is programmatic login by HttpServletRequest#login(). This allows you to use a fullworthy JSF form with JSF based validation, ajax fanciness and all on em. See also this answer for a kickoff example: Does JSF support form based security
Are the j_username/j_password fields available after successful authentication? More precisely, how do I identify the user after they have authenticated?
Only the username is in JSF context available by ExternalContext#getRemoteUser() and in views by #{request.remoteUser}. The password is not available for obvious security reasons.
Quite some time ago I tried to accomplish a jsf (1.2) login page with spring security. However as I did not succeed I finally gave up and did it with a "regular" jsp as you're doing it above.
You can identify the current user by injecting the current SessionContext into your EJB:
#Resource
SessionContext sessionContext;
public void doSth() {
log.info("The current user's name is: "
+ sessionContext.getCallerPrincipal().getName() );
}
You can do the same on HttpServletRequest:
request.getUserPrincipal();
Or from FacesContext:
FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal();

How to read the value of the radio button

I would like to read the selected role information on form submit (a role is selected for a user from a list of roles). How do I read the selected radio button value in my EntityHome interface (Note: I didn't want to use the h:selectOneRadio option here)
<tr>
<s:div rendered="#{userHome.instance.type ne 'admin'}">
<th width="150" class="rich-table-subheadercell center">#{_user.getName()}</th>
</s:div>
<c:forEach items="#{userHome.instance.roles}" var="_role">
<td width="150" class="center" style="background: rgb(100, 100, 100) none repeat scroll 0% 0%;">
#{_role.name}
<input type="radio" style="display : none" name="#{userHome.instance.id}" value="#{_role.id}"/>
</td>
</c:forEach>
</tr>
Two comments.
First of all. Use JSF Components where you can.
Secondly. Avoid using JSTL tags. Remove the c:forEach if you don't have to use it. Replace it with ui:repeat, h:dataTable etc.
Now to answer your question for a workaround if you can't directly use h:selectOneRadio
What you will have to do is use #WebRemote in Seam, and then by using javascript you can on form submit, set the value through Ajax in your UserHome component.
Take a look at chapter 5. Remoting in the Seam Documentation for more information on how to use Remoting.
You need to point the value / list to an ArrayList of SelectItem there's where the items you selected will be stored.

Resources