How can you access the second level parent composite component in a hierarchy of nested CCs? - jsf

In jsf difference between implicit objects cc and component it says:
cc refers to the top level composite component that is being processed at the time of evaluation.
In a hierarchy of nested composite components, how would I access say the second level parent?

Composite components are inherently naming containers. You can get the namingcontainer's parent as follows:
#{cc.namingContainer.parent}
And its namingcontainer parent as follows:
#{cc.namingContainer.parent.namingContainer.parent}
Etc.

Related

What's the difference between #{cc.foo} and #{cc.attrs.foo}?

I'm trying to add something to a composite component somebody else created and there is a #{cc.foo} in there. I can't seem to find where foo is defined, even doing a grep over the entire codebase.
What's the difference between cc.attrs.foo and cc.foo in general?
EDIT I found it in some jar, therefore I didn't see it in the search. Still the question generally remains. Thanks
What exactly is foo? Composite components (as other UIComponents) have certain properties predefined: for example, #{cc.rendered} or #{cc.clientId} are defined by the Java EE spec, not the user, so they are always available within composite components.
In general, #{cc.whatever} will be properties of the component itself: its component ID #{cc.id}, its client ID (i.e. what's rendered as the id attribute of the HTML tag) #{cc.clientID}, its parent component #{cc.parent}, etc. These are provided by Java EE. On the other hand, #{cc.attrs.whatever} are provided by the component developer: they will be the named attributes of the composite component: for each <composite:attribute name="myAttribute" ... /> in the <composite:interface> section of the composite component file, there will be a #{cc.attrs.myAttribute} available to use in the <composite:implmenentation> section of the composte component file.

How do I bind a composite component in JSF?

I have a composite component which is composed of other composite components. Now I would like to render only some of the child components within the parent component. From the Java EE tutorial I take it that I should probably bind my child components to some property of the backing bean for my parent component so that I can access their render attribute.
However, the NetBeans IDE does not know about a binding attribute for my composite components. So how am I supposed to do this?
Use case: The parent component is some wizard which should display only one of the child components at a time. Think of it as a poor man's tabbed view. I know there are libraries which provide ready-made components for this, but I do not want to add another dependency.
Netbeans is lying. That attribute is definitely supported on <ui:component>. Just use it and ignore the warning/error in the IDE. Or better, just use the rendered attribute; the need to conditionally render components is not a valid reason to prefer binding over rendered.

What is the purpose of a <af:declarativeComponent>?

I have been through this documentation on ADF declarative component but not still not clear on the intent of such a component . I want to know what is the use of this guy and what are the scenarios where such a component could become useful ? Is this related to ui:composition in JSF2.0 ?
af:declarativeComponent defines a dynamic declarative component and is used in ADF as a light weight form of encapsulating some UI logic. Think of it not as a template, but as a component that one can define without declaring a tag name (as for regular declarative components) and much lighter then a task-flow. When used you can pass parameters to such a component (including methods parameters since ADF 11.1.2). Such a component can also have a backing bean which executes in backing bean scope, so that if you have multiple instances of this component in a page you will have as many corresponding instances of the backing bean at the run-time, so the logic executed there will not interfere from one instance to another.
ADF Declarative component is composite component created using predefined ADF Faces components. It can be included in a packaged jar file and can be included in any ADF Pages or Page Fragments as a reusable component.
Example: Create a declarative component for user login
User Name [ af:InputText ]
Passwork [ af:InputText ]
SubmitButton
This component can be included in the login page in any application

How do I access the current TreeNode in primefaces tree (in mark-up or programmatically) without binding to UI component in managed bean?

