4 Replies Latest reply on Jun 9, 2010 3:58 AM by ufonaut

    a4j:selectOneMenu triggering rerendering

    ufonaut

      I've got a form, one panel of which is dynamically loaded.  The user makes a choice from a selectOneMenu.  Based on that choice, an "add" a4j:commandButton may be rendered.  If it is and the user hits it, the dynamically loaded panel is then opened with the appropriate xhtml.

       

      So, the code is as follows:

       

      {code:xml}

      <a4j:form id="myForm">


      <h:panelGroup id="detailsPanel" layout="block">


        <a4j:region>


          <c:set var="beanName"  value="#{myController.beanName}" />

       


          <a4j:include viewId="somepath/#{beanName}.xhtml"

       

                      id="#{beanName}Include"


                         ajaxRendered="false"/>


        </a4j:region>

      </h:panelGroup>

       


      <a4j:region>


        <h:selectOneMenu id="level1"


          value="#{myController.level1Value}"


        >


          <a4j:support event="onchange"


              limitToList="true" reRender="addButton"


              ajaxSingle="true" />


          <s:selectItems


          value="#{myController.level1ValueList}"


          var="t" label="#{t.code}"


          noSelectionLabel="${msgs.noSelectionMessage}"


          hideNoSelectionLabel="true" />


        </h:selectOneMenu>



      </a4j:region>

       



        <a4j:commandButton id="addButton" value="#{msgs.add}"


              ajaxSingle="true"


              disabled="#{myController.addButtonDisabled}"


              action="#{myController.openDetails}"


              reRender="detailsPanel"


        />

       


      </a4j:form>

      {code}

       

      myController is a very simple bean - none of the methods here reference FacesContext, etc.

       

      What's happening is :

      - Page opens

      - User makes a selection from "level1", and addButton becomes enabled

      - User hits addButton, and detailsPanel is rendered correctly

      - User makes another selection from "level1" (that would also enable the addButton)

       

      And an exception is thrown by the detailsPanel    Note that this is the onchange from the selectOneMenu - the user has not hit the addButton !

       

      I'm not actually bothered about the exception (it's just a consequence of the 'openDetails' method not being called).

       

      What I am bothered about is that detailsPanel is being rendered from this selectOneMenu onchange event.  All I want out of that event is to reRender the addButton - no more!  That's why I've tried wrapping it in a4j:regions, put in limitToList, etc.

       

      Why is the detailsPanel even being looked at when the selectOneMenu's onchange event is fired?  and what more can I do to get it to not be looked at?

        • 1. Re: a4j:selectOneMenu triggering rerendering
          ilya_shaikovsky

          need more info about panel and exception.. Also about RF version.

          • 2. Re: a4j:selectOneMenu triggering rerendering
            ufonaut

            The exception is (if the first choice from the selectOneMenu was "world", and the second selection was "cup") :

            javax.faces.FacesException: UIInclude component myForm:worldInclude could't include page with path somepath/cup/world.xhtml

             

            This is because the different xhtml files that may be loaded live in different subdirectories.  Deriving the path name is one of the functions that the "openDetails()" method does when the "add" button is clicked (and I simplified the example a bit, it's really more like :

             

            {code:xml}
                <c:set var="beanName"  value="#{myController.beanName}" />

                <c:set var="pathName"  value="#{myController.pathName}" />


                <a4j:include viewId="somepath/#{pathName}#{beanName}.xhtml"
            {code}

            )

             

            Since this panel is being processed without the "addButton" ever being clicked, then the controller's never getting the chance to set the pathName.  I can understand how the path name in the exception is being arrived at - as I say, that's not the problem, and I can probably program around it.   I'm just worried how the panel - any panel! - could possibly be being processed and looking for an xhtml from the selectOneMenu's onchange event?

             

            We're using RF3.3.3.CR1.

            • 3. Re: a4j:selectOneMenu triggering rerendering
              ilya_shaikovsky

              at first try to use relative path like /somepath... instead somepath...

               

              And try

                <a4j:include viewId=somepath/#{myController.pathName}#{myController.beanName}.xhtml
              • 4. Re: a4j:selectOneMenu triggering rerendering
                ufonaut

                Thanks, Ilya,

                 

                But getting it working isn't the issue;  I'm trying to understand what's going on in the background.

                 

                Having said that, I think I've found the issue.  In my real code, I actually had a "<c:if" wrtapped around the a4j:include.

                 

                Facelets class FaceletViewHandler has the following comment :

                 

                {code}

                // build view - but not if we're in "buildBeforeRestore"


                            // land and we've already got a populated view. Note


                            // that this optimizations breaks if there's a "c:if" in


                            // the page that toggles as a result of request processing -


                            // should that be handled? Or


                            // is this optimization simply so minor that it should just


                            // be trimmed altogether?

                {code}

                 

                Fortunately, the solution in my case is simple - just derive the path in the onchange instead of the addButton.

                 

                Thanks again