Facelets: ui:param default value - jsf

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}" />

Related

Variable set by ui:param or c:set inside ui:repeat is not available outside ui:repeat

I would like to define a variable and reuse it somewhere else on the page. I'm defining variable in JSF using <ui:param> and <c:set> and resetting it in the <ui:repeat> depending on condition as follows:
<ui:param name="title" value="default value"/>
<c:set var="title2" value="default val"/>
<ui:repeat value="#{aClip.revisions}" var="revs" varStatus="revStat">
<ui:repeat value="#{revs.metadataMap.entry}" var="entryLst">
<ui:repeat value="#{entryLst}" var="entry">
<ui:repeat value="#{entry.value}" var="metaVal">
<ui:repeat value="#{metaVal.values}" var="aValue">
<ui:fragment rendered="#{metaVal.key eq 'Title'}">
rendered //this prints. condition is evaluted to true
<ui:param name="title" value="#{aValue}"/>
<c:set var="title2" value="#{aValue}"/>
title2 -- #{title2} title -- #{title} //prints
</ui:fragment>
</ui:repeat>
</ui:repeat>
</ui:repeat>
</ui:repeat>
</ui:repeat>
title2 -- #{title2} title -- #{title} //does not print value not even defualt val
I know condition is true and value is set, but when I try to use it outside loop, it doesn't evalute. It doesn't even evalute to defualt value given to variable while defining.
How is this caused and how can I solve it?

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: h:outputText; how to show a dash when the value is empty string?

I'm using h:outputText tags to display readonly data. Ex:
<h:outputText value="Phone Number:" />
<h:outputText value="#{userHandler.user.phoneNumber}" />
When "phoneNumber" is an empty string or a null, I want to display a dash "-" as the value.
Is there any easy way to do this maybe with expression language or something?
BTW, I thought about adding methods to the User class like getPhoneNumberDisplayText() that could do the check internally, but I since it's a view issue, I'd rather keep the code in the JSF page.
<h:outputText value="#{userHandler.user.phoneNumber != null
? userHandler.user.phoneNumber : '-'}" />
Or, you could make a new outputText:
<h:outputText rendered="#{userHandler.user.phoneNumber == null}" value="-" />

JSF: Ternary operator used to assign a value to an <f:param> fails

I am using JSF tags within an XHTML file. My intention is to enable or disable a <rich:MenuItem> context-menu item by setting the "disabled" attribute to "true" or "false" appropriately. To do this, I am using a backing bean variable in a ternary operator and setting an <f:param> value to either "true" or "false" based on the bean variable, as below:
<rich:componentControl event="oncontextmenu" for="network-tree-menu"
operation="show">
<f:param id="nestlevel" value="#{item.nestLevel > 10 ? 'true' : 'false'}"
name="nestlevel" />
</rich:componentControl>
where item is the backing bean and item.nestLevel is an integer.
I am using this <f:param> value later in the XHTML file as below:
<rich:contextMenu ...
<rich:menuItem id="abc" ajaxSingle="true" disabled="{nestlevel}"
onclick="doSomething();" value="Do something...">
</rich:contextMenu>
This is not working !! The menu item is always enabled, (I guess this is the default behaviour) even though the result of the ternary operation is "true". Is there something I am missing here w.r.t the syntax, or is there some other way I can do this conditional enabling of context-menu items within the XHTML file?
Thanks in advance.
Regards,
Nagendra U M
How about this:
<f:param id="nestlevel" value="#{item.nestLevel > 10}" name="nestlevel" />

Resources