stg
stg

Reputation: 2797

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)

Upvotes: 4

Views: 2390

Answers (1)

Stephane Lallemagne
Stephane Lallemagne

Reputation: 1256

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.

Upvotes: 2

Related Questions