66

Is it possible to define variable and reuse the variable later in EL expressions ?

For example :

<h:inputText 
   value="#{myBean.data.something.very.long}"
   rendered="#{myBean.data.something.very.long.showing}"
/>

What i have in mind is something like :

<!-- 
     somehow define a variable here like : 
     myVar = #{myBean.data.something.very.long} 
-->
<h:inputText 
   value="#{myVar}"
   rendered="#{myVar.showing}"
/>

Any ideas ? Thank you !

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Bertie
  • 17,277
  • 45
  • 129
  • 182

2 Answers2

119

You can use <c:set> for this:

<c:set var="myVar" value="#{myBean.data.something.very.long}" scope="request" />

This EL expression will then be evaluated once and stored in the request scope. Note that this works only when the value is available during view build time. If that's not the case, then you'd need to remove the scope attribtue so that it becomes a true "alias":

<c:set var="myVar" value="#{myBean.data.something.very.long}" />

Note thus that this does not cache the evaluated value in the request scope! It will be re-evaluated everytime.

Do NOT use <ui:param>. When not used in order to pass a parameter to the template as defined in <ui:composition> or <ui:decorate>, and thus in essence abusing it, then the behavior is unspecified and in fact it would be a bug in the JSF implementation being used if it were possible. This should never be relied upon. See also JSTL in JSF2 Facelets... makes sense?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 2
    Wow, thanks ! I thought ui:param only supplies a variable to be used in a template, which makes use of ui:composition. Does that mean every jsf page that i make is a facelet even though im not using ui:composition ? – Bertie Jun 23 '11 at 01:10
  • @BalusC, what do you mean by don't cache the value ? – Mahmoud Saleh Dec 06 '11 at 12:33
  • 8
    @Msaleh: Everytime you call `#{myVar}` then the `#{myBean.data.something.very.long}` will be re-evaluated. It will not be evaluated only once during the set. It's thus merely an "alias". – BalusC Dec 06 '11 at 12:43
  • ok, it doesn't cache, but is there any reason why *it shouldn't* ? – Rajat Gupta Jun 17 '13 at 14:57
  • 2
    @user: Because, by default, EL expressions may evaluate to a different value depending on the moment you invoke it. E.g. depending on the current phase, iteration status of a repeating component, etc. If you want to explicitly set it in request, view, session or application scope use as answered the ``. – BalusC Jun 17 '13 at 15:09
  • Somewhere there was a mention of `` to which bertie further refers, but is now gone. He is actually asking a very valid question: `` documents: "Use this tag to pass parameters to an included file (using ui:include), or a template (linked to either a composition or decorator). Embed ui:param tags in either ui:include, ui:composition, or ui:decorate to pass the parameters." - can we use `` outside that context? See also https://stackoverflow.com/a/13620210/744133 – YoYo Nov 12 '18 at 19:46
  • @YoYo: You can, but the behavior is unspecified and should absolutely not be relied on. It's in fact a bug in the JSF implementation if abusing as would be possible. See also https://stackoverflow.com/q/3342984 – BalusC Nov 13 '18 at 12:29
19

Like any view in MVC, the page should be as simple as possible. If you want a shortcut, put the shortcut into the controller (the @ManagedBean or @Named bean).

Controller:

@Named
public MyBean
{
    public Data getData()
    {
        return data;
    }

    public Foo getFooShortcut()
    {
        return data.getSomething().getVery().getLong();
    ]
}

View:

<h:inputText 
   value="#{myBean.fooShortcut}"
   rendered="#{myBean.fooShortcut.showing}"
/>
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Matt Ball
  • 354,903
  • 100
  • 647
  • 710