2011-11-15 21 views
6

Tengo algunas dudas sobre ajax en JSF.malformadoXML: Durante la actualización: adminUsersForm no encontrado

Mi XHTML se ve así:

<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> 

Cuando uso <f:ajax render=":menuForm :adminUsersForm :loadInfoForm :viewFilesForm" /> consigo el error malformedXML, por el contrario cuando uso <f:ajax render="@all" /> la correcta <h:form> está prestando.

¿Qué está pasando aquí? Leí que usando ajax podemos representar los componentes solo dentro del mismo formulario, pero si usamos el :componentID es posible representar -usando ajax- componentes fuera de un formulario.

Gracias de antemano, y tal vez es una pregunta básica, pero soy muy nuevo en JSF e intento aprender.

Respuesta

13

El <f:ajax render> debe apuntar a los ID de cliente que es siempre presentes en el árbol DOM HTML generado por JSF. Esto es obligatorio porque es JavaScript en el lado del cliente que necesita actualizar el árbol DOM HTML. Sin embargo, lo está señalando a los ID de cliente que son no presentes en el árbol DOM HTML porque no se han procesado por JSF.

Debe colocar esos elementos con un atributo rendered en un componente primario que es siempre presente en el árbol DOM HTML generado por JSF.

Aquí es una manera:

<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> 

Aquí es otra manera (que recomiendo más si hay realmente no-a-ser-actualizado el contenido entre las formas):

<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> 

Nótese que en las dos formas en que he incluido las identificaciones de todos los demás formularios en el render también. Esto es para solucionar un error en JSF Ajax JavaScript (que se va a solucionar en JSF 2.2). Para una explicación detallada, vea también Ajax rendering of content which contains another form.

+1

Ok, lo tengo. ¿Hay demasiada diferencia entre '' y '' ?? Porque la segunda opción funcionaba incluso si no había un componente principal siempre presente. Solo quiero tener conceptos claros. THanks – BRabbit27

+2

La principal diferencia está en los datos transferidos. Si tiene muchos otros contenidos fuera de los formularios, el '@ all' transferiría datos innecesarios, lo que hace que el tamaño de respuesta sea más grande, lo que hace que todo sea más lento. Además, el '@ all' tiene el mismo problema que el descrito en el último párrafo de la respuesta, aún deberá especificar explícitamente los ID de formulario en' render'. – BalusC

+0

@BalusC Gracias por esta respuesta, entendí cuál es el problema. –