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
How to Vertically Align a Table in CSS
Bad Value X-Ua-Compatible for Attribute Http-Equiv on Element Meta
Why Does CSS Not Support Negative Padding
Multiple Distinct Pages in One HTML File
Overlapping/Overlaying Multiple Inline Images
Prevent a Child Element from Overflowing Its Parent in Flexbox
Difference Between "Visibility:Collapse" and "Display:None"
Why Is "&Reg" Being Rendered as "®" Without The Bounding Semicolon
How to Create a Wavy Shape CSS
Responsive Order Confirmation Emails for Mobile Devices
Select Label Using CSS Selector
Use Multiple @Font-Face Rules in CSS
Maintain Image Aspect Ratio in Carousel
Is It Correct to Use Single Quotes for HTML Attributes
Textarea Value Not Getting Posted with Form