17

If I'm clearing a form with 5 or more fields in IE11 using $('form input').val("") IE11 will crash. HTML:

<form>
    <label>1</label><input type="text"/>
    <label>2</label><input type="text"/>
    <label>3</label><input type="text"/>
    <label>4</label><input type="text"/>
    <label>5</label><input type="text"/>
</form>

JS:

$(document).ready(function(){
    $('#clearFormNormal').click(function(){
        $("form input").val("");
    });
});

When I'm doing this recursive and with a setTimeout it works.

JS:

function clearFields (counter) {
    var i = counter || 0, deferred = new $.Deferred();
    if ($("form input").eq(i).length === 1){
        setTimeout(function(){
            $("form input").eq(i).val("");
            i = i + 1;
            clearFields(i).always(function(){
                deferred.resolve();
            });
        },0);
    } else {
        deferred.resolve();
    }
    return deferred.promise();
}

$(document).ready(function(){
    $('#clearFormSetTimeout').click(function(){
        clearFields();
    });
});

See the http://jsfiddle.net/fransoverbeek/Cy5D5/7/ as well

Is this an IE11 bug?

user3114524
  • 173
  • 1
  • 6

6 Answers6

6

I believe that this is an IE bug and I have created the following connect bug report: https://connect.microsoft.com/IE/feedback/details/811930/ie11-crash-when-clearing-multiple-input-fields-with-jquery

I have added a slightly modified version of your recursive function there as a work around. The function is slightly more generic and looks like this:

function clearFields (counter, selector) {
    var i = counter || 0, deferred = new $.Deferred();
    if (selector.eq(i).length === 1){
        setTimeout(function(){
            selector.eq(i).val("");
            i = i + 1;
            clearFields(i, selector).always(function(){
                deferred.resolve();
            });
        },0);
    } else {
        deferred.resolve();
    }
    return deferred.promise();
}

$(document).ready(function(){
    $('#clearFormNormal').click(function(){
        $("form input").val("");
    });
    $('#clearFormSetTimeout').click(function(){
        clearFields(0, $("form input"));
    });
});

Please up-vote the connect issue.

How the clearFields function works:

First, note that I did not write the original function this was based off of, so the why of it working is only conjecture on my part.

The clearFields function is a recursive function. Each time it runs, it takes two parameters: counter (which is the index in the set of fields to be cleared) and selector (the jquery object that contains the set of fields to be cleared)

The function creates looks at the element specified by counter in the set of DOM elements specified by selector. If such an element exists, then it creates an asynchronous setTimeout which will clear that element. This async function then increments counter (which is called i here) and recursively calls clearFields. I believe that the recursiveness is key because I tried using just a setTimeout in a loop and it didn't work.

The recursion stops when counter goes past the index of the last element in the collection which is when selector.eq(counter).length !== 1

I think this function could further be improved by swapping the order of counter and selector parameters so that counter would be optional for the first call.

I have never needed to use the jQuery deferred code before, so I don't know what role that plays in this function.

Redbaran
  • 570
  • 2
  • 6
  • 11
  • I am having the same problem (http://stackoverflow.com/questions/20787807/html-forms-crash-ie-11) . Is there a simpler version of your solution? Or a JS version? I want to try it , but I dont know how, because I am new to JQuery, meaning I dont quite get it. Thanks a bunch – slevin Dec 27 '13 at 19:44
  • 1
    Please describe what's going on here. I'm having a similar issue in a project without jQuery and would like to implement the spirit of this solution. My assumption is that each field is cleared asynchronously, but the jQuery Deferred object promises that all operations are complete before returning control. I also assume that setTimeout triggers some sort of internal cleanup, so that the form is in a known state upon return. Are those assumptions correct? – J.D. Pace Dec 30 '13 at 18:12
  • @J.D.Pace I think your assumptions are correct about how Deferred objects work, but I've never used it directly, it was just in the code provided that I modified. I too assume that the setTimeout is what is causing the cleanup and "fixing" the IE11 problem. However, I tried it without the recursive call and it didn't work for me, so I'm not too sure. – Redbaran Jan 02 '14 at 20:33
  • If it helps anyone, here's a pure-JS version of the JSFiddle provided in the bug report. Haven't experimented yet to see if a simpler version exists. http://jsfiddle.net/dahjelle/s2Ch3/4/ – David Alan Hjelle Jan 09 '14 at 22:17
  • Tried your fiddle, does not crash my IE 11.0.2 (on win7) – Antwan Jan 10 '14 at 15:02
  • This was fixed yesterday as part of Windows Updates. Hooray! :-D – David Alan Hjelle Feb 12 '14 at 14:34
  • As of 2014, Feb 12, the newest IE appears to be IE 11.0.9600.16476, and this problem still exists in this version. – Mir Feb 13 '14 at 00:14
5

I believe it is a bug of IE and it is not related to jQuery, as you can simply show it by the following html page like:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>    
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"></meta>
    <title>test</title>
  </head>
  <body>
  <form id="form_1">
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="text" value="" size="10"/><br/>
  <input type="button" value="reset" onclick="document.getElementById('form_1').reset();">
  </form>.
  </body>
</html>

One can find that IE 11 will crash after you reset the form.

3

try

 $(':input',"#" + form.id)
  .not(':button, :submit, :reset, :hidden')
  .val('');

or

$("#" + form.id)[0].reset();

check this Clearing file input box in Internet Explorer

Community
  • 1
  • 1
Barno
  • 3,271
  • 5
  • 28
  • 58
2

The fix for this bug was included in the IE updates for February 2014 released today on Windows Update.

adrianba
  • 341
  • 1
  • 3
1

I think this is a bug in Internet Explorer 11. I reported a similar bug on Microsoft Connect. I was able to reproduce the issues I encountered both with and without jQuery.

On the bug report, there is a very simple (and quite surprising) workaround (discovered by philbee21). Before assigning the empty string, first set the value to a single space:

fields.forEach(function (field) {
    field.value = ' ';
    field.value = clearValue;
});

I have created an updated fiddle.

Phil Ross
  • 25,590
  • 9
  • 67
  • 77
0

This appears to fix the issue:

$(document).ready(function(){
    $('#clearFormNormal').click(function(){
        $("form input").val($("form input").val());
        $("form input").val("");
    });
});

I am not sure why, but my theory is that setting the field value to it's current value resets a reference that was null.

Check out the JS Fiddle here: http://jsfiddle.net/Cy5D5/22/

Barlow Tucker
  • 6,229
  • 3
  • 36
  • 42