11 Replies Latest reply on Feb 3, 2007 6:24 PM by jk;l jkl;

    dataTable in two windows

    jk;l jkl; Expert

      If you have the same page containing a dataTable open in two windows and you delete an element from one window (assume you've made delete functionality in your code to simply remove the injected @DataModelSelection from the entity and the EntityManager), then delete the same element from the other window (without refreshing first to pick up the deletion), something happens that I didn't expect.

      Rather than the second delete not doing anything (because the underlying object for that row doesn't exist), it actually deletes whatever object is currently under the row index in place of where the previous row was before. Let me clarify:

      table contains following elements:
      a
      b
      c

      In window one you delete a, and the table looks like this:
      b
      c

      In window two because you haven't refreshed it still looks like
      a
      b
      c

      In window two you delete a. I would think that nothing should happen because a is already gone. However, here's what window two (and window one after refreshing) looks like:
      c

      Apparently clicking delete deleted whatever is currently in the row index position that a was in before, which is now b...

      Do dataTables have some functionality to get around this or is this actually how this is supposed to work?

        • 1. Re: dataTable in two windows
          jk;l jkl; Expert

          Here's something else that happens, which I think is probably more important to address than the previous, and I think it'll solve the previous.

          If you delete a row, then refresh the page, the next row gets deleted. The more you refresh, the more rows get deleted!

          Here's what the table rows are initially:
          a
          b
          c
          d

          Let's say you delete row b, so the table now looks like
          a
          c
          d

          You refresh the page, click OK for the rePOST error that IE presents, but the table has changed again!
          a
          d

          Another refresh would result in:
          d

          The refresh repeats the delete operation with the current row index, so keeps deleting whatever is next in line from where b was initially.

          Is this just a downside of using DataModelSelection, or is there some way to avoid the injection based on row index (preferrably the id of the underlying entity for that row)?

          • 2. Re: dataTable in two windows
            Gavin King Master

            First problem can be solved by passing the id as a request parameter instead of blindly using @DataModelSelection.

            Second problem means you should be using post-then-redirect instead of letting refresh do a duplicate submission.

            • 3. Re: dataTable in two windows
              Alex Kozlenkov Newbie

              Hello guys,

              My first post here so perhaps not so insigtful. I'm on the same subject of duplicate actions. I have found that even a simple form submission like a simple sayHello method results in duplicate action. Could you perhaps make it more clear what should be done for it to stop doing that?

              Secondly, I'm experimenting with the new Seam security (in the CVS). I have found a few problems, the first being that once we are logged in, retyping the URL address of the starting page does not result in a request so the login dialogue is available once more since identity.loggedIn is not checked. So my question is what should normally happen when a user types in the URL directly.

              Cheers,
              Alex

              • 4. Re: dataTable in two windows
                Alex Kozlenkov Newbie

                Using a custom PhaseListener that disables the cache completely on response refreshes the login (home) page and checks for identity.loggedIn status. Perhaps there is an easier way--don;t know at this point.

                Now about another problem. I'm getting this exception

                [PhaseListenerManager] Exception in PhaseListener RENDER_RESPONSE(6) beforePhase.
                java.lang.IllegalStateException: No page context active
                 at org.jboss.seam.core.FacesPage.instance(FacesPage.java:88)
                 at org.jboss.seam.jsf.AbstractSeamPhaseListener.beforeRender(AbstractSeamPhaseListener.java:220)
                 at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener.java:53)
                (1) when I log out, (2) when I update the Seam Debug page. I know this exception has been mentioned before but can anyone comment on whether there is a fix underway.

                Many thanks,
                Alex
                Advanced Technology Group, Betfair Limited

                • 5. Re: dataTable in two windows
                  Pete Muir Master

                  Shane/Gavin/Norman will have to give you the definitive answer but I think that Seam Security is still being heavily developed and you would be well advised to wait for the release of 1.1.5 and associated documentation.

                  • 6. Re: dataTable in two windows
                    jk;l jkl; Expert

                     

                    First problem can be solved by passing the id as a request parameter instead of blindly using @DataModelSelection.


                    So I wouldn't use @DataModelSelection at all? How would the appropriate value get injected into the entity representing the selected row using a request parameter?

                    @DataModelSelection
                    @Out(required=false)
                    private MyEntity mySelectedEntity;
                    
                    ...
                    
                    public void removeMyEntity() {
                     em.remove(mySelectedEntity);
                    }


                    How would I change the above to use request parameters by using pages.xml or alternatively @RequestParameter?

                    • 7. Re: dataTable in two windows
                      jk;l jkl; Expert

                      I have added the below to pages.xml for the page containing the dataTable:

                      <param name="entityId" value="#{mySelectedEntity.id}" />


                      But how would I modify the code from the previous post to take advantage of the injected request parameter?

                      @DataModelSelection
                      @Out(required=false)
                      private MyEntity mySelectedEntity;
                      
                      ...
                      
                      public void removeMyEntity() {
                       // How does the remove know to take out the correct entity
                       em.remove(mySelectedEntity);
                      }


                      • 8. Re: dataTable in two windows
                        Mariusz Smykula Newbie

                        I think somethink like this can help...

                        @RequestParameter
                        Long entityId;
                        
                        public void removeMyEntity() {
                         MyEntity mySelectedEntity = em.find(MyEntity.class, entityId);
                         em.remove(mySelectedEntity);
                        }
                        



                        • 9. Re: dataTable in two windows
                          jk;l jkl; Expert

                          Thanks, that looks like a good solution.

                          Is there an easier way by using pages.xml however? If you set the #{mySelectedEntity.id} in the pages.xml like the following, then wouldn't the entity you selected actually somehow get refreshed with the value in the database associated with that id?

                          <param name="entityId" value="#{mySelectedEntity.id}" />


                          Then in the remove method you could stick to em.remove(...); alone?

                          But what I'm wondering is how I could modify my code to take advantage of this...basically, what does putting a param element in pages.xml that points to an id actually do...is it what I think (the refresh) or is it something else?

                          • 10. Re: dataTable in two windows
                            jk;l jkl; Expert

                            How do I get each row's ID to appear in it's text within the link? Right now when I put the following in pages.xml every commandLink shows up (when I put my cursor over it) with an ID URL parameter of the value that was previously selected, as opposed to the value that corresponds to the ID of what entity that row represents...

                            <param name="entityId" value="#{mySelectedEntity.id}" />


                            Every single commandLink on the page has the exact same entityID in its URL string! Why?

                            • 11. Re: dataTable in two windows
                              jk;l jkl; Expert

                               

                              First problem can be solved by passing the id as a request parameter instead of blindly using @DataModelSelection.


                              Could anybody please explain how they've done this with their code?

                              The code below explains how to remove the appropriate entity when you have a request parameter passed in. But how can I make every row in the dataTable output a corresponding request parameter (so that when someone clicks a link in the table, the request parameter gets passed)?

                              @RequestParameter
                              Long entityId;
                              
                              public void removeMyEntity() {
                               MyEntity mySelectedEntity = em.find(MyEntity.class, entityId);
                               em.remove(mySelectedEntity);
                              }


                              Is it as simple as an h:commandLink to the action method with a nested f:param that has the id of the entity?