Concatenating strings within EL expression defined in an attribute of a facelets tag

84,564

Solution 1

String concatenation in EL is only possible by just inlining in the expression. The + operator is in EL exclusively a sum operator. Further, < and > are invalid characters in XML attributes, so you have to escape them (and instruct <h:outputText> to not escape them once again by escape="false"):

<h:outputText value="#{cc.attrs.count}&lt;br/&gt;#{cc.attrs.count-1}" escape="false" rendered="#{cc.attrs.appreciatedByCurrentUser}" />
<h:outputText value="#{cc.attrs.count+1}&lt;br/&gt;#{cc.attrs.count}" escape="false" rendered="#{!cc.attrs.appreciatedByCurrentUser}" />

Alternatively, you can also use <c:set> to alias the expression:

<c:set var="appreciated" value="#{cc.attrs.count}&lt;br/&gt;#{cc.attrs.count-1}" />
<c:set var="notAppreciated" value="#{cc.attrs.count+1}&lt;br/&gt;#{cc.attrs.count}" />
<h:outputText value="#{cc.attrs.appreciatedByCurrentUser ? appreciated : notAppreciated}" escape="false" />

Solution 2

It is possible to concatenate Strings in EL using the java.lang.String.concat(String) method. Thus your code could look like:

<h:outputText value="#{cc.attrs.appreciatedByCurrentUser ?  (''.concat(cc.attrs.count).concat('&lt;br/&gt;').concat(cc.attrs.count-1)) :  (''.concat((cc.attrs.count+1)).concat('&lt;br/&gt;').concat(cc.attrs.count))}" escape="false" />

In this particular case however I would go with one of the options that Mr BalusC had suggested because the code above doesn't look quite elegant. In some cases knowing this technique could be useful, though.

I would hardly recommend using javascript as a workaround here.

Solution 3

This is the only thing i can come up with.

<h:panelGroup rendered="#{cc.attrs.appreciatedByCurrentUser}">
   <h:outputText value="#{(cc.attrs.count)}" style="display:block;" />
   <h:outputText value="#{(cc.attrs.count-1)}" />
</h:panelGroup>
<h:panelGroup rendered="#{not cc.attrs.appreciatedByCurrentUser}">
   <h:outputText value="#{(cc.attrs.count+1)}" style="display:block;" />
   <h:outputText value="#{(cc.attrs.count)}" />
</h:panelGroup>

Putting <br> in a value attribute will always throw errors in JSF, so you'll have to use display:block.

Share:
84,564
Rajat Gupta
Author by

Rajat Gupta

A problem solver &amp; enthusiastic programmer looking out for exciting work opportunities. Highly interested in building Android applications, Web development, &amp; Server side coding involving (sql/ nosql) databases &amp; APIs. I love solving problems, building efficient approaches &amp; algorithms. To describe my strong points, I have pretty decent problem solving skills, fast learner &amp; highly motivated &amp; energetic person! Gained good experience in software development in the past 2 years working on numerous android &amp; web development projects with companies like olready.in, twowaits.com, spactre.com. Selected among Top three finalists for LinkedIn MTV GetAJob Season 4 for Flipkart as Software Developer Intern among 50k candidates.

Updated on February 12, 2020

Comments

  • Rajat Gupta
    Rajat Gupta about 4 years

    I need to write an EL expression for an attribute which goes something like this:

    #{cc.attrs.appreciatedByCurrentUser ? (cc.attrs.count +'<br/>'+ (cc.attrs.count-1)) : ((cc.attrs.count+1) +'<br/>'+ cc.attrs.count)}
    

    Now the problem is that this gives an error as strings cannot be concatenated, the way I am doing it. So how can I rectify this?

    I'm using JSF 2.0 with facelets.


    EDIT :

    I'm resolving the issue using the following inline javascript

                <script type="text/javascript">
                    var count=#{cc.attrs.count};
                    document.write(#{cc.attrs.appreciatedByCurrentUser} ? (count-1) +'<br/>'+count  : count+'<br/>'+ (count+1));
                </script>
    

    Can you think of any issue with this?