How to invoke a JSF composite within composite:implementation? - jsf-2

How could you invoke a JSF2 composite (widget) within anothers composite's implementation tag?
When I do so, I get the following error: /resources/widgets/tileContainer.xhtml #25,45 <mywidgets:tileContainer> Tag Library supports namespace: http://java.sun.com/jsf/composite/widgets, but no tag was defined for name: tileContainer
The code snippet is:
<composite:interface name="tileContainer">
<composite:attribute name="pubCategoryId" type="java.lang.Long" required="true" />
</composite:interface>
<composite:implementation>
<div class="tileContainer">
<ui:repeat value="#{pubController.getPubsByCategory(cc.attrs.pubCategoryId)}" var="pub">
#{pub.title}
<mywidgets:tileContainer title="Private">
<mywidgets:tileSmallPictureTitle
title="Bulk Dispatch Lapse stressed with application protocols">
</mywidgets:tileSmallPictureTitle>
</mywidgets:tileContainer>
</ui:repeat>
</div>
</composite:implementation>
Any other design recommendations on how to handle this?
Thank you for sharing your thoughts.

This is recognizable as Mojarra issue 2437 which was fixed in Mojarra 2.1.10 (released 25 july 2012). It look like you're using a rather outdated Mojarra version. It's currently already at 2.1.25 (2.2.x is even already out, but I wouldn't recommend switching to 2.2 right now, let them fix all childhood diseases first).

Okay, I moved the namespace declaration of my composite directory from the <html xmlns... tag down to the <composite:implementation> tag.
So the composite looks like this:
<composite:implementation xmlns:mywidgets="http://java.sun.com/jsf/composite/widgets">
Otherwise, the namespaces of the parent and child composite will resolve wrongly.

Related

Getting correct parent ID in composite components

For partial updating my composite components, I have some problems finding the correct parent IDs. e.g. if my component is inside of a tabView
<p:tabView id="foo">
<p:tab>
<stg:mycomponent id="bar" />
</p:tab>
</p:tabView>
Now I need the String :foo:bar to find the correct parts, that I want to update. Via #{cc.id} I just get bar, so this does not work for me.
However, I tried to achieve this by some kind of dirty hack by adding a attribute to my component like this
<composite:attribute
name="parentId"
default=":#{component.namingContainer.parent.namingContainer.clientId}"
/>
If I hand over the String :foo:bar to parentId everything works fine, but of course that's not what I really want to do. I do not want to force the user of my component to hand over this ID.
But now the problem: If I do not hand over a parentId, I only can use my attribute in the "first level" of my component. If there are some kind of "nested IDs" then #{cc.attrs.parentId} is evaluated e.g. to foo:bar (which is nice) but also foo:bar:fooBar or somethin like that, depending on where #{cc.attrs.parentId} is located in my code.
I hope it's comprehensible what my problem is and what I am exactly asking for. If not, please leave a comment.
I am using primefaces 3.5 and JSF 2.1 (Mojarra)
If I understand, you need to update parts of a composite component within the composite component itself. Normally you don't need to know the parents IDs to achieve this.
As you are setting id on a primefaces component, you can update it with primefaces using the same id (without any :container:etc prefix) as long as your update is in the same scope.
Here is an example (see source below).
Observe the generated id's in the HTML page produced by JSF in the first tab:
First span : id="static" (raw html id, not PF, not unique in the document)
Second span : id="myform:tv1:comp1:static2" (PF-generated to ensure id is unique in the document)
Third span : id="myform:tv1:comp1:dynamic" (PF-generated, unique)
poll component use the id "myform:tv1:comp1:dynamic", even if we only provide "dynamic" in the source.
The parents does not need to know the ID of the component part to be updated
The component does not need to know the IDs of its parents/containers
Please note generated IDs on the second tab. PrimeFaces does its job by naming them unique.
Sample composite component:
<composite:interface>
<composite:attribute name="label" />
</composite:interface>
<composite:implementation>
<h1><h:outputText value="#{cc.attrs.label}"/></h1>
<span id="static1">
Static : #{testBean.increment}
</span>
<p:outputPanel id="static2">
Static : #{testBean.increment}
</p:outputPanel>
<p:outputPanel id="dynamic">
Dynamic : #{testBean.increment}
</p:outputPanel>
<p:poll interval="3" update="dynamic" />
</composite:implementation>
Use the component in a XHTML page:
<h:form id="myform">
<p:tabView id="tv1" >
<p:tab id="tab1" title="First Tab">
<comps:myComponent id="comp1" label="Abc" />
</p:tab>
<p:tab id="tab2" title="Second Tab">
<comps:myComponent id="comp2" label="Def" />
</p:tab>
</p:tabView>
</h:form>
And this is the code for the test bean:
#ManagedBean(name="testBean")
public class TestBean implements Serializable
{
static int _counter = 0;
public String getIncrement()
{
_counter++;
return Integer.toString(_counter);
}
}
I hope this example will be clear enough and close to what you want to get.
Please let me know.

Calendar popup of Richfaces or Primefaces not working

I have added richfaces 4.3.0 jars in my project and also tried with primefaces3.4.2 in netbeans 7.2.1
I am trying to use calendar component in my project but when I am using richfaces or primefaces calendar popup doesn't appear and it remains and it is or its not giving any error
I have used the following code in my .xhtml file
<rich:calendar id="givenDate" enableManualInput="true" style="width:60px" datePattern="MM/dd/yyyy" value="#{NewClass.ts}" immediate = "true" required="true" popup="true" />
In the java bean I have used the variable of java.util.Date type with getter and setter method.
Can Anybody please point me what I am doing wrong.
Solved:-
I forgot to add h:head tag in xhtml page thats why neither richfaces not primefaces was working.
Primefaces calendar width change size tag
<p:calendar size="7" />

Primefaces outputLabel for composite component

I have an issue with using p:outputLabel when used with composite component. I have composite component with p:inputText field (I removed irrelevant parts from component):
<cc:interface>
<cc:editableValueHolder name="myInput" targets="myInput"/>
<cc:attribute name="required" required="true" type="java.lang.Boolean" default="false"/>
</cc:interface>
<cc:implementation>
<p:inputText id="myInput" required="#{cc.attrs.required}"/>
</cc:implementation>
Now, I wont to use this component with p:outputLabel:
<p:outputLabel for="myComponent:myInput" value="#{resources['myLabel']}:"/>
<my:myComponent id="myComponent" required="#{myBean.required}"/>
Everything works fine, required validation, message is displayed as well, but there is no * sign on label, as there is when I connect label directly to p:inputText component. If I, on the other hand, hardcode required="true" on p:inputText everything works fine.
I debugged through org.primefaces.component.outputlabel.OutputLabelRenderer and discovered that component is recognized as UIInput, but input.isRequired() returns false. Farther debugging discovered that required attribute isn't yet defined on component, so it returns false as default value i UIInput:
(Boolean) getStateHelper().eval(PropertyKeys.required, false);
Also, if I just move p:outputLabel inside composite component everything works fine. Like EL is evaluated later inside composite component?
I'm using Primefaces 3.5 with Mojarra 2.1.14
This is, unfortunately, "by design". The evaluation of the #{} expressions is deferred to the exact moment of the access-time. They're unlike "standard" EL ${} in JSP not evaluated at the exact moment they're been parsed by the tag handler and "cached" for future access during the same request/view. At the moment the <p:outputLabel> is rendered, and thus the #{cc.attrs.required} as referenced by UIInput#isRequired() needs to be evaluated, there's no means of any #{cc} in the EL context. So any of its attributes would not evaluate to anything. Only when you're sitting inside the <cc:implementation>, the #{cc} is available in the EL context and all of its attribues would thus successfully evaluate.
Technically, this is an unfortunate corner case oversight in the design of <p:outputLabel>. Standard JSF and EL are namely behaving as specified. Basically, the presentation of the label's asterisk depending on the input's required attribute should be evaluated the other way round: at the moment the <p:inputText> inside the composite is to be rendered or perhaps even already when it's to be built. Thus, the label component should not ask the input component if it's required, but the input component should somehow notify the label component that it's required. This is in turn hard and clumsy (and thus inefficient) to implement.
If moving the label to inside the composite is not an option, then your best bet is to create a tag file instead of a composite component around the input component. It only requires some additional XML boilerplate.
/WEB-INF/tags/input.xhtml:
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui"
>
<c:set var="id" value="#{not empty id ? id : 'myInput'}" />
<c:set var="required" value="#{not empty required and required}" />
<p:inputText id="#{id}" required="#{required}"/>
</ui:composition>
/WEB-INF/my.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0"
>
<namespace>http://example.com/my</namespace>
<tag>
<tag-name>input</tag-name>
<source>tags/input.xhtml</source>
</tag>
</facelet-taglib>
/WEB-INF/web.xml:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
Usage:
<html ... xmlns:my="http://example.com/my">
...
<p:outputLabel for="myInput" value="#{resources['myLabel']}:" />
<my:input id="myInput" required="#{myBean.required}" />
I just did a quick test and it works fine for me.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?

Composite component parameter does not evaluate when it is a ui:repeat var attribute

I have a composite component that takes a specific object type as its value attribute. It looks like this:
<cc:interface>
<cc:attribute name="value"
type="com.myapp.Tally"
required="true"
</cc:interface>
The component merely produces a h:panelGrid with data elements from the object.
I have never had trouble with it until I tried using it inside a ui:repeat structure like this:
<ui:repeat value="#{myApp.tallyList}" var="tally">
<p>
<qc:tallySummaryH value="#{tally}" />
</p>
</ui:repeat>
When this page is requested, it throws an exception:
javax.faces.view.facelets.TagException: /table.xhtml #86,66 <qc:tallySummaryH> The following attribute(s) are required, but no values have been supplied for them: value.
at com.sun.faces.facelets.tag.composite.InterfaceHandler.validateComponent(InterfaceHandler.java:233)
at com.sun.faces.facelets.tag.composite.InterfaceHandler.apply(InterfaceHandler.java:125)
at javax.faces.view.facelets.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:98)
at com.sun.faces.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:93)
at com.sun.faces.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:86)
at com.sun.faces.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:152)
at com.sun.faces.facelets.tag.jsf.CompositeComponentTagHandler.applyCompositeComponent(CompositeComponentTagHandler.java:349)
Other references to #{tally} inside the ui:repeat loop do not have any problem. They operate as expected. Is this a Mojarra bug or is there something in the JSF specification I didn't understand?
This is on Mojarra 2.1.0 (FCS 2.1.0-b11) in GlassFish 3.1.1
This is related to a bug which was fixed in Mojarra 2.1.1. Consider upgrading. I believe it's (in)directly the result of the visit hint fixes as mentioned in this overview of issues fixed in Mojarra 2.1.1.

