Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

malformedXML: During update: adminUsersForm not found

I'm having some doubts about ajax on JSF.

My xhtml looks like this:

<h:body>
<h:form id="menuForm">
    <h:outputLabel for="menu">Available actions: </h:outputLabel>
    <h:selectOneMenu id="menu" value="#{menu.mainMenuItem}">
        <f:selectItem itemLabel="Select an option..." itemValue="null" />
        <f:selectItems value="#{menu.mainMenuItems}" />
        <f:ajax render=":menuForm :adminUsersForm :loadInfoForm :viewFilesForm" />
        <!-- <f:ajax render="@all" /> -->
    </h:selectOneMenu>
</h:form>

<h:form id="adminUsersForm"
    rendered="#{menu.mainMenuItem == 'Admin users.'}">
    <h:commandButton value="Button 1" />
</h:form>

<h:form id="loadInfoForm"
    rendered="#{menu.mainMenuItem == 'Load info.'}">
    <h:commandButton value="Button 2" />
</h:form>

<h:form id="viewFilesForm"
    rendered="#{menu.mainMenuItem == 'View files.'}">
    <h:commandButton value="Button 3" />
</h:form>
</h:body>

When I use <f:ajax render=":menuForm :adminUsersForm :loadInfoForm :viewFilesForm" /> I get the malformedXML error, on the other hand when I use <f:ajax render="@all" /> the correct <h:form>is rendering.

Whats happening in here? I read that using ajax we can render components just inside the same form, but if we use the :componentID it is possible to render -using ajax- components outside a form.

Thanks in advance, and maybe it's a basic question but I'm very new to JSF and trying to learn.

like image 264
BRabbit27 Avatar asked Nov 15 '11 03:11

BRabbit27


1 Answers

The <f:ajax render> should point to client IDs which is always present in the JSF-generated HTML DOM tree. This is mandatory because it's JavaScript in the client side which needs to update the HTML DOM tree. However, you're pointing it to client IDs which are not present in the HTML DOM tree because they are not been rendered by JSF.

You need to put those elements with a rendered attribute in a parent component which is always present in the JSF-generated HTML DOM tree.

Here is one way:

<h:form id="menuForm">
    <h:outputLabel for="menu">Available actions: </h:outputLabel>
    <h:selectOneMenu id="menu" value="#{menu.mainMenuItem}">
        <f:selectItem itemLabel="Select an option..." itemValue="null" />
        <f:selectItems value="#{menu.mainMenuItems}" />
        <f:ajax render=":menuForm :adminUsers :loadInfo :viewFiles :adminUsersForm :loadInfoForm :viewFilesForm" />
    </h:selectOneMenu>
</h:form>

<h:panelGroup id="adminUsers">
    <h:form id="adminUsersForm" rendered="#{menu.mainMenuItem == 'Admin users.'}">
        <h:commandButton value="Button 1" />
    </h:form>
</h:panelGroup>

<h:panelGroup id="loadInfo">
    <h:form id="loadInfoForm" rendered="#{menu.mainMenuItem == 'Load info.'}">
        <h:commandButton value="Button 2" />
    </h:form>
</h:panelGroup>

<h:panelGroup id="viewFiles">
    <h:form id="viewFilesForm" rendered="#{menu.mainMenuItem == 'View files.'}">
        <h:commandButton value="Button 3" />
    </h:form>
</h:panelGroup>

Here is another way (which I recommend more if there's actually no to-be-updated content between the forms):

<h:form id="menuForm">
    <h:outputLabel for="menu">Available actions: </h:outputLabel>
    <h:selectOneMenu id="menu" value="#{menu.mainMenuItem}">
        <f:selectItem itemLabel="Select an option..." itemValue="null" />
        <f:selectItems value="#{menu.mainMenuItems}" />
        <f:ajax render=":menuForm :otherForms :adminUsersForm :loadInfoForm :viewFilesForm" />
    </h:selectOneMenu>
</h:form>

<h:panelGroup id="otherForms">
    <h:form id="adminUsersForm" rendered="#{menu.mainMenuItem == 'Admin users.'}">
        <h:commandButton value="Button 1" />
    </h:form>

    <h:form id="loadInfoForm" rendered="#{menu.mainMenuItem == 'Load info.'}">
        <h:commandButton value="Button 2" />
    </h:form>

    <h:form id="viewFilesForm" rendered="#{menu.mainMenuItem == 'View files.'}">
        <h:commandButton value="Button 3" />
    </h:form>
</h:panelGroup>

Note that in the both ways I've included the IDs of all other forms in the render as well. This is to workaround a bug in JSF Ajax JavaScript (which is to be fixed in JSF 2.2). For a detailed explanation, see also Ajax rendering of content which contains another form.

like image 55
BalusC Avatar answered Nov 15 '22 21:11

BalusC