2

I am using <p:commandButton> tag with update attribute and passing current element ID in update attribute as currentForm: messages. something like: update="currentForm: messages". Where messages is the id of <div> element which I want to update after request call.

This is working fine.

Now I created a composite component with the same command button as we have in main template and replaces that PrimeFaces command button with created custom command button. (for now no any custom changes made in created command button just prime faces command button in this)

When I rendered the template it is complaining me about the ID given update attribute error given as:

javax.faces.FacesException: Cannot find component with expression "currentForm

and if I give full element ID path for this element it works again.

Although it is good if we give full element ID path to the element, but it surprise me why it is working when I am calling direct PrimeFaces command button ?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Varun
  • 95
  • 7

1 Answers1

2

That's because composite components are like <h:form>, <h:dataTable>, etc also naming containers. Their effect on ajax client IDs is outlined in this related question: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".

This is done so because you otherwise run into "duplicate component ID" errors on composite component's implementation when reusing the composite component more than once in the same naming container parent. See also this related question: Should a composite component really require namingcontainer interface?

If you're absolutely positive that the composite component is the right solution for the concrete requirement and thus not a tagfile (a lot of starters namely overuse composite components due to their zero-configuration nature, while it should really best only be used if you intend to bind a single model property to a bunch of closely related components), then you may consider the following alternative ways to update the messages component:

  1. Either dynamically pass the target client ID:

    <my:compositeButton ... update=":#{messages.clientId}" />
    ...
    <p:messages binding="#{messages}" ... />
    

    (note: the code is as is; you don't need to bind it to a bean property or so!)

  2. Or just let PrimeFaces auto-update the messages component on every ajax request:

    <my:compositeButton ... />
    ...
    <p:messages autoUpdate="true" ... />
    
Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555