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

15,698

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>
Share:
15,698
magenta placenta
Author by

magenta placenta

Updated on June 04, 2022

Comments

  • magenta placenta
    magenta placenta almost 2 years

    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}">
    
  • magenta placenta
    magenta placenta about 12 years
    Neither seem to work. In your version, B.xhtml doesn't get loaded when the page is accessed without a query string, A.xhtml is loaded. I can't seem to use EL in my template, either, it causes a stack overflow, crashes my editor (RAD) and it won't relaunch. I have to edit the file in another editor (remove the EL in my template), then RAD will launch. This is in JSF 1.2 as well.
  • BalusC
    BalusC about 12 years
    I must admit that this is a quite strange way of using <ui:composition>, but as I don't know your functional requirement and other details and I have myself never used this construct, I just ignored the strange usage. But after all, don't you rather mean to use <ui:decorate> or at least <ui:include> which in turn uncludes another composition?
  • magenta placenta
    magenta placenta about 12 years
    BTW, it does work without rendering a composition - as well as what I was trying yesterday. <h:outputText value="with param: #{param.foo== 'bar'}"/><br/> <h:outputText value="no param: #{param.foo != 'bar'}"/> These output true and false and work correctly, but when I try to render the templates, they just don't work. I did try ui:decorate as well, but it gave me duplicate ID errors - it seemed to be pulling in both templates.