I am using Primefaces 3.4.1 with the 2.2.0-m05 milestone build of Oracle's JSF 2.2 implementation. I am also using Spring 3.1 for dependency injection and some AOP.
I am trying to use the Primefaces tree component to display a composite of logical filter rules (and allow the user to create composite/leaf nodes at any depth within the composite structure).
Example composite filter:
((location = 'cal') AND (description contains 'test')) OR (project = 'someProject')
Example tree markup:
<p:tree value="#{form.rootComponent}" var="filterComponent" animate="true">
<p:treeNode type="composite">
<!-- some composite specific components -->
</p:treeNode>
<p:treeNode type="leaf">
<!-- some leaf specific components -->
</p:treeNode>
</p:tree>
Although the "value" attribute on the element accepts the root TreeNode (retrieved from a managed bean), the "var" attribute points to the actual data present in the current tree node, rather than the node itself. I would like a way to access the current tree node, not its wrapped data, either in mark-up or programmatically.
If I can access it in mark-up, I can pass it as a method argument to a managed bean. If there's no way of accessing it in the mark-up, can I gain direct programmatic access through a model object? (presumably by gaining access to the underlying tree model?).
I know you can use an expression which resolves to an underlying DataModel instead of the data collection directly as the "value" of h:dataTable, but I believe you can only use the root node itself with p:tree.
I could include a reference to the tree node in the wrapped data object, but I'd really rather avoid nasty circular references if at all possible.
In the absence of a better alternative, I tried using the "binding" attribute to bind the p:tree element directly to a Tree instance in the managed bean (Tree being the UIComponent class for p:tree), which allows me to access the current node via the getTreeNode() method, but I would prefer to avoid this given the lifecycle mismatch between managed beans and view components. It is not working perfectly as is, and I assume there must be a much better, simpler solution.
I also tried using a jsf data table - with nested data tables to handle the composite part - but decided against it given the difficulty in creating a conditionally recursive structure within jsf markup (I believe the "rendered" attribute is not evaluated at view build time so it's difficult to avoid infinite recursion).
Just to clarify, I am only interested in the current tree node containing the data referred to by "var", not the node currently selected by the user.
PF Lead just added a new attribute called "nodeVar" for the p:treeTable (dunno if p:tree is included) as in PF 5.1.10 / 5.2. This feature will allow to get a hold of the actual TreeNode instead of it's data. Hence, one can now perform extra method calls on the node itself, such as TreeNode.isLeaf().
Well, there is an attribute called "selection" in the tree component. You just need to provide a reference to the managed bean method.
For e.g., in your xhtml define the attribute the following way:
selection="#{myManagedBean.selectedNode}"
And with the definition of the above attribute, you will have to provide the usual setter and getter methods in the managed bean that references to org.primefaces.model.TreeNode instance.

How to access a composite component's sibling via clientId

I have a composite component that bundles some input fields. The component will be used multiple times on a page and contains a button to copy the values of another of these components. For this I would need to access one of those siblings via its clientId as a target for an
<f:ajax execute=":XXX:siblingId" render="...">
My problem lies in constructing this ID. I have the name of the sibling and I can make sure that it is located in the same naming container as the component that contains the copy button, but I can't control the complete nesting hierarchy, so it might be :form:foo:bar:parent:child or just form:parent:child. So essentially I would want to get the prefix of the current composite component, but without the component's own ID and then attach the ID of the component from which to copy.
This is similar to these questions:
How to address the surrounding naming container in jsf
How to access the parent naming container of composite
However, both answers make use of PrimeFaces-sepcific features like #parent and widgetVar, which does not apply to my project.
When experimenting with EL's implicit objects I basically tried the same things as the poster of the second question - with the same results: cc.parent.clientId is always empty. I also tried cc.namingContainer.clientId and some combinations of the two, alas - no success. Especially the fact that parent does not work as expected confuses me...
So: Is there a component-library-agnostic way to access the "path" of containing naming containers for a composite component? How is the parent object supposed to work, especially: when can we use it and when not?
PS: I was thinking about using the composite's full clientId and then trimming its actual ID with fn:split, however, if there was a more direct way I'd be happy to use it.
The #{cc.parent} resolves to UIComponent#getCompositeComponentParent() which returns the closest parent composite component. In other words, it returns only non-null when the composite component is by itself nested in another composite component.
The #{cc.namingContainer} simply refers to #{cc} itself, fully conform as specified in UIComponent#getNamingContainer():
Starting with "this", return the closest component in the ancestry that is a NamingContainer or null if none can be found.
Composite components namely implicitly implement NamingContainer themselves.
So your attempts unfortunately won't work. I also do not see any "standard API" ways to achieve the concrete functional requirement. The CompositeComponentAttributesELResolver causes that the #{cc.parent} doesn't resolve to UIComponent#getParent() which is what you ultimately want.
You can however provide a custom UIComponent implementation for the composite which adds an extra getter with an unique name which in turn properly delegates to UIComponent#getParent().
Here's a kickoff example:
#FacesComponent("myComposite")
public class MyComposite extends UINamingContainer {
public UIComponent getParentComponent() {
return super.getParent();
}
}
If you register it as follows in the composite interface:
<cc:interface componentType="myComposite">
then you'll be able to use
#{cc.parentComponent.clientId}
to get the client ID of the real parent UIComponent.
Ultimately you should be able to use the following construct to refer the sibling:
process=":#{cc.parentComponent.clientId}:siblingId"

Resources