Value expressions still evaluated despite ui:fragment rendered="false" - jsf

I have bean:
class Property{
private String type;
private Date value;
//getters and setters
}
also have block of code on page:
<ui:fragment rendered="#{property.type eq 'checkbox'}">
<ui:include src="checkbox.xhtml">
<ui:param name="property" value="#{property}"/>
</ui:include>
</ui:fragment>
checkbox.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition>
<h:selectBooleanCheckbox value="#{property.value}"/>
</ui:composition>
</body>
</html>
The condition #{property.type eq 'checkbox'} = false
But I get next exception:
javax.servlet.ServletException: checkBox.xhtml value="#{property.value}": Cannot convert 01.11.02 0:00 of type class java.util.Date to class java.lang.Boolean
I expect if the attribute rendered=false in ui:include, then this block will not be processed.

<ui:fragment rendered> prevents it from rendering the HTML output, but it doesn't prevent it from ending up in JSF component tree and being eligible for state saving.
Use <c:if test> instead. It runs during view build time instead of view render time and thus the whole bunch won't end up in JSF component tree at all.
Or, if you have this all inside an <ui:repeat var="property">, and you are using Mojarra, then upgrade to at least 2.1.29 or 2.2.7 wherein this state saving bug was fixed.
See also:
JSTL in JSF2 Facelets... makes sense?
PropertyNotFoundException on conditionally rendered subclasses in ui:repeat

Related

Composite component causes warning "no 'head' component has been defined within the view"

I have a working JSF page, but if I add xmlns:leaf="http://java.sun.com/jsf/composite/jsf2leaf" to it, and try to use any ot its tags, like <leaf:map center="42.120000,-72.540000" />, I get the following warning:
One or more resources have the target of 'head', but no 'head' component has been defined within the view.
Everything works fine, the map is there, I can add markers, but I can't get rid of the warning message.
My JSF page looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui" xml:lang="hu" lang="hu"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:leaf="http://java.sun.com/jsf/composite/jsf2leaf"
>
<f:view contentType="text/html">
<f:metadata>
<f:viewAction action="#{dashboardController.readURLParam()}"/>
</f:metadata>
<h:head/>
<h:body>
...
<h:form>
...
<p:panel>
...
<c:forEach>
...
<p:panel>
<leaf:map center="42.120000,-72.540000" />
</p:panel>
</c:forEach>
</p:panel>
</h:form>
</h:body>
</f:view>
found the problem, it, in the jsf2leaf.jar the map.xhtml and advancedmap.xhtml uses <head></head> instead of <h:head></h:head>, changed it, repackaged the jar file, and it works fine

Programmatically loaded composite disappear elements after postback

