Wicket
  1. Wicket
  2. WICKET-1646

AjaxFormComponentUpdatingBehavior not working correctly when using IE 7

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.3.4, 1.4-M3
    • Fix Version/s: 1.3.4, 1.4-M3
    • Component/s: wicket
    • Labels:
      None
    • Environment:
      OS: Windows XP SP2
      ServletContainer: Jetty 6.1.6
      Browser: IE 7

      Description

      AjaxFormComponentUpdatingBehavior works with Firefox, but doesn't work when using IE7.
      I also observed similar problems when using AjaxEventBehavior as well.
      The error returned via the ajax debug console was: "Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it".

      Below is a simple example that should demonstrate the problem.

      Example.java
      ============================================================
      package example.page;

      import org.apache.wicket.ajax.AjaxRequestTarget;
      import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
      import org.apache.wicket.markup.html.WebPage;
      import org.apache.wicket.markup.html.basic.Label;
      import org.apache.wicket.markup.html.form.Form;
      import org.apache.wicket.markup.html.form.TextField;
      import org.apache.wicket.model.CompoundPropertyModel;
      import org.apache.wicket.model.PropertyModel;

      public class Example extends WebPage {
      private int age;

      public Example() {
      Form form = new Form("form", new CompoundPropertyModel(this));
      add(form);

      final Label label = new Label("label", new PropertyModel(this, "age"));
      label.setOutputMarkupId(true);
      add(label);

      final TextField age = new TextField("age");
      age.add(new AjaxFormComponentUpdatingBehavior("onblur") {

      /**

      • */
        private static final long serialVersionUID = 1L;

      protected void onUpdate(AjaxRequestTarget target)

      { System.out.println("onUpdate triggered"); target.addComponent(label); }

      });
      form.add(age);
      }

      public int getAge()

      { return age; }

      public void setAge(int age)

      { this.age = age; }

      }

      Example.html
      ==================================================
      <html>
      <head>
      <title>Test</title>
      </head>
      <body>

      <div>
      <label wicket:id="label">My Label Goes Here</label>
      </div>
      <form wicket:id="form">
      <div>Age: <input type="text" wicket:id="age" /></div>
      <div>
      <input type="submit" value="Submit" />
      </div>
      </form>
      </body>
      </html>

        Activity

        Hide
        Frank Bille Jensen added a comment -

        It should work now, but it of cause needs to be tested on other browsers to make sure that we haven't introduced some new weirdness.

        Show
        Frank Bille Jensen added a comment - It should work now, but it of cause needs to be tested on other browsers to make sure that we haven't introduced some new weirdness.
        Hide
        Brian Diekelman added a comment -

        Oh, don't get me wrong. I'm not saying the 'file://' issue is anywhere close to the showstopper in this case. I personally couldn't imagine a scenario where I'd use that in a production application.

        The issue is that right now we use either the native XMLHttpRequest or the ActiveX implementation. I'm saying that 'either/or' isn't the right way to go. We need to try to use the best one for the browser (based on capability detection, not browser sniffing), then fall back to the other if our first choice isn't available.

        I referenced the jQuery example because it's simple and it works. As of now the code checked into subversion doesn't work on a large number of computers (as posted above, anywhere with restricted IE settings). On top of that, our stuff used to work until a fairly recent change that added the 'Wicket.Browser.isIE7() && ' between 1.3.3 and current trunk (I noticed it in 1.4-M1/M2).

        I say at least revert back to the 1.3.3 code. That didn't appear to have any compatibility issues and the changed code doesn't appear to have any benefits.

        Show
        Brian Diekelman added a comment - Oh, don't get me wrong. I'm not saying the 'file://' issue is anywhere close to the showstopper in this case. I personally couldn't imagine a scenario where I'd use that in a production application. The issue is that right now we use either the native XMLHttpRequest or the ActiveX implementation. I'm saying that 'either/or' isn't the right way to go. We need to try to use the best one for the browser (based on capability detection, not browser sniffing), then fall back to the other if our first choice isn't available. I referenced the jQuery example because it's simple and it works. As of now the code checked into subversion doesn't work on a large number of computers (as posted above, anywhere with restricted IE settings). On top of that, our stuff used to work until a fairly recent change that added the 'Wicket.Browser.isIE7() && ' between 1.3.3 and current trunk (I noticed it in 1.4-M1/M2). I say at least revert back to the 1.3.3 code. That didn't appear to have any compatibility issues and the changed code doesn't appear to have any benefits.
        Hide
        Matej Knopp added a comment -

        What's the usecase of file:// URLs anyway? I don't really think such thing can work in any but the qute specific circumstances.

        Show
        Matej Knopp added a comment - What's the usecase of file:// URLs anyway? I don't really think such thing can work in any but the qute specific circumstances.
        Hide
        Brian Diekelman added a comment - - edited

        Just in case that link dies later, the issue was that the 'file://' protocol with the IE7 native XMLHttpRequest doesn't work (and does work with the ActiveX object).

        So I guess at this point, what reason is there to use the native implementation on IE7 other than if ActiveX is disabled? I don't see any benefits.

        Show
        Brian Diekelman added a comment - - edited Just in case that link dies later, the issue was that the 'file://' protocol with the IE7 native XMLHttpRequest doesn't work (and does work with the ActiveX object). So I guess at this point, what reason is there to use the native implementation on IE7 other than if ActiveX is disabled? I don't see any benefits.
        Hide
        Frank Bille Jensen added a comment -

        Brian: The comment you made about JQuery is interesting. I have checked the jquery svn (http://dev.jquery.com/changeset/1627) and it points to this issue:

        http://dev.jquery.com/ticket/963

        Show
        Frank Bille Jensen added a comment - Brian: The comment you made about JQuery is interesting. I have checked the jquery svn ( http://dev.jquery.com/changeset/1627 ) and it points to this issue: http://dev.jquery.com/ticket/963
        Hide
        Brian Diekelman added a comment -

        Good info. Thanks Lonnie.

        I was concerned about compatibility of the MSXML object, so I looked this up: http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx

        To keep it here for posterity:

        • MSXML 6.0 - it is "in the box" on Vista and available for download on Win2k, XP, and 2003. It has the best security, performance, reliability, and W3C conformance
        • MSXML 3.0 is our preferred "fallback" - It is installed on every OS from a fully patched Win2k SP4 installation on up, so it requires "zero-deployment" and is serviced regularly with the OS
        • MSXML 4.0 was released to the web about 5 years ago, but at this point has been superseded by MSXML 6.0 and is only intended to support legacy applications
        • MSXML 5.0 for Microsoft Office Applications is purpose-built for Office applications and isn't intended for broad deployment. Internet Explorer 7 actually has the MSXML5 components "off-by-default" in the Internet zone so your customers will get a goldbar for each MSXML5 control on a page if your code tries to instantiate it. The best recommendation is to avoid MSXML5 in your web apps (only machines with Office 2003 or higher will have it, anyway.).
        Show
        Brian Diekelman added a comment - Good info. Thanks Lonnie. I was concerned about compatibility of the MSXML object, so I looked this up: http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx To keep it here for posterity: MSXML 6.0 - it is "in the box" on Vista and available for download on Win2k, XP, and 2003. It has the best security, performance, reliability, and W3C conformance MSXML 3.0 is our preferred "fallback" - It is installed on every OS from a fully patched Win2k SP4 installation on up, so it requires "zero-deployment" and is serviced regularly with the OS MSXML 4.0 was released to the web about 5 years ago, but at this point has been superseded by MSXML 6.0 and is only intended to support legacy applications MSXML 5.0 for Microsoft Office Applications is purpose-built for Office applications and isn't intended for broad deployment. Internet Explorer 7 actually has the MSXML5 components "off-by-default" in the Internet zone so your customers will get a goldbar for each MSXML5 control on a page if your code tries to instantiate it. The best recommendation is to avoid MSXML5 in your web apps (only machines with Office 2003 or higher will have it, anyway.).
        Hide
        Lonnie Fulton added a comment -

        This is what i currently do. I followed microsofts documentation on how to fallback to using a ActiveX object if native XMLHTTP is disabled (http://msdn.microsoft.com/en-us/library/ms537505(VS.85).aspx) and simply added the following to wicket-ajax.js. You just need to make sure this snippet is inserted before Wicket.Ajax = { ... is called.

        /**

        • Check to see if the native XMLHttpRequest has been disabled for IE7,
        • if so fallback to using the ActiveXObject.
          */
          if (Wicket.Browser.isIE7() && !window.XMLHttpRequest) {
          window.XMLHttpRequest = function()
          Unknown macro: { try { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); } catch (ex) { return null; } }

          }

        I have been using this for awhile on our production server and have had no problems. I hope this can be incorporated into 1.3.4.

        Show
        Lonnie Fulton added a comment - This is what i currently do. I followed microsofts documentation on how to fallback to using a ActiveX object if native XMLHTTP is disabled ( http://msdn.microsoft.com/en-us/library/ms537505(VS.85).aspx ) and simply added the following to wicket-ajax.js. You just need to make sure this snippet is inserted before Wicket.Ajax = { ... is called. /** Check to see if the native XMLHttpRequest has been disabled for IE7, if so fallback to using the ActiveXObject. */ if (Wicket.Browser.isIE7() && !window.XMLHttpRequest) { window.XMLHttpRequest = function() Unknown macro: { try { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); } catch (ex) { return null; } } } I have been using this for awhile on our production server and have had no problems. I hope this can be incorporated into 1.3.4.
        Hide
        Brian Diekelman added a comment - - edited

        So what about something like:

        Wicket.Ajax = {
        // Creates a new instance of a XmlHttpRequest
        createTransport: function() {
        var transport = null;

        if (window.ActiveXObject)

        { transport = new ActiveXObject("Microsoft.XMLHTTP"); }

        if (transport == null && window.XMLHttpRequest)

        { transport = new XMLHttpRequest(); }

        if (transport == null)

        { Wicket.Log.error("Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it."); }

        return transport;
        },

        Still tries to default to ActiveX, but if it's not available reverts to native?

        Show
        Brian Diekelman added a comment - - edited So what about something like: Wicket.Ajax = { // Creates a new instance of a XmlHttpRequest createTransport: function() { var transport = null; if (window.ActiveXObject) { transport = new ActiveXObject("Microsoft.XMLHTTP"); } if (transport == null && window.XMLHttpRequest) { transport = new XMLHttpRequest(); } if (transport == null) { Wicket.Log.error("Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it."); } return transport; }, Still tries to default to ActiveX, but if it's not available reverts to native?
        Hide
        Brian Diekelman added a comment -

        Unfortunately the code that fixed Jarmar's IE7 broke ours.

        We're on a similarly locked down configuration of IE 7 within our organization. In this case this is going to break in any large organization that has ActiveX objects disabled.

        Removing 'Wicket.Browser.isIELessThan7() &&' (as in Wicket 1.3.3) fixes the issue.

        Because of how a lot of organizations lock down IE, it really should try as many options as possible before failing. For instance, here's how a few ajax libraries do it:

        MooTools:

        return $try(function()

        { return new XMLHttpRequest(); }

        , function()

        { return new ActiveXObject('MSXML2.XMLHTTP'); }

        );

        • '$try' looks weird because it's a cross browser abstraction
        • this will try to use a native XMLHttpRequest first, if that fails in any way it will revert to the ActiveXObject

        JQuery:
        // Create the request object; Microsoft failed to properly
        // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
        var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();

        • those comments are from the jQuery devs... maybe they know something we don't? They get a lot more eyes on their ajax stuff than we do...
        Show
        Brian Diekelman added a comment - Unfortunately the code that fixed Jarmar's IE7 broke ours. We're on a similarly locked down configuration of IE 7 within our organization. In this case this is going to break in any large organization that has ActiveX objects disabled. Removing 'Wicket.Browser.isIELessThan7() &&' (as in Wicket 1.3.3) fixes the issue. Because of how a lot of organizations lock down IE, it really should try as many options as possible before failing. For instance, here's how a few ajax libraries do it: MooTools: return $try(function() { return new XMLHttpRequest(); } , function() { return new ActiveXObject('MSXML2.XMLHTTP'); } ); '$try' looks weird because it's a cross browser abstraction this will try to use a native XMLHttpRequest first, if that fails in any way it will revert to the ActiveXObject JQuery: // Create the request object; Microsoft failed to properly // implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest(); those comments are from the jQuery devs... maybe they know something we don't? They get a lot more eyes on their ajax stuff than we do...
        Hide
        Jarmar Fowler added a comment -

        I determined that the cause of my issue was related to a browser setting. Native XMLHttp was not enabled.
        Unfortunately, this option is disabled for everyone in my company by default. Would it be possible to try and use
        native XMLHttp for IE7 by default, but if the XMLHttpRequest object is null fallback to the old approach? The code in question
        is in wicket-ajax.js (see snippet below).

        /**

        • The Ajax class handles low level details of creating and pooling XmlHttpRequest objects,
        • as well as registering and execution of pre-call, post-call and failure handlers.
          */
          Wicket.Ajax = {
          // Creates a new instance of a XmlHttpRequest
          createTransport: function() {
          var transport = null;
          if (Wicket.Browser.isIELessThan7() && window.ActiveXObject) { transport = new ActiveXObject("Microsoft.XMLHTTP"); }

          else if (window.XMLHttpRequest)

          { transport = new XMLHttpRequest(); }

        if (transport == null)

        { Wicket.Log.error("Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it."); }


        return transport;
        },

        Show
        Jarmar Fowler added a comment - I determined that the cause of my issue was related to a browser setting. Native XMLHttp was not enabled. Unfortunately, this option is disabled for everyone in my company by default. Would it be possible to try and use native XMLHttp for IE7 by default, but if the XMLHttpRequest object is null fallback to the old approach? The code in question is in wicket-ajax.js (see snippet below). /** The Ajax class handles low level details of creating and pooling XmlHttpRequest objects, as well as registering and execution of pre-call, post-call and failure handlers. */ Wicket.Ajax = { // Creates a new instance of a XmlHttpRequest createTransport: function() { var transport = null; if (Wicket.Browser.isIELessThan7() && window.ActiveXObject) { transport = new ActiveXObject("Microsoft.XMLHTTP"); } else if (window.XMLHttpRequest) { transport = new XMLHttpRequest(); } if (transport == null) { Wicket.Log.error("Could not locate ajax transport. Your browser does not support the required XMLHttpRequest object or wicket could not gain access to it."); } return transport; },
        Hide
        Johan Compagner added a comment -

        i think that you have security settings or policy settings in IE that is a bit to restrictive

        all examples i test for IE7 work fine.

        Show
        Johan Compagner added a comment - i think that you have security settings or policy settings in IE that is a bit to restrictive all examples i test for IE7 work fine.

          People

          • Assignee:
            Frank Bille Jensen
            Reporter:
            Jarmar Fowler
          • Votes:
            3 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development