ModalPanelValidation

One of the frequently asked questions is how to prevent modal panel from closure if the validation inside fails. Here is a very simple code to provide such behaviour.

 

<ui:define name="body">
     <f:verbatim>
          <a href="javascript:Richfaces.showModalPanel('_panel',{left:'auto', top:'auto'})">
               Show Modal Panel
          </a>
     </f:verbatim>
     <rich:modalPanel id="_panel">
          <f:facet name="header">
               <h:outputText value="test"></h:outputText>
          </f:facet>
          <h:form id="mpform">
               <a4j:outputPanel ajaxRendered="true">
                    <h:messages id="error"></h:messages>
               </a4j:outputPanel>
               <h:inputText value="#{bean.property}" required="true"></h:inputText>
               <a4j:commandLink value="click" oncomplete="windowclose();"
                    reRender="test" ></a4j:commandLink>
          </h:form>
     </rich:modalPanel>
     <script type="text/javascript">
          //<![CDATA[
               function windowclose(){
                    if (document.getElementById('mpform:error')==null){
                         Richfaces.hideModalPanel('_panel');
                    };
               };
//\]\]\>

     </script>
</ui:define>

 

All that we perform inside the panel - we check whether the messages are created on a page. And if the messages don't appear, just close the window. In the other case nothing is done, so the window stays with the messages inside.

 

More generic solution

See also on RichFaces user forum

 

In my default.xhtml template, I added the following:

 

<a4j:outputPanel ajaxRendered="true">
   <h:form style="display:none" prependId="false">
        <h:inputHidden id="maximumSeverity" value="#{facesContext.maximumSeverity.ordinal}"/>
    </h:form>              
</a4j:outputPanel>


Basically, we now have an invisible form that gets refreshed on every postback and contains a hidden field that tells us the maximum severity in the message queue, or null if the queue is empty.

Next, I have a little utility javascript method like this:

function ajaxRequestContainsErrors() {
    return document.getElementById("maximumSeverity").value == "2";
}


This method simply reads the value of the hidden field and tests if its equal to the ERROR severity ordinal value.

Since all of this is done in my base template, every facelet client file can now use this little javascript method to see if the last postback to the server generated any errors.

Finally, the a4j:commandLink or a4j:commandButton that submits a form from within a modal panel can now look like this:

<a4j:commandButton value="Save" action="#{myController.save}" 
     oncomplete="if (!ajaxRequestContainsErrors()) Richfaces.hideModalPanel('myModalPanelId');"/>