4 Replies Latest reply on Feb 12, 2008 10:08 AM by achildress

    modalpanel disappearing-parent form submit when you don't wa

    achildress

      This is kind of complex, but I'm guessing that the complexity is the reason for the buggy modal panel behavior. I am using facelets and richfaces 3.1.3. I have a facelet template that defines the general page structure:

      <?xml version='1.0' encoding='UTF-8' ?>
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html">
      <head>
       <title>OPUS Online</title>
       <link rel="stylesheet" type="text/css" media="all" href="#{facesContext.externalContext.requestContextPath}/css/default.css"/>
      </head>
      <body>
      <div id="top" class="header">
       <h:graphicImage url="/images/opusonline.gif" />
      </div>
      <div id="container">
       <div id="left" style="margin: 0px 0px 0px 0px; width: 300px; float:left;">
       <ui:insert name="left">
       </ui:insert>
       </div>
       <div id="content" style="margin: 0px 0px 0px 10px; float:left;">
       <ui:insert name="content">
       </ui:insert>
       </div>
      </div>
      <div id="footer" class="footer">
       <ui:insert name="footer">
       </ui:insert>
      </div>
      </body>
      </html>
      


      In the "left" div of the template, I use a rich tree for navigation:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:u="http:/jsf.exadel.com/template/util"
       xmlns:custom="http://doc/jsf/custom"
       template="pagetemplate.xhtml">
       <link rel="stylesheet" type="text/css" media="all" href="#{facesContext.externalContext.requestContextPath}/css/default.css"/>
       <ui:define name="left">
       <rich:panelBar height="460" width="300">
       <rich:panelBarItem label="DOP Intake" rendered="#{custom:roleRender('DOP')}">
       <a4j:form>
       <rich:panel>
       <rich:tree nodeSelectListener="#{DOPIntakeMenuBean.processSelection}" adviseNodeOpened="#{DOPIntakeMenuBean.adviseNodeOpened}"
       ajaxSingle="true" ajaxSubmitSelection="true" switchType="client"
       value="#{DOPIntakeMenuBean.treeNode}" var="item" iconLeaf="/images/spacer.gif">
       <rich:treeNode>
       <a4j:commandLink reRender="maincontent" value="#{item.itemText}" ></a4j:commandLink>
       </rich:treeNode>
       </rich:tree>
       </rich:panel>
       </a4j:form>
       </rich:panelBarItem>
       <rich:panelBarItem label="DCC Intake" rendered="#{custom:roleRender('DCC')}">
       This is a test.
       </rich:panelBarItem>
       </rich:panelBar>
       </ui:define>
       <ui:define name="content">
       <a4j:outputPanel id="maincontent" ajaxRendered="true">
       <a4j:include viewId="#{DOPIntakeMenuBean.selectedURL}"/>
       </a4j:outputPanel>
       </ui:define>
      </ui:composition>
      


      When a leaf of the tree is clicked, the URL associated with that leaf is loaded into the maincontent outputPanel. In this test case, I select the leaf that loads the following xhtml:

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:u="http:/jsf.exadel.com/template/util" >
       <link rel="stylesheet" type="text/css" media="all" href="#{facesContext.externalContext.requestContextPath}/css/default.css"/>
       <rich:panel style="width: 100%; height: 500px;">
       <f:facet name="header">Process Scheduled Arrivals</f:facet>
       <h:panelGrid columns="2" style="margin-top: 10px;">
       <h:outputLabel styleClass="stdLabel" for="diagFacCombo" value="Facility: "/>
       <h:selectOneListbox size="1" id="diagFacCombo" value="#{DOPIntakeScheduledArrivalsBean.facility}">
       <f:selectItems value="#{CodeCacheBean.getCodes$['diagFacilityCode']}"/>
       </h:selectOneListbox>
       <h:outputLabel styleClass="stdLabel" value="Scheduled Arrival Date Range: "/>
       <h:panelGrid columns="3">
       <rich:calendar id="dateRangeStart" value="#{DOPIntakeScheduledArrivalsBean.dateRangeStart}" datePattern="MM/dd/yyyy"></rich:calendar>
       <h:outputLabel styleClass="stdLabel" value=" To: "/>
       <rich:calendar id="dateRangeEnd" value="#{DOPIntakeScheduledArrivalsBean.dateRangeEnd}" datePattern="MM/dd/yyyy"></rich:calendar>
       </h:panelGrid>
       </h:panelGrid>
       <rich:panel style="margin-top: 10px;">
       <h:form>
       <f:facet name="header">Scheduled Arrivals</f:facet>
       <rich:datascroller for="offenderList" style="margin-top: 6px; text-align: center; background-color: #c6c6c6;"></rich:datascroller>
       <rich:dataGrid style="height: 350px;" id="offenderList" value="#{DOPIntakeScheduledArrivalsBean.preArrivalOffenders}" var="PreArrivalOffenderBean" columns="1" elements="2">
       <rich:panel style="width: 600px;">
       <f:facet name="header">
       <h:outputText value="#{PreArrivalOffenderBean.offenderName}" styleClass="stdLabel"></h:outputText>
       </f:facet>
       <table>
       <tr>
       <td align="right" width="10%"><h:outputText value="DOC#:" styleClass="tableLabel"/></td>
       <td align="left" width="20%"><h:outputText value="#{PreArrivalOffenderBean.offenderID}" styleClass="tableText"/></td>
       <td align="right" width="20%"><h:outputText value="Scheduled Arrival Date:" styleClass="tableLabel"/></td>
       <td align="left" width="20%"><h:outputText value="#{PreArrivalOffenderBean.scheduledArrivalDate}" styleClass="tableText"><f:convertDateTime pattern="MM/dd/yyyy" /></h:outputText></td>
       <td align="left" width="20%" rowspan="5" valign="top">
       <rich:dataGrid id="taskList" value="#{PreArrivalOffenderBean.tasks}" var="PreArrivalTaskBean" columns="1" elements="3">
       <h:commandLink styleClass="linkText" onclick="javascript:Richfaces.showModalPanel('dci',{width:450, top:200})" value="#{PreArrivalTaskBean.taskName}">
       <a4j:actionparam name="offenderID" value="#{PreArrivalOffenderBean.offenderID}" assignTo="#{PreArrivalDCISearchConfirmBean.offenderID}"/>
       </h:commandLink>
       </rich:dataGrid>
       </td>
       </tr>
       <tr>
       <td align="right"><h:outputText value="County:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.convictionCountyDisplay}" styleClass="tableText"/></td>
       <td align="right"><h:outputText value="Offense Type:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.primaryFelonyMisdemeanorDisplay}" styleClass="tableText"/></td>
       </tr>
       <tr>
       <td align="right"><h:outputText value="Gender:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.genderDisplay}" styleClass="tableText"/></td>
       <td align="right"><h:outputText value="Sentence Length:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.sentenceLengthDisplay}" styleClass="tableText"/></td>
       </tr>
       <tr>
       <td align="right"><h:outputText value="Race:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.raceDisplay}" styleClass="tableText"/></td>
       <td align="right"><h:outputText value="Spec Char:" styleClass="tableLabel"/></td>
       <td align="left"><h:outputText value="#{PreArrivalOffenderBean.specialCharacteristicsDisplay}" styleClass="tableText"/></td>
       </tr>
       <tr>
       <td align="right"><h:outputText value="Birth Date:" styleClass="tableLabel"/></td>
       <td align="left" colspan="3"><h:outputText value="#{PreArrivalOffenderBean.birthDate}" styleClass="tableText"><f:convertDateTime pattern="MM/dd/yyyy" /></h:outputText></td>
       </tr>
       </table>
       </rich:panel>
       </rich:dataGrid>
       </h:form>
       </rich:panel>
       <script>
       function getRightTop(ref) {
       var position = new Object();
       position.top = 0; //ref.offsetTop;
       position.left =0; // ref.offsetLeft+ref.clientWidth+6;
       return position;
       }
       </script>
       <rich:modalPanel id="dci" minHeight="200" minWidth="450"
       height="200" width="500" zindex="2000" onshow="alert(event.parameters.offenderID)">
       <f:facet name="header">
       <h:outputText value="Confirm DCI Search" />
       </f:facet>
       <f:facet name="controls">
       <h:graphicImage value="/images/close.png" style="cursor:pointer" onclick="Richfaces.hideModalPanel('dci')" />
       </f:facet>
       <a4j:outputPanel id="confirm">
       <h:outputText value="Offender ID:" styleClass="tableLabel"/><h:outputText value="#{PreArrivalDCISearchConfirmBean.offenderID}" styleClass="tableText"/>
       </a4j:outputPanel>
       </rich:modalPanel>
       </rich:panel>
      </ui:composition>
      


      I had this coded so that when the commandLink in the dataGrid was clicked, I would obtain the appropriate showModalPanel code for the link clicked, but for this example I just changed it to have the hardcoded showModalPanel that you see.

      Here's the problem. When I click the commandLink which is supposed to open the modal panel after doing an actionparam to set a value in the backing bean that the modal panel uses, the modal panel shows for a split second before disappearing. I assume that this is because a submit is being performed on the entire page that is loaded into the maincontent outputPanel that is the parent of the commandLink. I can add return false; to the end of the showModalPanel call, but then the actionparam does not take place to set the bean property that the modalPanel will be displaying.

      Funny thing is, that if I open the page that is being loaded into the maincontent outputPanel by itself in a browser and click the commandLink to show the modal panel, it works fine and the modal panel does not disappear.

      My question is, do I have too many complex components nested and being further complicated by the use of facelets? If not, how do I make this work?

      The process I am trying to accomplish is basically:
      1- use rich tree to navigate to page showing dataGrid, where each row in the dataGrid contains a commandLink that will pass information to a modalPanel so it can display that passed information and act on it.

      Perhaps my problem is that I've got a dataGrid inside a dataGrid? That didn't seem like too much of a stretch to make such a thing work, especially given that the nested dataGrid renders just fine.

      Don't laugh, because I admit I am a newbie to JSF and RichFaces, and I'm basically hacking my way through it with little or no intuitive information to go on. I know there is probably an easier way to do this, but I have yet to stumble upon it. I have tried to pass custom parameters to the modal panel by adding ",{param:paramvalue}" to the showModalPanel call, but that doesn't seem to work either. I've tried doing onshow alert to try to see if the parameter was being passed, with no luck there either because the alert never displays.

      Somebody has to have solved this already......Please Help!! Thanks in advance.

        • 1. Re: modalpanel disappearing-parent form submit when you don'
          achildress

          reposting the maincontent xhtml, as I posted incorrect one. This one is the version where the modalpanel shows for a split second and then disappears:

          <ui:composition xmlns="http://www.w3.org/1999/xhtml"
           xmlns:ui="http://java.sun.com/jsf/facelets"
           xmlns:h="http://java.sun.com/jsf/html"
           xmlns:f="http://java.sun.com/jsf/core"
           xmlns:a4j="http://richfaces.org/a4j"
           xmlns:rich="http://richfaces.org/rich"
           xmlns:u="http:/jsf.exadel.com/template/util" >
           <link rel="stylesheet" type="text/css" media="all" href="#{facesContext.externalContext.requestContextPath}/css/default.css"/>
           <rich:panel style="width: 100%; height: 500px;">
           <f:facet name="header">Process Scheduled Arrivals</f:facet>
           <h:panelGrid columns="2" style="margin-top: 10px;">
           <h:outputLabel styleClass="stdLabel" for="diagFacCombo" value="Facility: "/>
           <h:selectOneListbox size="1" id="diagFacCombo" value="#{DOPIntakeScheduledArrivalsBean.facility}">
           <f:selectItems value="#{CodeCacheBean.getCodes$['diagFacilityCode']}"/>
           </h:selectOneListbox>
           <h:outputLabel styleClass="stdLabel" value="Scheduled Arrival Date Range: "/>
           <h:panelGrid columns="3">
           <rich:calendar id="dateRangeStart" value="#{DOPIntakeScheduledArrivalsBean.dateRangeStart}" datePattern="MM/dd/yyyy"></rich:calendar>
           <h:outputLabel styleClass="stdLabel" value=" To: "/>
           <rich:calendar id="dateRangeEnd" value="#{DOPIntakeScheduledArrivalsBean.dateRangeEnd}" datePattern="MM/dd/yyyy"></rich:calendar>
           </h:panelGrid>
           </h:panelGrid>
           <rich:panel style="margin-top: 10px;">
           <a4j:form>
           <f:facet name="header">Scheduled Arrivals</f:facet>
           <rich:datascroller for="offenderList" style="margin-top: 6px; text-align: center; background-color: #c6c6c6;"></rich:datascroller>
           <rich:dataGrid style="height: 350px;" id="offenderList" value="#{DOPIntakeScheduledArrivalsBean.preArrivalOffenders}" var="PreArrivalOffenderBean" columns="1" elements="2">
           <rich:panel style="width: 600px;">
           <f:facet name="header">
           <h:outputText value="#{PreArrivalOffenderBean.offenderName}" styleClass="stdLabel"></h:outputText>
           </f:facet>
           <table>
           <tr>
           <td align="right" width="10%"><h:outputText value="DOC#:" styleClass="tableLabel"/></td>
           <td align="left" width="20%"><h:outputText value="#{PreArrivalOffenderBean.offenderID}" styleClass="tableText"/></td>
           <td align="right" width="20%"><h:outputText value="Scheduled Arrival Date:" styleClass="tableLabel"/></td>
           <td align="left" width="20%"><h:outputText value="#{PreArrivalOffenderBean.scheduledArrivalDate}" styleClass="tableText"><f:convertDateTime pattern="MM/dd/yyyy" /></h:outputText></td>
           <td align="left" width="20%" rowspan="5" valign="top">
           <rich:dataGrid id="taskList" value="#{PreArrivalOffenderBean.tasks}" var="PreArrivalTaskBean" columns="1" elements="3">
           <a4j:commandLink styleClass="linkText" onclick="javascript:Richfaces.showModalPanel('dci',{width:450, top:200})" value="#{PreArrivalTaskBean.taskName}">
           <a4j:actionparam name="offenderID" value="#{PreArrivalOffenderBean.offenderID}" assignTo="#{PreArrivalDCISearchConfirmBean.offenderID}"/>
           </a4j:commandLink>
           </rich:dataGrid>
           </td>
           </tr>
           <tr>
           <td align="right"><h:outputText value="County:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.convictionCountyDisplay}" styleClass="tableText"/></td>
           <td align="right"><h:outputText value="Offense Type:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.primaryFelonyMisdemeanorDisplay}" styleClass="tableText"/></td>
           </tr>
           <tr>
           <td align="right"><h:outputText value="Gender:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.genderDisplay}" styleClass="tableText"/></td>
           <td align="right"><h:outputText value="Sentence Length:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.sentenceLengthDisplay}" styleClass="tableText"/></td>
           </tr>
           <tr>
           <td align="right"><h:outputText value="Race:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.raceDisplay}" styleClass="tableText"/></td>
           <td align="right"><h:outputText value="Spec Char:" styleClass="tableLabel"/></td>
           <td align="left"><h:outputText value="#{PreArrivalOffenderBean.specialCharacteristicsDisplay}" styleClass="tableText"/></td>
           </tr>
           <tr>
           <td align="right"><h:outputText value="Birth Date:" styleClass="tableLabel"/></td>
           <td align="left" colspan="3"><h:outputText value="#{PreArrivalOffenderBean.birthDate}" styleClass="tableText"><f:convertDateTime pattern="MM/dd/yyyy" /></h:outputText></td>
           </tr>
           </table>
           </rich:panel>
           </rich:dataGrid>
           </a4j:form>
           </rich:panel>
           <script>
           function getRightTop(ref) {
           var position = new Object();
           position.top = 0; //ref.offsetTop;
           position.left =0; // ref.offsetLeft+ref.clientWidth+6;
           return position;
           }
           </script>
           <rich:modalPanel id="dci" minHeight="200" minWidth="450"
           height="200" width="500" zindex="2000">
           <f:facet name="header">
           <h:outputText value="Confirm DCI Search" />
           </f:facet>
           <f:facet name="controls">
           <h:graphicImage value="/images/close.png" style="cursor:pointer" onclick="Richfaces.hideModalPanel('dci')" />
           </f:facet>
           <a4j:outputPanel id="confirm">
           <h:outputText value="Offender ID:" styleClass="tableLabel"/><h:outputText value="#{PreArrivalDCISearchConfirmBean.offenderID}" styleClass="tableText"/>
           </a4j:outputPanel>
           </rich:modalPanel>
           </rich:panel>
          </ui:composition>
          
          


          • 2. Re: modalpanel disappearing-parent form submit when you don'
            ilya_shaikovsky

            docs - always good start to new components usage.

            modal panel can't be opened using h:command* onclick attributes. In your case oncomplete attribute of a4j:commandLink should be used.

            • 3. Re: modalpanel disappearing-parent form submit when you don'
              achildress

              See my second post. I incorrectly posted one of my failed attempts at opening the modal panel with h:commandLink first, but the second post is using the a4j:commandLink. This is the one where the modal panel opens for a split second, then closes. I have a feeling that the problem lies in the fact that the xhtml code that has the commandLink open of the modal pane is first displayed using an a4j:commandLink itself when the leaf of the rich tree is clicked. Somehow the modal panel open is triggering a reload of the parent, thus dismissing the modal panel. If I could just figure out how to load the child using the tree without an a4j call, that would take care of it. I struggled for over a week just to get the tree working, so I feel I'm back to square one again. I'm just so inexperienced with ajax and I don't really understand the ajax conversation itself and how to control it at a more atomic level. Would you have a substitute for the a4j:commandLink in the rich tree that would work the same way?

              • 4. Re: modalpanel disappearing-parent form submit when you don'
                achildress

                GOT IT WORKING!!!

                I changed the commandLink to look like this:

                 <a4j:commandLink limitToList="true" reRender="confirm" styleClass="linkText" oncomplete="javascript:Richfaces.showModalPanel('dci',{width:450, top:200})" value="#{PreArrivalTaskBean.taskName}">
                 <a4j:actionparam name="offenderID" value="#{PreArrivalOffenderBean.offenderID}" assignTo="#{PreArrivalDCISearchConfirmBean.offenderID}"/>
                 </a4j:commandLink>
                


                Then I changed the modal panel display area to:

                 <h:form>
                 <a4j:outputPanel id="confirm">
                 <h:outputText value="Offender ID:" styleClass="tableLabel"/><h:outputText value="#{PreArrivalDCISearchConfirmBean.offenderID}" styleClass="tableText"/>
                 </a4j:outputPanel>
                 </h:form>
                


                Apparently the limitToList and reRender added to the commandLink combined with defining the a4j:outputPanel with an id to match the reRender did the trick. This seems to have confined the ajax reloading to just the modal panel display. Phew! RichFaces sure is powerful, but the documentation leaves a lot to be desired if you learn from example. The examples don't exactly explore the full range of possibilities for the components. Anyway, that's my subtle hint to JBoss for the day. Thanks ilya for contributing.