Conditional Rendering of Non-Jsf Components (Plain Vanilla HTML and Template Text)

Conditional rendering of non-JSF components (plain vanilla HTML and template text)

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

How to conditionally render plain HTML elements like divs?

The right JSF component to represent a HTML <div> element is the <h:panelGroup> with the layout attribute set to block. So, this should do:

<h:panelGroup layout="block" ... rendered="#{someCondition}">
...
</h:panelGroup>

Alternatively, wrap it in an <ui:fragment>:

<ui:fragment rendered="#{someCondition}">
<div>
...
</div>
</ui:fragment>

Or when you're already on JSF 2.2+, make it a passthrough element:

<div jsf:rendered="#{someCondition}">

</div>

Do note that when you'd like to ajax-update a conditionally rendered component, then you should be ajax-updating its parent component instead.

See also:

  • Alternative to ui:fragment in JSF
  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)
  • Ajax update/render does not work on a component which has rendered attribute
  • Why do I need to nest a component with rendered="#{some}" in another component when I want to ajax-update it?
  • Is it possible to update non-JSF components (plain HTML) with JSF ajax?

How to not render whole block in JSF?

<h:panelGroup>

If you set attribute layout="block", you will have a <div> tag

Otherwise, you have a <span> tag.

Render JSF component based on user role

If your web.xml is declared as Servlet 3.0 (which implicitly relates to JSP/EL 2.2)

<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">

then you can take benefit of being able to invoke methods with arguments in EL like as ExternalContext#isUserInRole():

rendered="#{facesContext.externalContext.isUserInRole('ADMIN')}"

Note that this requires a Servlet 3.0 capable container, but since you're using Glassfish 3 (which supports Servlet 3.0), it should work without any issues.

Also note that if you're using Facelets instead of JSP, then you've the HttpServletRequest available as #{request} in EL, allowing you the following shorter expression:

rendered="#{request.isUserInRole('ADMIN')}"
  • Conditionally displaying JSF components
  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)
  • JSF: How control access and rights in JSF?

EL expression in c:choose, can't get it working

First and foremost: JSTL tags runs during view build time, not during view render time.

Your concrete problem suggests that #{projectPageBean} is been set during view render time, such as would happen when definied as <ui:repeat var>, <h:dataTable var>, <p:tabView var>, etc. It's thus null during view build time.

In that case, you should not be using a view build time tag to conditionally render HTML. You should instead use a view render time component to conditionally render HTML. As first choice, use <ui:fragment>:

<p>#{projectPageBean.availableMethods}</p>
<ui:fragment rendered="#{projectPageBean.availableMethods}">
<p>Abc</p>
</ui:fragment>
<ui:fragment rendered="#{not projectPageBean.availableMethods}">
<p>Xyz</p>
</ui:fragment>

By the way, there's in Facelets no need to switch between #{} and ${}. In contrary to JSP, in Facelets the ${} behaves exactly the same as #{}. To avoid potential confusion and maintenance trouble, I recommend to stick to #{} all the time.

See also:

  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)

Alternative to ui:fragment in JSF

Since ui:fragment doesn't support rendered most of IDE (like Netbeans mark it as error BUT it works because in JSF parameters are inherited)

This is actually a bug in JSF 2.0 Facelets tag file declaration (in Mojarra, that's the com/sun/faces/metadata/taglib/ui.taglib.xml file). The rendered attribute is overlooked and missing in the tag file declaration (and also in the JSF 2.0 <ui:fragment> tag documentation), while it is really present in the UIComponent. The IDE validation is based on the tag file declarations and hence it gives a misleading validation error. This issue is fixed in JSF 2.1, the missing attribute is added to the tag file declaration (and also in the JSF 2.1 <ui:fragment> tag documentation).

If either just ignoring the IDE warnings or upgrading to JSF 2.1 is not an option, then you can consider using the <h:panelGroup> component instead:

<h:panelGroup rendered="#{condition}">
<h:outputText value="text 1"/>
<h:outputText value="text 2"/>
<h:outputText value="text 3"/>
</h:panelGroup>

It outputs nothing anyway if you don't specify the id, style, styleClass and like attributes, else a simple <span> will be rendered.

If all what you have is plain vanilla HTML (i.e. no JSF components), then you can also consider using <f:verbatim>.

<f:verbatim rendered="#{condition}">
text 1
text 2
text 3
</f:verbatim>

However, the <f:verbatim> is deprecated in JSF 2.0 (which in turn has also a documentary bug by the way, the JSF 2.0 <f:verbatim> tag documentation does not mention deprecation, but the JSF 2.1 <f:verbatim> tag documentation does).

EL expression in c:choose, can't get it working

First and foremost: JSTL tags runs during view build time, not during view render time.

Your concrete problem suggests that #{projectPageBean} is been set during view render time, such as would happen when definied as <ui:repeat var>, <h:dataTable var>, <p:tabView var>, etc. It's thus null during view build time.

In that case, you should not be using a view build time tag to conditionally render HTML. You should instead use a view render time component to conditionally render HTML. As first choice, use <ui:fragment>:

<p>#{projectPageBean.availableMethods}</p>
<ui:fragment rendered="#{projectPageBean.availableMethods}">
<p>Abc</p>
</ui:fragment>
<ui:fragment rendered="#{not projectPageBean.availableMethods}">
<p>Xyz</p>
</ui:fragment>

By the way, there's in Facelets no need to switch between #{} and ${}. In contrary to JSP, in Facelets the ${} behaves exactly the same as #{}. To avoid potential confusion and maintenance trouble, I recommend to stick to #{} all the time.

See also:

  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)

c:if test seems to always evaluate true in JSF2 Facelets

The XML namespace is invalid. It should be

xmlns:c="http://java.sun.com/jsp/jstl/core"

Yes, astonishingly with the /jsp part in the URI! The one without /jsp works only in Facelets 1.x for JSF 1.x. If you have checked the generated HTML output in the webbrowser, you should have noticed as well that the <c:if> is left unparsed in the HTML output.


That said, you should prefer JSF components over JSTL tags, unless technically impossible (i.e. when you actually want to control the building of the view, not rendering of the view). The h:panelGroup as you found out yourself is a good candidate, however the ui:fragment is a nicer choice since it has less overhead.

<ui:fragment rendered="#{not empty title}">
<h1>#{title}</h1>
</ui:fragment>

Note that due to a mistake of the JSF guys in the <ui:fragment> tag definition file of the initial JSF 2.0 version, Netbeans will jerk that the tag doesn't support the rendered attribute, but this is untrue. It certainly supports it. It has been fixed in JSF 2.1 tag definition.

See also:

  • JSTL in JSF2 Facelets... makes sense?
  • Alternative to ui:fragment in JSF
  • Conditional rendering of non-JSF components (plain vanilla HTML and template text)


Related Topics



Leave a reply



Submit