JSF 2.0 Warning about a component not surronded by an h:form tag [duplicate]

I am getting the following error on my Facelet page, which simply consists of an IceFaces form with two fields and two buttons:
The form component needs to have a UIForm in its ancestry. Suggestion: enclose the necessary components within <h:form>
Here is the form:
<ice:form id="form1" partialSubmit="false">
<ice:panelLayout id="panelLayout3">
<ice:graphicImage id="graphicImage1" url="/resources/images/LoginImage.jpg" width="560" />
<ice:outputLabel for="j_username" id="outputLabel1" value="Username:"/>
<ice:outputLabel for="j_password" id="outputLabel2" value="Password:"/>
<ice:inputText binding="#{login.username}" id="j_username" required="true" />
<ice:inputSecret binding="#{login.password}" id="j_password" required="true" />
<ice:commandButton actionListener="#{login.login}" id="loginBtn" value="Login"/>
<ice:commandButton action="#{login.reset}" id="resetBtn" value="Reset"/>
<ice:outputText id="errorMessage" />
<ice:message errorClass="errorMessage" for="j_username" fatalClass="fatalMessage" id="messages1" infoClass="infoMessage" showSummary="false" warnClass="warnMessage"/>
</ice:panelLayout>
</ice:form>
How is this caused and how can I solve it?
This is not an error. This is a warning. The code looks fine, all input components are inside a form, it seems that it should run and work fine. If it indeed works fine, just ignore the warning. This warning is displayed only when the context parameter javax.faces.PROJECT_STAGE is set to Development anyway .
As to the false warning message itself, this check was introduced in Mojarra 2.1.1 as per issue 1663. However, as per issue 2147 it turns out to have some bugs and is been further improved in Mojarra 2.1.3. I'd imagine that the false warning is in your particular case caused by having an <ice:panelLayout> between the form and the input elements.
If you aren't on Mojarra 2.1.3 yet, you may want to consider upgrading to see if it removes the false warning message.

Resources