ICEfaces
  1. ICEfaces
  2. ICE-9137

ace:comboBox and ace:autoCompleteEntry js errors

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.2
    • Fix Version/s: 3.3
    • Component/s: ACE-Components
    • Labels:
      None
    • Environment:
      MyFaces, Mojarra
    • Assignee Priority:
      P1

      Description

      The comboBox and autoCompleteEntry have javascript errors in the console when navigating between examples of the respective components. The exceptions vary depending on which sample is browsed from and to, and whether Mojarra or MyFaces is used.

      [window] Error [status: sendError code: 0]: undefined
      http://localhost:8080/showcase/javax.faces.resource/bridge.js.jsf?ln=ice.core&v=3_3_0_130403
      Line 1

      TypeError: at is undefined
      http://localhost:8080/showcase/javax.faces.resource/bridge.js.jsf?ln=ice.core&v=3_3_0_130403
      Line 1

      TypeError: s is undefined

      What I've found is that it's easiest to reproduce the issue with comboBox, by going to one comboBox example, showing the popup, and while it's still displaying, clicking to go to another comboBox example. 100% of the time one of those exceptions will occur. I recommend using MyFaces.

      The hope is that with te shared javascript, a comboBox fix will also fix autoCompleteEntry, or illuminate a fix for it as well.

        Activity

        Hide
        Arturo Zambrano added a comment -

        The autoCompleteEntry, comboBox and selectMenu components fire their onBlur handlers via a timeout function. So, it seems that this problem is related to this characteristic. If the options list is still open and the user navigates to a different demo (using the showcase's navigation style), then the objects of the first demo might not be there, and errors will be shown in the console. Perhaps this could be simply solved by adding try-catch clauses or by checking if the related objects are still in memory.

        Show
        Arturo Zambrano added a comment - The autoCompleteEntry, comboBox and selectMenu components fire their onBlur handlers via a timeout function. So, it seems that this problem is related to this characteristic. If the options list is still open and the user navigates to a different demo (using the showcase's navigation style), then the objects of the first demo might not be there, and errors will be shown in the console. Perhaps this could be simply solved by adding try-catch clauses or by checking if the related objects are still in memory.
        Hide
        Arturo Zambrano added a comment - - edited

        I found out and confirmed that this error only happens with components that have an ace:ajax 'blur' event. That's also why the error is reported to be in the bridge code. If I made the timeout for the 'blur' ajax request longer, then the error took longer to appear. It also seems to happen while preparing the request, not in the response, since I placed alert calls before and after the ice.ace.ab call, and only the alert before the ajax call appears, and no request is actually made.

        There doesn't seem much we can do about it. I've tried using a try-catch clause, but the error continues to appear in the console. I've tried to check to see if the root node or the containing form are still on the page (in order to avoid sending the request if they aren't), but they are still in memory and apparently still in the DOM, with the showcase's navigation style. The only thing that worked was using !jQuery.is(':hidden'), but for that to work, the timeout needs to be much longer, like more than a second, otherwise the timeout function fires while the component is still visible and the ice.ace.ab call is made, which fails at some point while the new demo/page is loaded.

        Show
        Arturo Zambrano added a comment - - edited I found out and confirmed that this error only happens with components that have an ace:ajax 'blur' event. That's also why the error is reported to be in the bridge code. If I made the timeout for the 'blur' ajax request longer, then the error took longer to appear. It also seems to happen while preparing the request, not in the response, since I placed alert calls before and after the ice.ace.ab call, and only the alert before the ajax call appears, and no request is actually made. There doesn't seem much we can do about it. I've tried using a try-catch clause, but the error continues to appear in the console. I've tried to check to see if the root node or the containing form are still on the page (in order to avoid sending the request if they aren't), but they are still in memory and apparently still in the DOM, with the showcase's navigation style. The only thing that worked was using !jQuery.is(':hidden'), but for that to work, the timeout needs to be much longer, like more than a second, otherwise the timeout function fires while the component is still visible and the ice.ace.ab call is made, which fails at some point while the new demo/page is loaded.
        Hide
        Arturo Zambrano added a comment -

        I found something that worked. Adding the following script to the blur ajax event prevents the errors from showing in the console:

        onStart="setTimeout(function(){cfg.onstart = null; try

        {ice.ace.ab(cfg);}

        catch(e){}},50); return false;"

        It basically cancels the current ajax requests and creates another one via a timeout. It delays the request 50 milliseconds more (to a total of 250) and puts the call to ice.ace.ab in a try-catch clause. This time the try-catch clause is able to prevent showing the errors.

        Show
        Arturo Zambrano added a comment - I found something that worked. Adding the following script to the blur ajax event prevents the errors from showing in the console: onStart="setTimeout(function(){cfg.onstart = null; try {ice.ace.ab(cfg);} catch(e){}},50); return false;" It basically cancels the current ajax requests and creates another one via a timeout. It delays the request 50 milliseconds more (to a total of 250) and puts the call to ice.ace.ab in a try-catch clause. This time the try-catch clause is able to prevent showing the errors.
        Hide
        Arturo Zambrano added a comment -

        Committed fix at revision 34264.

        After trying different things, I came up with a fix in the component code itself, and not in the app code. It wasn't actually necessary to use the onStart callback in the 'blur' ajax event, but to simply increase the lengths of the timeouts in the onBlur handler of the component and surrounding the ajax call inside a try-catch clause.

        These components have two timeouts: one for setting the inField label (when there is one) and another to send the 'blur' ajax request (when there is one too). The timeout length for the ajax request has to be long enough to trigger the request once the user has navigated to the new page and short enough for the component to still feel responsive. At the same time, the timeout length for the ajax call has to be shorter than the one for the inField label, because otherwise the label string would be submitted as the value of the component. I found that having timeout lengths of 400 and 390 milliseconds, respectively, prevents the errors from showing in all major browsers, as I wasn't able to reproduce these issues with these new settings.

        Show
        Arturo Zambrano added a comment - Committed fix at revision 34264. After trying different things, I came up with a fix in the component code itself, and not in the app code. It wasn't actually necessary to use the onStart callback in the 'blur' ajax event, but to simply increase the lengths of the timeouts in the onBlur handler of the component and surrounding the ajax call inside a try-catch clause. These components have two timeouts: one for setting the inField label (when there is one) and another to send the 'blur' ajax request (when there is one too). The timeout length for the ajax request has to be long enough to trigger the request once the user has navigated to the new page and short enough for the component to still feel responsive. At the same time, the timeout length for the ajax call has to be shorter than the one for the inField label, because otherwise the label string would be submitted as the value of the component. I found that having timeout lengths of 400 and 390 milliseconds, respectively, prevents the errors from showing in all major browsers, as I wasn't able to reproduce these issues with these new settings.
        Hide
        Carmen Cristurean added a comment -

        Re-tested autoCompleteEntry and ComboBox components in showcase with revision# 34269 in Firefox19 and IE9, and the JS errors could not be reproduced any longer.

        Show
        Carmen Cristurean added a comment - Re-tested autoCompleteEntry and ComboBox components in showcase with revision# 34269 in Firefox19 and IE9, and the JS errors could not be reproduced any longer.

          People

          • Assignee:
            Arturo Zambrano
            Reporter:
            Mark Collette
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: