Concatenating strings in EL - jsf

The following keeps returning null any idea why
<ui:param name="dialogName" value="#{index.toString().concat('Overlay')}" />

Just do this:
<ui:param name="dialogName" value="#{cc.attrs.xProd.product.productId}Overlay" />
See also:
Concatenating Strings within EL expression

Related

jsf make ui:param result static

I am using templating and pass some values by to use them in the template:
<ui:repeat var="entry" value="#{showEntriesBean.entries}" id="repeatId">
<ui:include src="/templates/entryTemplate.xhtml">
<ui:param name="prePath" value="/" />
<ui:param name="allowedToSee" value="#{bean.calcRandom(0, 10)}" />
</ui:include>
<br />
</ui:repeat>
I found out, that everytime I use the "allowedToSee" variable in my entryTemplate.xhtml, it recalculates its value.
Is there any way to pass the result of calcRandom in a static way? So it is ONCE calculated (when the allowedToSee value is calculated) and performs like a final number? I don't want it to be calculated everytime #{allowedToSee} is used
If you want the value to be held, you should held it somewhere.
What I would do:
1) Create a List<Integer> property.
2) When the values of the entries properties are set, call a method (preRenderEvent? #PostConstruct?) that introduces in your list as many items as there are in entries.
3) Consult that list using the varStatus attribute of ui:repeat
Little more of less, like:
<ui:repeat var="entry" value="#{showEntriesBean.entries}" id="repeatId" varStatus="status">
<ui:include src="/templates/entryTemplate.xhtml">
<ui:param name="prePath" value="/" />
<ui:param name="allowedToSee" value="#{bean.getPrecalculedRandomAt(status.index)}" />
</ui:include>
<br />
</ui:repeat>
More on the varStatus attribute: http://docs.oracle.com/javaee/6/javaserverfaces/2.0/docs/pdldocs/facelets/ui/repeat.html

Facelets: ui:param default value

How can one define a default value for a facelet template parameter?
Consider the following element using a template parameter:
<h:outputText value="#{templParam}"></h:outputText>
The above line will print the the template parameter templParam which is passed by a ui:param tag in a ui:composition using the template:
<ui:param name="templParam" value="Hello world"></ui:param>
But if ui:param tag is missing nothing will be printed. Although, how can one print e.g "Default value" in this case?
Could use this:
<h:outputText value="#{empty templParam ? 'Default value' : templParam}" />
I hope it helps.
A default value can be defined by using a ternary operator checking for null value.
<h:outputText value="#{templParam != null ? templParam : 'Default value'}"></h:outputText>
This will print "Default value" if the parameter was not passed by a ui:param tag.
After the composition tag to define the start of the template, the template parameter can be set to its default value (if it is empty) so that all following uses of it don't require checking for a null each time (and its default value is in one place in the code).
<html xmlns:c="http://java.sun.com/jsp/jstl/core" >
<ui:composition>
<c:set var="templParam" value="#{empty templParam ? 'Default value' : templParam}"
scope="request" />
<h:outputText value="Use 1: #{templParam}" />
<h:outputText value="Use 2: #{templParam}" />

Output curly brace in JSF h:outputText

I want to use the following EL inside a custom component:
<ui:param name="valueAfter"
value="#{not empty valueAfter ? valueAfter : false}" />
<h:outputText
value="#{x.label}#{valueAfter == true ? {x.value} : ''}" />
This does not work as I cannot output the curly braces around x.value but now I am looking for a good way to actually output those.
Try this:
<h:outputText value="#{x.label"}/>
<h:outputText value="{#{x.value}}" rendered="#{valueAfter}"/>
Here you go -In case you are using EL 2 (I think), one line with one h:outputText solution thanks to the .concat()
<h:outputText value="#{x.label}#{valueAfter == true?'{'.concat(x.value).concat('}'):''}" />

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

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?
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('<br/>').concat(cc.attrs.count-1)) : (''.concat((cc.attrs.count+1)).concat('<br/>').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.
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}<br/>#{cc.attrs.count-1}" escape="false" rendered="#{cc.attrs.appreciatedByCurrentUser}" />
<h:outputText value="#{cc.attrs.count+1}<br/>#{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}<br/>#{cc.attrs.count-1}" />
<c:set var="notAppreciated" value="#{cc.attrs.count+1}<br/>#{cc.attrs.count}" />
<h:outputText value="#{cc.attrs.appreciatedByCurrentUser ? appreciated : notAppreciated}" escape="false" />
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.

JSF: ui:include param for "for"-attribute

I have swapped out a composition to re-use it. The composition contains tags like this:
<t:radio for=":someForm:someComponent" index="#{index}" />
I include the composition like this:
<ui:include src="/theComposition.xhtml">
<ui:param name="someParam" value="#{someBean}" />
</ui:include>
But how can I parameterize the "someForm" part of the composition? Because that will differ depending on where I include it. I could pass a string... but how should I concatenate it? Or is there any other way?
You can just inline EL in the attribute value.
<t:radio for=":#{someParam}:someComponent" index="#{index}" />

Resources