facelets ui:fragment ignores rendered attribute - jsf

i'm having a very strange behaviour with this piece of code:
<ui:fragment rendered="#{price.guestIdTrue}">
<b>PRICE_GUEST_ID_TRUE : #{price.guestIdTrue}</b>
<h:outputText>#{Global.guestTypeMap[price.guestId]} #{price.guestIndex}</h:outputText>
</ui:fragment>
Even when the rendered condition is false, the
PRICE_GUEST_ID_TRUE : false 1
1 is the #{price.guestIndex}
The ui namespace is correctly defined, and it works on others facelets.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:t="http://myfaces.apache.org/tomahawk">
Any Ideas of what happens.
Thanks in advance.

You seem to be using <ui:fragment> inside an iterating tag/component where the #{price} is actually the currently iterated variable, such as the JSTL <c:forEach> tag, or the JSF <h:dataTable> or <ui:repeat> component while using an early version of Mojarra. In those situations, the #{price} is not available in EL scope at the point it's been evaluated.
You need the <h:panelGroup rendered> instead or to upgrade the Mojarra version to the latest.

Related

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

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

RichFaces a4j:commandButton oncomplete

Hi i have this demo form with RF 4.5.2, the oncomplete execute 3 times, i need a way to execute a method after the ajax call but only one time, i think that is the behaviour of the oncomplete but if it doesnt you can suggest any other ideas to accomplish this:
<!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:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head></h:head>
<body>
<rich:panel>
<h:form>
<a4j:commandButton id="btnAccion" value="enviar" oncomplete="#{archivoAfipController.emptyAction()}"/>
</h:form>
</rich:panel>
</body>
</html>
You're supposed to use the action attribute for the purpose of invoking a managed bean method on submit.
<a4j:commandButton ... action="#{archivoAfipController.emptyAction}" />
The oncomplete must represent a client side script expression (thus, e.g. JavaScript, which is in JSF perspective basically a plain vanilla String!), which should be executed when the ajax action has completed, the response has returned, and all necessary parts of the view have been updated in the client side.
See also:
<a4j:commandButton> tag documentation
https://stackoverflow.com/a/20146879/ (only second half of the answer is relevant)

Passing data to a JSF facelet

On the 1st page that is displayed in my JSF application, I want to display data from a database in the form of a table. I have a ManagedBean called a ProductList which has an ArrayList of Product Objects, and I want to put all the Products in a table. I am using the jstl c:forEach tags, but for some reason I get a compile error:
Fatal Error: The prefix "c" for element "c:forEach" is not bound.
Am I using the forEach tag correctly?
<c:forEach items="#{productList.allProducts}" var="product">
</c:forEach>
Here are the namespace tags:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
You must define all the namespaces(the h:, f:prefixes of your xml tags) that you use in the page.
The proper definition for xmlns:c is xmlns:c="http://java.sun.com/jsp/jstl/core"
You can have a longer example here: <c:if test> seems to always evaluate true in JSF2 Facelets

Unable to understand <h:head> behaviour

I have a template composition Button.xhtml which contains a <p:commandLink>:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<p:commandLink value="View" action="#{printClass.printPdf}"/>
</ui:composition>
The link's purpose is to generate PDF.
I have a template client defaultPage.xhtml where the Button.xhtml is been included.
<ui:composition template="../../WebPages/MasterPage/Template.xhtml">
<ui:define name="MainContent">
<ui:include src="../../WebPages/Facelets/Button.xhtml"/>
</ui:define>
</ui:composition>
The last one is Template.xhtml which inserts the MainContent template definition inside a <h:form>.
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<ui:insert name="MainContent" />
</h:form>
</h:body>
</html>
When I place <h:head></h:head> in Template.xhtml, then the <p:commandLink> in Button.xhtml stops working, but CSS of page works perfect. When I remove the <h:head></h:head> or replace it by <head></head> then the <p:commandLink> starts working, but CSS stops working.
How is this caused and how can I solve it?
The <h:head> will auto-include all necessary JavaScript files for ajax behavior and CSS files for layout. When you remove it, then CSS will not be auto-included and ajax behavior will not be enabled. The <p:commandLink> would then act like as a plain vanilla link.
The <h:head> is absolutely necessary for proper functioning of JSF and PrimeFaces components and applying of the PrimeFaces look'n'feel. So you should not remove or replace it.
Let's concentrate on the problem of the failing <p:commandLink>. There are relatively a lot of possible causes, which are all mentioned in this answer: commandButton/commandLink/ajax action/listener method not invoked or input value not updated
You didn't show a fullworthy SSCCE, so it's impossible to copy'n'paste'n'run your code to see the problem ourselves (work on that as well in your future questions). So, I'll just mention the most probable cause for this problem based on the symptoms: you're nesting <h:form> components in each other. Placing the <h:form> in the master template is also a design smell. You should rather place it in the template client. Als note that the <p:dialog> should have its own form but that the <p:dialog> should by itself not be nested in another form.
Update: based on the comments, you're trying to return a whole PDF file as a response to an ajax request. This will indeed not work. The ajax engine expects a XML response with information about changes in the HTML DOM tree. A PDF file isn't valid information. Also, JavaScript has for obvious security reasons no facilities to programmatically trigger a Save As dialogue whereby possibly arbitrary content is provided.
You can't download files by ajax. You have to turn off ajax. In case of <p:commandLink> there are basically 2 solutions:
Use ajax="false".
<p:commandLink ... ajax="false" />
Just use <h:commandLink> instead.
<h:commandLink ... />
In Button.xhtml where you placed
<h:commandLink value="View" action="#{printClass.printPdf}"/>
You need to disable the ajax.So your new code should be like
<h:commandLink value="View" action="#{printClass.printPdf}">
<f:ajax disabled="true"></f:ajax>
</h:commandLink>

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