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
Related
I am upgrading my application from JSF 1.2 to JSF 2.
I am trying a below simple forEach tag but it not showing anything inside the loop.
<table
id="tab${sectionId}"
border="0"
cellpadding="0"
cellspacing="0"
width="100%"
class="listingTable"
>
<c:forEach
var="row"
rowStatus="index"
items="#{bean.department.userActivities}"
>
<tr>
<td>
test
</td>
</tr>
</c:forEach>
</table>
The value test is not showing up. Has the c:forEach implementaion changed?
I tried replacing with but has some other issue. It is rendering the content inside it. But if I have a component inside , I am not able to assign a backing bean value as ID of the component. Example is as below
<table
id="tab${sectionId}"
border="0"
class="listingTable"
>
<t:dataList
var="row"
rowIndexVar="index"
value="#{bean.department.userActivities}"
>
<h:column>
<h:outputText id="#{row.activityCode}">test1</h:outputText>
</h:column>
</t:dataList>
</table>
So, with . I am not able to assign backing bean property as ID of the component. I am receiving the error "java.lang.IllegalArgumentException: component identifier must not be a zero-length String "
Can anyone please help me in understanding as to why the c:forEach tag is not working. I have huge code which is using forEach tag. With upgrade, I will have to remove every forEach if it is no more supported in JSF2 :(
JSTL taglib/XML namespace URI has changed forth and back across JSTL/JSF/Facelets versions.
For JSF on JSP with JSTL 1.0, it is
<%#taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
For JSF on JSP with JSTL 1.1+, it is
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
For JSF 1.x on Facelets with JSTL 1.1+, it is
<xxx xmlns:c="http://java.sun.com/jstl/core">
For JSF 2.x on Facelets with JSTL 1.2+, it is
<xxx xmlns:c="http://java.sun.com/jsp/jstl/core">
For JSF 2.2+ on Facelets with JSTL 1.2+, it is
<xxx xmlns:c="http://xmlns.jcp.org/jsp/jstl/core">
Make sure you pick the right one.
See also:
Our JSTL wiki page
Unrelated to the concrete problem, as to the underlying functional requirement which you're actually ultimately trying to solve, head to the following related questions for a thought:
Using id="#{...}" causes java.lang.IllegalArgumentException: Empty id attribute is not allowed
How to use EL with <ui:repeat var> in id attribute of a JSF component
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>
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.
I want to access a variable through out my page. The var is declared inside a ui:repeat element. Heard that the scope of the variable in only inside the repeat tag. I want to load another div on the same page which need the details inside this var. How can I achieve this.
<ui:repeat var="errorDetails"
value="#{adminDashboardController.errorDetails}" varStatus="status">
<tr>
<td>#{errorDetails.issueName}</td>
<td>#{errorDetails.priority}</td>
<td>#{errorDetails.comments}</td>
<td><h:commandButton class="btn btn-primary btn-xs view-issue"
value="View" /></td>
</tr>
</ui:repeat>
<h4 class="modal-title" id="myModalLabel">#{errorDetails.issueName}</h4>
The errorDetails variable is only available in the scope of the ui:repeat.
You have here two options:
HTML/JS solution: Generate HTML code which contains one <h4...>#{errorDetails.issueName}</h4> for each line of your table and use JavaScript to display the right block when pressing on the command button.
I think that this option should be only used for performance reason, because you will generate lot of HTML and because as a JSF developer you usually prefer to avoid coding custom things in JavaScript.
JSF solution (my preferred one): use a backing bean to hold the currently viewed error detail. That would be something like this:
<ui:repeat var="errorDetails" value="#{adminDashboardController.errorDetails}" varStatus="status">
...
<h:commandButton ... action="#{adminDashboardController.showDetails(errorDetails)" update="myModalLabel" />
...
</ui:repeat>
...
<h:panelGroup rendered="#{adminDashboardController.currentDetail != null}">
<h4 class="modal-title" id="myModalLabel">#{adminDashboardController.currentDetail.issueName}</h4>
</h:panelGroup>
The AdminDashboardController.showDetails methods would save the given error detail in a the field currentDetail.
This question already has an answer here:
Ajax update/render does not work on a component which has rendered attribute
(1 answer)
Closed 7 years ago.
Hello I have this code to conditionally render components in my page:
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="one two" />
</h:commandButton>
<p><h:outputFormat rendered="#{Bean.answer=='one'}" id="one" value="#{messages.one}"/></p>
<p><h:outputFormat rendered="#{Bean.answer=='two'}" id="two" value="#{messages.two}"/></p>
It gets the answer and renders the component but in order to see it on my page, I need to refresh the page. How can I fix this problem? Any suggestions?
The JSF component's rendered attribute is a server-side setting which controls whether JSF should generate the desired HTML or not.
The <f:ajax> tag's render attribute should point to a (relative) client ID of the JSF-generated HTML element which JavaScript can grab by document.getElementById() from HTML DOM tree in order to replace its contents on complete of the ajax request.
However, since you're specifying the client ID of a HTML element which is never rendered by JSF (due to rendered being false), JavaScript can't find it in the HTML DOM tree.
You need to wrap it in a container component which is always rendered and thus always available in the HTML DOM tree.
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="messages" />
</h:commandButton>
<p>
<h:panelGroup id="messages">
<h:outputFormat rendered="#{Bean.answer=='one'}" value="#{messages.one}"/>
<h:outputFormat rendered="#{Bean.answer=='two'}" value="#{messages.two}"/>
</h:panelGroup>
</p>
Unrelated to the concrete problem, you've there a possible design mistake. Why would you not just create a #{Bean.message} property which you set with the desired message in the action method instead, so that you can just use:
<h:commandButton action="#{Bean.method()}" value="Submit">
<f:ajax execute="something" render="message" />
</h:commandButton>
<p>
<h:outputFormat id="message" value="#{Bean.message}" />
</p>
I know it's not the central point of the question, but as I had this problem many times in the past, I just post it here to help others who are in need.
For those who uses PrimeFaces there's a component in PrimeFaces Extension called Switch.
Sometimes you need to display different outputs or components depending on a value. Usually you can achieve this by using the ui:fragment tag. With the pe:switch util tag you won't have to declare ui:fragment tags, with different checks like ui:fragment rendered="#{!empty someController.value}", anymore.
style="visibility: #{questionchoose.show==false ? 'hidden' : 'visible'}"