6 Replies Latest reply on May 22, 2009 9:23 AM by mpickell

    Programmatically get id's of components to be rerendered

    mpickell

      I have set up a phase listener that needs to check which components are being re-rendered during a specific ajax request. Is there an easy way to know this?

      I believe that AjaxContext has what I need in it, but I cannot find any documentation on it. The javadoc does not have any descriptions in it.

      Thanks!

        • 1. Re: Programmatically get id's of components to be rerendered
          nbelaevski

          Hi,

          Use org.ajax4jsf.context.AjaxContext.getAjaxAreasToRender() to get Set of components' IDs.

          • 2. Re: Programmatically get id's of components to be rerendered
            mpickell

             

            "nbelaevski" wrote:
            Hi,

            Use org.ajax4jsf.context.AjaxContext.getAjaxAreasToRender() to get Set of components' IDs.


            This always returns an empty set, except for AFTER the render_response phase. Is it possible to catch these IDs somehow prior to render_response?

            • 3. Re: Programmatically get id's of components to be rerendered
              mpickell

               

              "nbelaevski" wrote:
              Hi,

              Use org.ajax4jsf.context.AjaxContext.getAjaxAreasToRender() to get Set of components' IDs.


              "mpickell" wrote:
              This always returns an empty set, except for AFTER the render_response phase. Is it possible to catch these IDs somehow prior to render_response?


              Also, is it possible to know (PRIOR to the render_response phase) the ID of the component submitting the ajax event, and what the event is? I do not see options for these in AjaxContext.

              • 4. Re: Programmatically get id's of components to be rerendered
                nbelaevski

                 

                "mpickell" wrote:
                "nbelaevski" wrote:
                Hi,

                Use org.ajax4jsf.context.AjaxContext.getAjaxAreasToRender() to get Set of components' IDs.


                "mpickell" wrote:
                This always returns an empty set, except for AFTER the render_response phase. Is it possible to catch these IDs somehow prior to render_response?


                Also, is it possible to know (PRIOR to the render_response phase) the ID of the component submitting the ajax event, and what the event is? I do not see options for these in AjaxContext.

                All events are queued from child to parent, using queueEvent() method. So if your component is parent to the components, you wish to be notified of events, then it's easy. Also you can use AjaxListener to get notified of AjaxEvent events fired.

                BTW, can you please describe your use case in more details?

                • 5. Re: Programmatically get id's of components to be rerendered
                  nbelaevski

                   

                  "mpickell" wrote:
                  "nbelaevski" wrote:
                  Hi,

                  Use org.ajax4jsf.context.AjaxContext.getAjaxAreasToRender() to get Set of components' IDs.


                  This always returns an empty set, except for AFTER the render_response phase. Is it possible to catch these IDs somehow prior to render_response?

                  Since JSF 1.2, there are two types of phase listeners: the first sort already existed in JSF 1.1 (they're registered in faces-config.xml), the second is there since JSF 1.2 - that are phase listeners for UIViewRoot component. You can add yours by calling javax.faces.component.UIViewRoot.addPhaseListener(PhaseListener) (and it's easy to add one to view root from the traditional phase listener registered in faces-config.xml bundled with your components archive - you get pluggable solution for free). The idea is that all IDs to re-render should be set by the time the listener will be called for RENDER_RESPONSE phase start. Take a look at JSF/RF code for more - related classes are UIViewRoot and AjaxViewRoot.

                  • 6. Re: Programmatically get id's of components to be rerendered
                    mpickell

                     

                    "nbelaevski" wrote:

                    All events are queued from child to parent, using queueEvent() method. So if your component is parent to the components, you wish to be notified of events, then it's easy. Also you can use AjaxListener to get notified of AjaxEvent events fired.

                    BTW, can you please describe your use case in more details?

                    ...

                    Since JSF 1.2, there are two types of phase listeners: the first sort already existed in JSF 1.1 (they're registered in faces-config.xml), the second is there since JSF 1.2 - that are phase listeners for UIViewRoot component. You can add yours by calling javax.faces.component.UIViewRoot.addPhaseListener(PhaseListener) (and it's easy to add one to view root from the traditional phase listener registered in faces-config.xml bundled with your components archive - you get pluggable solution for free). The idea is that all IDs to re-render should be set by the time the listener will be called for RENDER_RESPONSE phase start. Take a look at JSF/RF code for more - related classes are UIViewRoot and AjaxViewRoot.


                    nbelaevski, thanks for your responses! You can get a little more insight into what we are working on from my responses on this other post:
                    http://www.jboss.org/index.html?module=bb&op=viewtopic&t=155822 which I think you are aware of since you are mentioning phase listeners.

                    More detail:
                    At the company I work for, we have developed a small framework that is essentially a layer over JSF that allows for JSF view creation completely from Java. (you can read about it (www.b6systems.com/blog) and (http://www.theserverside.com/tt/articles/article.tss?l=IntroducingJavaPureFaces)). There is a lot of information and discussion at those links if you want to know more.

                    We have been using this framework for a while now with a lot of success, and we are beginning to replace the JSF implementation we are using with the RichFaces framework so that we can integrate Ajax.

                    This issue:
                    The issue we were currently dealing with was to dynamically replace entire sections of the JSF Tree (i.e., a panelGroup and all of its children) on the page based on ajax events. We attempted to use the phase listener approach, but quickly discovered that it was always re-rendering the components, not just on specific Ajax events. The question I posted here was intended to assist in targeting the phase listeners to only run their code when the right component was triggered by the right event. I believe you have answered this question with the AjaxListener! Thank you!

                    Solution to the bigger problem:
                    But to solve the bigger issue, and not need to get the component ID as I asked here, we move the phase listener code into an ActionListener. We then create HtmlAjaxSupport objects for the specific Ajax event, and added the ActionListener. These HtmlAjaxSupport objects are added as children of the component we wish to rerender. The ActionListener code stores the absolute component ID to be rerendered and a reference to a method using the Reflections API, and when triggered, finds the component in the JSF tree and replaces it with a new dynamically created component.