What is the use of defining <ui:fragment> tag in jsf - 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>

Related

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

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" ...>

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.

How can I show/hide row of table in jsf? [duplicate]

I'm trying to conditionally render a <tr> therefore I cannot use <h:panelGroup> as it will render to <span> or <div>
My current (working) approach is the following:
<h:outputFormat rendered="#{negotiator.maySend}">
<tr> my tr stuff </tr>
</h:outputFormat>
This works, but I'm not sure if that's the way to abuse <h:outputFormat> - before that I used <h:outputLabel> but this was rendered to <label> in IE.
I have also read the answers to this question, but as mentioned above, they won't work for me because of the <tr>: How to not render whole block in JSF?
I cannot use <h:panelGroup> as it will render to <span> or <div>
Apparently you didn't test it carefully. The <h:panelGroup> won't render anything if you don't specify attributes which should end up in the client side, like layout, id, styleClass, etc.
Thus, this should technically perfectly work fine.
<h:panelGroup rendered="#{negotiator.maySend}">
<tr> my tr stuff </tr>
</h:panelGroup>
However, better for the main purpose would be to use <ui:fragment>.
<ui:fragment rendered="#{negotiator.maySend}">
<tr> my tr stuff </tr>
</ui:fragment>
This is by the way also possible with <f:verbatim>, but this is deprecated since JSF 2.0 as it's designed specifically for usage in JSP.
See also:
Alternative to ui:fragment in JSF
Conditionally displaying JSF components
How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar"
Ajax update/render does not work on a component which has rendered attribute

Access JSF Custom Tag's id

TL;DR
Is there something like composite's cc.clientId that will give me the id of a custom tag?
Details:
I'd like a custom tag that will render a label, a value, and an icon. When the icon is clicked, a Bootstrap modal is supposed to open up that will edit the value.
<ui:composition>
<div> #{field.label}: #{field.value}
<a class="icon-pencil" data-target="#editForm" data-toggle="modal">
</div>
<h:form id="editForm" class="modal hide fade" role="dialog" ...>
... there's an input here linked to field.value ...
</h:form>
</ui:composition>
I can use the tag with <my:editor />. When I do so within a ui:repeat, an id is prepended to the editForm so that it renders with id j_idt104:editForm. So I need to modify the data-target to include the id.
This would be really easy with a composite component because I have access to the id via cc.clientId:
data-target="\##{cc.clientId}\:editForm"
However, I can't get it to work with a custom tag because I don't know of an EL expression (or something) that will give me access to the id. I could probably wait until after the page is loaded, then use jQuery to inspect the id and set the data-target after the fact, but I was hoping for a more pure-JSF solution.
I'm using JSF 2.1 and Bootstrap 2.3, at the moment.
Answer seems to be no. BalusC says you should replace things like custom tags with "normal" JSF components. In this case, that would mean using the composite component.
If you're deadset on using custom tag, I worked around the issue (with lots of help from the answer here) by using an index in the form's id:
I replaced the ui:repeat with a c:forEach that has access to the item's index:
<table>
<c:forEach items="#{bean.items}" var="item" varStatus="status">
<my:editor index="#{status.index}" ... />
</c:forEach>
</table>
And in the custom tag, I used the index in the data-target:
<tr>
<td>#{label}: #{value}</td>
<td>
<a data-target="\#editForm-#{index}" ... ></a>
<h:form id="editForm-#{index}" ... >
...
</h:form>
</td>
</tr>
The only catch is that c:forEach is a build-time construct (see details in this answer), which is a problem if you need any render-time data (like if you build information up in preRenderView). If you do, then you're better off using ui:repeat with a custom component, and relying on the cc.clientId.

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