In my project I'm adding programmatically a composite component to a primefaces p:panel, as described here: How to programmatically or dynamically create a composite component in JSF 2 .
This is the composite component:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui">
<composite:interface>
</composite:interface>
<composite:implementation>
<h:panelGroup styleClass="ui-grid ui-grid-responsive"
id="myPG" layout="block">
<div class="ui-grid ui-grid-responsive label-777777">
<div class="ui-grid-row">
<div class="ui-grid-col-11-5">
<label>#{msgs['label.content']}</label>
</div>
</div>
</div>
<p:commandButton styleClass="myButton blueButton"
id="myCompositeButton" value="#{msgs['button.elimina']}"
update="#form"
actionListener="#{myController.onMyClick}" />
</h:panelGroup>
</composite:implementation>
</html>
When added to the page, it show fine, but after the postback of the button, the "div" part, disappear (it isn't sent to the browser).
If I implements the div whith h:panelGroup and h:outputlabel, the elements get rendered but empty (#{msgs['label.content']} is void).
Here is the onMyClick handler (no logic in it):
public void onMyClick()
{
System.out.println("#########################################CALLBAK");
}
Where I'm wrong?
Primefaces version is 5.1, running on JBoss AS 7.1.1
As I was having problem to programmatically create a component on the target architecture (IBM WAS 8.5, with myfaces 2.0 and no, I can't change jsf implementation), I changed the approach, using backing bean bound ui:include inside an h:panelGroup
<h:panelGroup id="myPanel" layout="block" rendered="#{myController.moduleSelected }">
<ui:include src="#{myController.moduleType}"></ui:include>
</h:panelGroup>
Posting the answer to help other users

Saving and reusing tag definition in PrimeFaces

Let's say I have the following construct polluting the simplicity of my JSF code in many places:
<p:calendar id="decisionDate"
effect="explode"
yearRange="2000:2100"
pattern="MM/dd/yyyy"
navigator="true" display="inline"
value=""
label="Decision Date"
maxlength="10"
size="20">
<f:convertDateTime pattern="MM/dd/yyyy" />
</p:calendar>
As can be seen, this has nine (9) attributes and a nested tag. This is an awful amount of tedious detail to consume with your eye.
Is there a way I can reuse PrimeFaces tags in a similar way as CSS: to save a complex tag definition as <px:myCalendar/> with the above parameters minus the ID ones, which should be set for each instance of use nonetheless, where px would be my namespace and then each time I need to invoke it, I would just say <px:myCalendar id="uniqueCalID"/> and ... BOOM ... there goes all the repeated clutter?
POST ANSWER EDIT: Check out this tutorial
You can define composite component. It is defined with xhtml+ jsf namespaces and, but in your case it is unnesessary, backing component, which is java class, instantiated for every composite component usage.
Within composite component interface you can define attributes, which vary its behaviour. And in implementation you then can insert needed primefaces' component with some hardcoded attributes and some passed from your composite component invocation.
Consider this tutorial: https://docs.oracle.com/javaee/6/tutorial/doc/giqzr.html
Example
Composite component is resource, so we put it below /resources folder. Let's create subfolder /resources/myCompositeComponents and create xhtml file myCalendar.xhtml there. It will be our composite component. Basically, it is xhtml file with additional namespace xmlns:cc="http://java.sun.com/jsf/composite". Here is the code. You can notice two elements: <cc:interface> and <cc:implementation>. And <cc:attribute> element inside the <cc:interface> is the input of our composite component.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html">
<cc:interface>
<cc:attribute name="label" default="Decision Date"/>
</cc:interface>
<cc:implementation>
<h2>#{cc.clientId}</h2>
<h:outputLabel
id="Label"
value="#{cc.attrs.label}"/>
<p:calendar id="Calendar"
effect="explode"
yearRange="2000:2100"
pattern="MM/dd/yyyy"
navigator="true" display="inline"
value=""
label="Label"
maxlength="10"
size="20">
<f:convertDateTime pattern="MM/dd/yyyy" />
</p:calendar>
</cc:implementation>
</html>
Then, let's use it. To be able to declare our brand new component we will put additional namespace into the using page: xmlns:my="http://java.sun.com/jsf/composite/myCompositeComponents". The last part of the namespace uri corresponds to the folder under /resources, where composite component lives. Give it any prefix you like. Here is source code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:my="http://java.sun.com/jsf/composite/myCompositeComponents">
<h:head>
<title>Simple JSF Facelets page</title>
</h:head>
<h:body>
<my:myCalendar id="LetsUseIt" label="MyLabel"/>
</h:body>
</html>
Have a notice of attribute "label" - that very attribute, that is declared in the "interface" element.
This is quite basic usecase, though it will help in your situation. More complex scenarios include passing typed attributes and implementing backing component - java class, instantiated every time the component is used.

JSF2 EL html output

Background
I have an existing web application that relies on JSF2. In most pages, there are expressions that output text from various property files. Some properties might contain html. However, JSF expressions escape html into plain text. The solution I found was to use <h:outputText> with escape set to false. Using this would be cumbersome due to amount of expressions that would need to be wrapped.
Question
My question is, is there a way to configure all expressions to not escape html?
If I were you I would create my own composite component wich can be called In xhtml with
<myComponents:outputText value="<STRONG>the html taged value</STRONG>">
Simply add this custom component in a new xhtml file in the defaut jsf folder src/webapp/components.
Like :
src/webapp/components/myComponents/outputText.xhtml
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="value" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputText value="#{cc.attrs.value}" escape="false"/>
</cc:implementation>
</ui:composition>
Don't forget to add the folowwing namespace in your xhtml pages where the components are used xmlns:field="http://java.sun.com/jsf/composite/components/myComponents in the ui:composition tag
Hope this helps...

param reference to bean not being passed into composite component

i'm having a bit of trouble with a composite component in JSF 2.1 vanilla (on glassfish 3.1). the simplified version of my problem is here:
[composite component]
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="value" required="true"/>
<cc:attribute name="title" required="false" default=""/>
<cc:editableValueHolder name="inputTarget" targets="labeledInputField"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<p:inputText id="labeledInputField"
label="#{cc.attrs.title}"
value="#{cc.attrs.value}"
title="#{cc.attrs.title}">
<cc:insertChildren/>
</p:inputText>
</cc:implementation>
</html>
[implemented in]
<!-- thisPerson is passed in via ui:param to the facelet containing this code.
it works in other (non-composite) components on the page -->
<comp:labeledInputText
id="baseUsername"
value="#{controller.username}"
title="#{bundle.Username}">
<f:validator for="inputTarget" binding="#{thisPerson.usernameValidator}"/>
<f:converter for="inputTarget" converterId="#{whiteSpaceTrimConverter}"/>
</comp:labeledInputText>
the problem is, the "thisPerson.usernameValidator" is evaluating to NULL, which then causes the com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl to then skip to the code that attempts to load the validator by "validatorID" which is not set because we're trying to send in the validator by "binding". is there a way to get the composite to evaluate the ui:param value, or a workaround that does not require reworking the validator (it's a huge anti-pattern and i don't have time to reverse the damage right now). assume the validator HAS to come in via binding.
i know the composite works because in a different facelet, i have the validator binding against a concrete bean reference, rather than a "soft" reference, and it works like a champ.
TIA
Without knowing your exact JSF implementation, I am going to assume Mojarra, you may be running into the following known bug.
http://java.net/jira/browse/JAVASERVERFACES-2040
Regardless if this is your exact problem or not, you can try to disable partial state saving and see if this resolves your issue. If it does then that means that you are facing this issue, which apparently was (fixed?) in later versions of Mojarra.
Another possibility would be to simply use renderFacet instead of insertChildren and insert your validators in the form of a facet.

Resources