3

I have the following simple code in a composite component (using Mojarra 2.3.9 / Primefaces 7):

<composite:implementation>
    <h:form id="form">
            <composite:insertChildren />

            <ui:fragment rendered="#{!empty cc.facets.actions}">
                <div class="actions">
                    <composite:renderFacet name="actions" />
                </div>
            </ui:fragment>
        </div>
    </h:form>
</composite:implementation>

And the following part is used in a page, trying to fill the composite form with life:

<cc:compForm id="mySpecialForm">
    <f:facet name="actions">
        <p:commandButton
                id="myBtn"
                value="Submit"
                process="@form"
                update="@form">
        </p:commandButton>
    </f:facet>
</cc:compForm>

The form and all the children are rendered correctly and working quite well. But the button in the renderFacet block has - in my opinion - a wrong client ID, because instead of:

mySpecialForm:form:myBtn

the button only gets the following clientId:

mySpecialForm:myBtn

This leads to an error rendering the page:

Cannot find component for expression "@form" referenced from "mySpecialForm:myBtn".: org.primefaces.expression.ComponentNotFoundException: Cannot find component for expression "@form" referenced from "mySpecialForm:myBtn".

Am i doing something wrong or is this a bug in JSF/Primefaces? I also tried to configure the componentType to an @FacesComponent extending from UIForm, but in this case no form will be rendered at all.

Update 1:

I tried to create a "minimal, reproducible example (reprex)" like mentioned by Kukeltje. All what is needed are those 2 Parts in a web application (both files under resources):

cc/compForm.xhtml:

<html
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:composite="http://xmlns.jcp.org/jsf/composite">

    <composite:interface name="compForm" displayName="A composite form">
        <composite:facet name="actions" />
    </composite:interface>

    <composite:implementation>
        <h:form id="form">
            <composite:insertChildren />
            <composite:renderFacet name="actions" />
        </h:form>
    </composite:implementation>
</html>

compFormTest.xhtml:

<html
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://xmlns.jcp.org/jsf/html"
        xmlns:f="http://xmlns.jcp.org/jsf/core"
        xmlns:cc="http://xmlns.jcp.org/jsf/composite/cc">
    <cc:compForm id="mySpecialForm">
        <h:inputText id="inputParam" value="" />

        <f:facet name="actions">
            <h:commandButton id="myBtn" value="Test" />
        </f:facet>
    </cc:compForm>
</html>

All todo is call the .xhtml page: http:localhost/YOUR_APP/compFormTest.xhtml.

After using it (at least with Mojarra JSF implementation), the input field has the following correct client ID mySpecialForm:form:inputParam. But the command button retrieves another client ID outside the form: mySpecialForm:myBtn, what is a bug from my point of view, regarding the JSF VDL: " ... will be rendered at this point in the composite component VDL view.".

But as i downstriped the example files, it is clearly not a primefaces problem, because the wrong client ID is also included, if using the standard h:commandButton component.

Perhaps someone can use the mentioned 2 files above in a MyFaces environment to check if the behaviour differs or is the same?

Or has someone a workaround in mind? Using an additional @FacesComponent and moving the button from facet to the right spot under the form leads to the following "funny" duplicate ID error:

"Cannot add the same component twice: mySpecialForm:form:myBtn" (at least the client ID was what i expected in the first place)

Daniel K.
  • 41
  • 5
  • 1
    Can you check how the component hierarchy is rendered in the DOM? – tandraschko Mar 24 '20 at 17:38
  • The DOM tree looks like expected. The button is beneath the form in the rendered HTML page: div (outside cc) --> form --> div (actions) --> button The HTML form has the right client ID "mySpecialForm:form". Also the rendered input fields (insertChildren) have the expected client IDs. If i move the button from facet directly under the composite component tag in page, it is also working. But in this case i have to copy'n'paste the actions DIV over and over again :( – Daniel K. Mar 24 '20 at 18:28
  • 1
    Can you try what happens in MyFaces? Such cases are interpreted different in MyFaces and Mojarra. Also not sure what is the correct behavior, we would need to check the specs and spec issues. – tandraschko Mar 24 '20 at 18:33
  • I tried, but it is really hard to install MyFaces in a WildFly environement :( – Daniel K. Mar 24 '20 at 19:17
  • Then download TomEE? Might be simpler if you have a [mcve]. Or try a simple servlet engine? Unfortunately I'm also primarily using wildfly, otherwise I'd give it a go. – Kukeltje Mar 24 '20 at 19:38
  • Can you give me a hint howto use MyFaces in Wildfly 18? I tried with multi-jsf-installer (failure on deployment) and than bundled myfaces 2.3.1 with my WAR. But Wildfly still using own Mojarra implementation :(( – Daniel K. Mar 24 '20 at 19:48
  • Sorry, no, other than the tool you refer to or searching for in stackoverflow on how to do that manually I have no idea. When I needed to try something with MyFaces to see if there was a difference with Mojarra (in Wildfly), I used TomEE. With a simple war that worked file for me. – Kukeltje Mar 24 '20 at 20:06
  • s/file/fine/g ! – Kukeltje Mar 24 '20 at 20:21
  • Could https://stackoverflow.com/questions/46171478/children-component-does-not-contain-id-parent-in-facet be effectively a duplicate? In the sense of it being the same issue? Not a solution? – Kukeltje Mar 30 '20 at 18:58
  • 1
    and https://stackoverflow.com/questions/31996021/why-does-a-commandlink-within-a-facet-within-a-composite-component-renders-an-er ? – Kukeltje Mar 30 '20 at 19:03
  • Heeeee, wait.... The last link is a post by you too. You did not have a deja-vu when posting this question? At least the answer is – Kukeltje Mar 30 '20 at 19:04
  • First, yes. But on the second look it is another kind of problem/bug. The link you mentioned is about primefaces with two facets (paginator rendered twice) sharing the same ID. My current problem is much more generic, because it depends on only one facet in JSF not primefaces. And the problem is not duplicate ID - it is wrong client ID and unusable button, because @form also is not working in the facet of a composite component. Woops, the second post is really a duplicate .... should i delete this one? – Daniel K. Mar 30 '20 at 19:14
  • Seems to be fully duplicate but there is a small thing that is unclear to me. The commandLink vs commandButton. Button seems to be working in the other case, link not... strange... Leave it for now. I'll see if I can try a small case in TomEE somehwere the coming days' – Kukeltje Mar 30 '20 at 19:49
  • Thanks for your time and comments. Perhaps i should just open an issue for mojarra on github. But not today, perhaps tomorrow :) – Daniel K. Mar 30 '20 at 19:53
  • What if you put an input in the facet? Does that get the right id? – Kukeltje Mar 30 '20 at 22:56
  • It is the same for inputText. My guess, they first create the client IDs and then move the facet to the right spot. – Daniel K. Mar 31 '20 at 09:59

1 Answers1

0

Please check your <h:form id="form"> in your implementation. Most likely this is causing issues with duplicate form ID.

You might try defining an "id" atribute in your component

<composite:interface>
    <composite:attribute name="id" required="true" />
</composite:interface>

Inside your component, use the defined ID this way:

<h:form id="#{cc.attrs.id}">

Finally, define the id atribute in the client view:

<yournamespace:yourComponent id="myFormId" />

This way you can derive additional IDs fro the id attribute, eliminating the form id duplication.