2 Replies Latest reply on Apr 10, 2010 1:42 PM by akaine

    Form validation executes only once

    akaine

      Hello

      I've run into a pretty strange problem. I have a modal panel with a relatively complex datatable in it. Actually it's not that complex in the template structure, but the backing bean is ugly. When I submit the form the required fields are getting validated as they should and there are error messages I show with another modal panel. And if all is ok the data is getting submitted as it should. The thing here is that after I've seen the validation errors once the fields are never getting validated again and the partially filled data injects right into the backing bean object even if the required fields were never filled. In other words the first time I press the 'Guardar' (or Save) button the facesContext.maximumSeverity object is not null and on the second try it is. This happens in both 3.3.2GA and 3.3.3CR1. JSF version is 1.2.

       

      Here is the actual code. Sorry for the mess but I decided to submit the whole structure to avoid any misunderstandings:

       

      <rich:modalPanel id="modal_area" autosized="true" resizeable="false">
        <f:facet name="header">
          <h:panelGroup>
            <h:outputText value="Area: #{opercuestController.area.catAreaCuestionario.nombre}" />
          </h:panelGroup>
          </f:facet>
            <div style="border: none; padding: 0; margin-bottom: 20px;">
              <h:outputText value="#{opercuestController.area.catAreaCuestionario.instrucciones}" />
            </div>
          <a4j:form id="form_area">
      
          <style>.rich-table-subheadercell{white-space: normal; width: 120px;}</style>
          <rich:dataTable id="dt_area" value="#{opercuestController.area.reactivos}" rowKeyVar="reactivoIdx" var="reactivo" onRowMouseOver="this.style.backgroundColor='#F1F1F1'" onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'" width="#{opercuestController.areaWidth}" >
            <f:facet name="header">
              <rich:columnGroup>
                <rich:column headerClass="rich-table-subheadercell">
                  <h:outputText value="Pregunta" />
                </rich:column>
                <rich:columns value="#{opercuestController.columnas}" index="columnaIdx" var="columna" headerClass="rich-table-subheadercell">
                  <h:outputText value="#{columna.catColumnaArea.descripcion != null and jstl:length(columna.catColumnaArea.descripcion) != 0 ? columna.catColumnaArea.descripcion : columnaIdx+1}" />
                </rich:columns>
              </rich:columnGroup>
            </f:facet>
      
            <rich:column rendered="#{opercuestController.rendered[reactivoIdx]}" >
              <h:outputText value="(#{reactivo.catReactivoArea.numero != null and jstl:length(reactivo.catReactivoArea.numero) != 0 ? reactivo.catReactivoArea.numero : reactivoIdx+1 }) #{reactivo.catReactivoArea.descripcion}" />
            </rich:column>
      
            <rich:columns value="#{opercuestController.columnas}" index="columnaIdx" var="columna" headerClass="rich-table-subheadercell" rendered="#{!reactivo.catReactivoArea.abierta and opercuestController.rendered[reactivoIdx]}" style="text-align: right;">
              <rich:comboBox value="#{opercuestController.respuestas[reactivoIdx][columnaIdx]}" defaultLabel="Ponga algún valor" width="122" listWidth="200px" enableManualInput="false" converter="catalogoConverter" required="#{opercuestController.esSisvea ? reactivoIdx==0 or reactivoIdx==(jstl:length(opercuestController.area.reactivos)-1) : true}" requiredMessage="- Falta respuesta (#{reactivo.catReactivoArea.numero != null and jstl:length(reactivo.catReactivoArea.numero) != 0 ? reactivo.catReactivoArea.numero : reactivoIdx+1 } : #{columnaIdx+1})" style="margin: 0 0 0 auto;">
                <f:selectItems value="#{opercuestController.respuestasSI[reactivoIdx][columnaIdx]}" />
              </rich:comboBox>
            </rich:columns>
          </rich:dataTable>
      
          <rich:panel style="text-align: center; border: none;">
            <a4j:commandButton value="Guardar" id="btn_area" action="#{opercuestController.saveArea}" type="submit" oncomplete="#{facesContext.maximumSeverity == null ? 'Richfaces.hideModalPanel(\'modal_area\');' : 'Richfaces.showModalPanel(\'valida_panel_cuest\');'}" reRender="formCuestionario" onclick="this.disabled='disabled';" disabled="#{opercuestController.disabled}" />
            <rich:spacer width="10"></rich:spacer>
            <a4j:commandButton value="Cancelar" action="#{opercuestController.flushArea}" type="button" oncomplete="#{rich:component('modal_area')}.hide(); #{rich:component('modal_cuestionario')}.show();" reRender="modal_area" ajaxSingle="true" />
          </rich:panel>
        </a4j:form>
      </rich:modalPanel>
      
      
      <rich:modalPanel id="valida_panel_cuest" autosized="true">
        <f:facet name="header">Error de validación de datos</f:facet>
        <a4j:form>
          <h:panelGrid style="width: 380px;">
            <h:panelGrid columns="2" style="margin-bottom: 10px;">
              <h:graphicImage value="resource:///resources/images/dialog_warning.png" style="margin-right: 20px;" />
                <rich:messages layout="table" showSummary="true" showDetail="false" ajaxRendered="true" style="color: red;" />
            </h:panelGrid>
            <h:panelGroup>
              <div style="text-align: center;">
                <a4j:commandButton value="Regresar a la forma" oncomplete="#{rich:component('valida_panel_cuest')}.hide(); document.getElementById('form_area:btn_area').disabled=false;" />
              </div>
            </h:panelGroup>
          </h:panelGrid>
        </h:form>
      </rich:modalPanel>
      
      

       

      Any ideas? Thanks in advance

        • 1. Re: Form validation executes only once
          nbelaevski

          Hi Akaine,

           

          This can be a problem with required expression changing its value between requests:

           

          #{opercuestController.esSisvea ? reactivoIdx==0 or reactivoIdx==(jstl:length(opercuestController.area.reactivos)-1) : true}
          

           

          or with rich:comboBox (can you please try with h:selectOneMenu?).

          • 2. Re: Form validation executes only once
            akaine

            1. The problem persists even if I remove the required binding and just set it "true"

            2. I've "tried" h:selectOneMenu and while there is no problem with this one (because of the fact that all the fields are always filled from the very moment I load the datatable) I can't use this element because of lack of some attributes and empty value by default which I actually need since not all the fields should be always filled.

             

            To clear up the picture a bit here goes a screenshot of what it looks like:

             

            screen2.png

             

            An interesting fact: If I rerender the datatable each time I close the error modal the form gets validated again when I press Guardar button. But in this case all the filled fields reset themselves which I cannot allow.