7 Replies Latest reply on Sep 4, 2009 6:51 PM by Juan Martin Chiaradia

    reRenderin a c:foreach

    Juan Martin Chiaradia Newbie

      Hello,


      I have a page that renders a sorted collection of a bean into a panelMenu.


      An equivalent page will be like this:


      <rich:panelMenu id="menu">
           <rich:panelMenuGroup label="MENU GROUP">
           <c:forEach items="#{menuBean.items}" var="_item">
                <rich:panelMenuItem
                     action="#{_item.action}" 
                     reRender="contentPanel" 
                     ignoreDupResponses="true" 
                     ajaxSingle="true"
                     mode="ajax">
                          <h:outputText value="#{_item.name}" />
                </rich:panelMenuItem>
           </c:forEach>
           </rich:panelMenuGroup>
      </rich:panelMenu>
      
      <a4j:commandButton action="#{menuBean.items.add(new Item())}" value="Nuevo Item" reRender="menu" />
      
      
      




      the problem is that when I add a new item to my item collection, the menu is rerendered, but it acts in an estrange way:


      It only rerender the last item of the collection, letting the other same as before.


      For example if we have:


      MENU GROUP



      • item A

      • item C

      • item D



      if I add a new item (item B), I spect that it should render:


      MENU GROUP



      • item A

      • item B

      • item D

      • item D



      But the real output is:




      MENU GROUP



      • item A

      • item C

      • item D

      • item D





      If I add a new item (item Z), it will work fine and will render:


      MENU GROUP



      • item A

      • item C

      • item D

      • item Z



      Any idea??


        • 1. Re: reRenderin a c:foreach
          Phil Haigh Novice

          Hi Juan,


          Isn't that expected behaviour? You are not telling the list to re-order at any point, so adding the new item will put it at the end.


          Just add a line into your add method to re-sort the collection post adding, and you should be fine.


          • 2. Re: reRenderin a c:foreach
            Juan Martin Chiaradia Newbie

            Hi Phil, my collection is a SortedSet so it is automatically reordered in every add.


            The problem is that if in my model I have a collection of 3 elements:



            • item A

            • item C

            • item D



            and I add a fourth one (Item B) to it, my new collection will be:



            • item A

            • item B

            • item C

            • item D



            But the page only will reRender the last element of the collection (item D) generating a repeat item in the view:



            • item A

            • item C

            • item D

            • item D



            do you understand my problem?

            • 3. Re: reRenderin a c:foreach
              Erik Magnusson Newbie

              This sounds like it might be a problem with the way Facelets deals with the c:forEach tag. You should be very careful and know exactly what your are doing when using any of the JSTL tags with Facelets, since they do not work like any of the other Facelets tags. In general you should use ui:repeat instead of c:forEach in Facelets pages.


              A detailed explanation is available in this blog post.

              • 4. Re: reRenderin a c:foreach
                Juan Martin Chiaradia Newbie

                Hi Erik,


                I already read the post.


                I was forced to use c:forEach because the rich:menuPanel doesn't allows a ui:repeat as child component.


                Acording to the post:




                The most important thing to understand about the jstl tags in Facelets is that they do not represent components and never become a part of the component tree once the view has been built. Rather, they are tags which are actually responsible for building the tree in the first place. Once they have done their job they expire, are no more, cease to be, etc etc.

                I understand this, so the components tree is generated the firs time I render my page, and will generate the next tree component:


                -panelMenu


                ---panelMenuGroup


                -----panelMenuItem


                -------outputText: Item A


                -----panelMenuItem


                -------outputText: Item C


                -----panelMenuItem


                -------outputText: Item D


                but, the post also states that:



                When is the view built?
                Now that you understand that tag handlers are only effective when the tree is built, the next logical question should be well, when is tree built?
                The short answer is that a new view is built for every request which is not a postback. During a postback, the view is reconstructed from saved state. Quite confusing, and not very obvious I know, but there you have it.

                So, if in a postback, the view is reconstructed from previous state ... why it is adding to the menu a new item recently added??


                It seams that the in the render phase it notes that the size of the collection is changed, but it only add to the tree the las element of the collection and not replace the previous ones ...


                I really don't know how to solve this. If I shouldn't use c:forEach ... how can I get a similar result?


                • 5. Re: reRenderin a c:foreach
                  Francisco Jose Peredo Noguez Master

                  Juan Chiaradia wrote on Sep 04, 2009 15:52:


                  I really don't know how to solve this. If I shouldn't use c:forEach ... how can I get a similar result?




                  This is in fact a question for the richfaces forum, you are much more likely to get an answer to this question this there.

                  • 6. Re: reRenderin a c:foreach
                    Francisco Jose Peredo Noguez Master

                    Francisco Peredo wrote on Sep 04, 2009 16:55:



                    Juan Chiaradia wrote on Sep 04, 2009 15:52:


                    I really don't know how to solve this. If I shouldn't use c:forEach ... how can I get a similar result?




                    This is in fact a question for the richfaces forum, you are much more likely to get an answer to this question this there.


                    Sorry, this is the current link to the richfaces forum you may also vote to make this easier here (RF-4128).

                    • 7. Re: reRenderin a c:foreach
                      Juan Martin Chiaradia Newbie

                      Thanks Fransisco, I will cheack that.


                      Meanwhile, here is a demo:
                      list menu demo
                      that works fine and do almost the same that I do, but in my code, this dont work well ... I'm a little confused...