14 Replies Latest reply on Jun 24, 2008 4:17 PM by bgregory

    Client elements not updated after a4j request

      This was embedded in another thread, but deserves its own...

      "bgregory" wrote:
      I don't know if this is related, but I have a case where a datatable with links for each record. This table is re-rendered from an ajax call. Calling client.getElement() for the ID of the links (after the ajax update) gives me the expected "matches more than one JSF component ID" exception and lists the links that were there prior to the ajax call - not what should be there now. Calling client.getContentPage() and then dumping the xml (HtmlPage.asXml()) does display the updated page.


      "stan.silvert@jboss.com" wrote:
      Your datatable problem could be related. I have to distinguish between an a4j request that changed the view and one that didn't (like a resource request). I need to take a closer look at that.


      Not sure yet if this only applies to rich:dataTable reRender'ing, but that scenario is heavily used in our test cases.

        • 1. Re: Client elements not updated after a4j request
          ssilvert

          So are you seeing this problem too or just wondering if it is something you might run into?

          I actually think I know what the problem is though. I just need to figure out how it can be solved.

          Stan

          • 2. Re: Client elements not updated after a4j request

            No I'm seeing it too... bgregory and I are working on the same project.

            Justin.

            • 3. Re: Client elements not updated after a4j request

              It seems to be that keeping the ClientIDs up to date is a continuing problem (do I presume too much?). Perhaps an xpath query would be a more advantageous method for finding components by id?

              Just a thought...

              • 4. Re: Client elements not updated after a4j request
                ssilvert

                 

                "bgregory" wrote:
                It seems to be that keeping the ClientIDs up to date is a continuing problem (do I presume too much?). Perhaps an xpath query would be a more advantageous method for finding components by id?

                Just a thought...

                It hasn't been a problem until recently. The reason you are seeing a problem is because of a bug I fixed a couple of weeks ago. Gathering all the ID's from a DataTable when there are LOTS of undisplayed rows caused a big performance hit. So I changed ClientIDs to only find rows that were displayed. But with AJAX, you can start displaying rows that were previously undisplayed without changing the view. That causes the ID's to never make it into ClientIDs. At least that's what I think is happening.

                Anyhow, I think your idea about using xpath is probably very good. I'll still need to use the old ClientIDs class for the server side, but xpath might be better for the client side. I'll look into it.

                Stan

                • 5. Re: Client elements not updated after a4j request

                  Understood. I've been thinking about it since we originally discussed that problem.

                  Something to keep in mind about datatables, and perhaps other data-driven controls, is that you can't count on anything that isn't rendered to be correctly renderable. For example, the data supporting non-displayed datatable rows isn't even queried in most cases, so they'll be blank or at least mis-labeled (since the ids are derrived from the row key, and the row key may not be loaded). Also, when a control causes the backing data to re-queried, the rendered controls may not have even existed before, even in the set of non-rendered controls.

                  It seems a bit tricky to me...thoughts?

                  • 6. Re: Client elements not updated after a4j request
                    ssilvert

                     

                    "bgregory" wrote:
                    It seems a bit tricky to me...thoughts?

                    My thought is that I agree it is tricky. :-)

                    So if I can get xpath working on the client, that should cover everything you need on the client side, right?

                    Then the tricky stuff only matters on the server side. What I care about on the server side is being able to look up any component in the component tree. Easy access to server-side artifacts is where JSFUnit really shines, IMO.

                    So we just need to think about use cases where the ClientIDs class falls short in that regard. I've known all along that ClientIDs is not very efficient, but it's already pretty complex and I'd like to keep it as simple as possible. So if we want to change it, I'd like to get some solid use cases I can put into the JSFUnit test suite.

                    Stan

                    • 7. Re: Client elements not updated after a4j request

                      Regarding ClientIDs, I also ran into a case where rendered components in a rich:dataTable footer aren't available in ClientIDs. In this test, the footer contains columnGroup/columns which contain user input fields.

                      To get around this, I got the dataTable element via JSFClientSession.getElement(), got the component in question from the dataTable element via HtmlTable.getHtmlElementById(), then accessed the component directly.

                      Justin.

                      • 8. Re: Client elements not updated after a4j request

                        Stan: Yes, I understand and agree. May require some thought. Since we are currently building a rather large test suite, I'll take notes as we go.

                        Thanks for the continued support...

                        • 9. Re: Client elements not updated after a4j request
                          ssilvert

                          JSFClientSession is now using XPath instead of the ClientIDs class. Thanks for the suggestion.

                          Stan

                          • 10. Re: Client elements not updated after a4j request

                            Ok, I've run our test suite with the latest from svn and there seems to be a number of cases where the components can not longer be found. One case I think I know what's going on (the control isn't rendered), and I think there's another case where a form is submitted, the action sets a message and returns null, therefore the page is reloaded, but the next client.setValue() fails when attempting to find the input control. There are other cases where I'm not entirely sure what's going on.

                            I will try nail these down a bit more.

                            • 11. Re: Client elements not updated after a4j request

                              I'm still unable to completely nail this down, but it appears that in a great many places [in our tests] where the control lookup (client.getElement()) fails (returns null for a component that is definately on the page) the client.getContentPage() returns the following blank page:

                              <?xml version="1.0" encoding="ISO-8859-1"?>
                              <html/>
                              


                              It appears that for some strange reason the content pages is being wiped out after a click() or setValue() or some other operation. I will try to nail it down some more when I have time.

                              • 12. Re: Client elements not updated after a4j request
                                ssilvert

                                Hmm. That would be easy enough find out. Just go to the code for JSFClient session and change the webWindowChanged() method so that it doesn't update the contentPage for a blank HTML.

                                I suspect that this is a case where HtmlUnit should not be firing a WebWindowEvent.

                                Sorry, but I won't be able to be as responsive this week as I was last week.

                                Stan

                                • 13. Re: Client elements not updated after a4j request

                                  Thanks for the heads up, here is the modification that I made:
                                  (When you get some time, let me know if there's anything I've missed)

                                   public void webWindowContentChanged(WebWindowEvent webWindowEvent)
                                   {
                                   Page page = webWindowEvent.getNewPage();
                                   if(page instanceof HtmlPage) {
                                   HtmlPage ht = (HtmlPage)page;
                                   if( ht.getDocumentElement().hasChildNodes() )
                                   this.contentPage = page;
                                   }
                                   }
                                  


                                  • 14. Re: Client elements not updated after a4j request

                                    After looking at this futher, I'm not entirely sure this is bad behavior.
                                    Here is a dump of the "unexpected" WebWindowEvents:

                                    WebWindowEvent(source=[FrameWindow[name=""]] type=[CHANGE] oldPage=[null] newPage=[HtmlPage(about:blank)@4321717])

                                    WebWindowEvent(source=[FrameWindow[name=""]] type=[CHANGE] oldPage=[HtmlPage(about:blank)@4321717] newPage=[HtmlPage(javascript:'')@5377162])

                                    The 1st one is usually followed by the second (not directly, but shortly after).

                                    Note source is "FrameWindow" instead of "TopLevelWindow" and the first page title is "about:blank" (standard for IE6?) plus the second being "javacsript:". I'm sure one of the links being actuated on the page under test has a target="" attribute, but I don't think these showed up at that point in the test. Also, no other action on this page should be opening a new window.

                                    Strange.... ?