Conditionally render JSF h:panelGrid based on presence of query string (or no query string at all)

magenta placenta picture magenta placenta · Mar 23, 2012 · Viewed 15.6k times · Source

I'm trying to dynamically render some composition/templates based on the presence of a query string or the absence of a query string. For example:

localhost:9080/myWonderfulApp/test.xhtml?foo=bar

This works, A.xhtml gets pulled in.

localhost:9080/myWonderfulApp/test.xhtml

This doesn't work, B.xhtml does not get pulled in.

I'm having problems with the absence of a query string part. I can render A.xhtml when I pass ?foo=bar, but I can't seem to get B.xhtml rendered when I have no query string. I've tried some variations, I initially figured #{param['foo'] != 'bar' would work, but I think that's not working because I don't have a foo query param at all. I've tried checking if param == null but that didn't work either.

Is it possible to set my rendered attribute based on NO query string?

I can't just set another query string for B.xhtml, either as I'm working on a legacy app that gets 2 different skins, so retrofitting all the old apps that link in isn't an option. New apps will use a query string, old ones need to get an old skin linking in with no query string.

<!--This works-->
<h:panelGrid rendered="#{param['foo'] == 'bar' ? true : false}">
    <ui:composition template="A.xhtml">...</ui:composition>
</h:panelGrid>

<!--This doesn't work-->
<h:panelGrid rendered="#{param == null ? true : false}">
    <ui:composition template="B.xhtml">...</ui:composition>
</h:panelGrid>

This doesn't seem to work, either:

<h:panelGrid rendered="#{empty facesContext.externalContext.requestParameterMap.foo ? true : false}">

Answer

BalusC picture BalusC · Mar 23, 2012

You just need the inverse condition: #{param.foo != 'bar'}. Those conditional operators returning booleans are unnecessary, the equation itself returns a boolean already. The #{param} is never null. It returns a Map<String, String> which is just empty (not null!) when it doesn't contain any parameters. The brace notation is only useful when the parameter name contains periods which would otherwise be interpreted as nested properties, but request parameter names shouldn't contain periods anyway.

So, this should do:

<h:panelGrid rendered="#{param.foo == 'bar'}">
    <ui:composition template="A.xhtml">...</ui:composition>
</h:panelGrid>

<h:panelGrid rendered="#{param.foo != 'bar'}">
    <ui:composition template="B.xhtml">...</ui:composition>
</h:panelGrid>

As a different alternative, if you want to use the conditional operators the right way, you can also do

<ui:composition template="#{param.foo == 'bar' ? 'A' : 'B'}.xhtml">...</ui:composition>