Setting the “name” attribute in Internet Explorer

I have recently needed to write code that uses JavaScript to add elements dynamically to a web page on the client. I read the relevant W3C documents and wrote the code, and it seemed to work fine. Until I tried it on Internet Explorer. After some digging, I found an explanation in the MSDN DHTML reference, on the page describing the NAME Attribute.

The NAME attribute cannot be set at run time on elements dynamically created with the createElement method. To create an element with a name attribute, include the attribute and value when using the createElement method.

The trouble is that including attributes in calls to createElement is a Microsoft-only extension. If you try to do this (e.g. document.createElement("<input name='brian'>")), there are at least three possible outcomes:

  • The browser throws an exception because “<input name=’brian’>” is not a valid element type. This is the correct behaviour.
  • The browser creates an element with type = “input” and name = “brian”. This is what IE 6 does.
  • The browser creates an element with the invalid type = “<input name=’brian’>”. This is what Netscape 7.1 and Opera 8.5 do. Thanks to Kristof for pointing this out.

So if you want to create named elements dynamically, you have to be a bit crafty. It’s no good trying the correct approach first, because this will fail on IE6 with no way for your code to check. Therefore, I first attempt to create the element by including the name attribute in the call to createElement, and check the result. If it checks out OK, then I’m probably running on IE6 and all is well. Otherwise, I just try again using the correct method of creating the element and then setting the name.

Here’s the function I came up with that allows you to create named elements on any browser. Pass it the name and type of the element you want to create. I have tested this on various Windows browsers: IE5, 5.5 and 6; Firefox 1 and 1.5; Mozilla 1.7; Netscape 7.1 and 8; and Opera 7.23 and 8.5. Please let me know if you notice problems on these or any other browser.

function createNamedElement(type, name) {
   var element = null;
   // Try the IE way; this fails on standards-compliant browsers
   try {
      element = document.createElement('<'+type+' name="'+name+'">');
   } catch (e) {
   }
   if (!element || element.nodeName != type.toUpperCase()) {
      // Non-IE browser; use canonical method to create named element
      element = document.createElement(type);
      element.name = name;
   }
   return element;
}

This code doesn’t use browser-sniffing techniques. Instead it simply tries to create the element using the Internet Explorer method first; if this fails it uses the standard method.

Note also that there are problems setting the name attribute even on static elements:

Microsoft JScript allows the name to be changed at run time. This does not cause the name in the programming model to change in the collection of elements, but it does change the name used for submitting elements.

Be sure to test thoroughly — don’t just assume it will work (as I did).

Share This | Comments | Permalink | Trackback | Comments feed

35 responses

Other comment pages: « 1 [2]

  • [...] 参考:1、http://www.thunderguy.com/semicolon/2005/05/23/setting-the-name-attribute-in-internet-explorer/2、http://alt-tag.com/blog/archives[...]
  • I am trying to set an onclick event with setAttribute and it works in FF, but it does not with IE6. I solved the problem doing something as it is said here with ‘name’; but I would appreciate any other method, if it is possible.

    Pablo | 9 December 2006
  • First off, great article, I found it very helpful and I think it explains my problem….

    I think the same problem applies to copied elements. I’m creating an input table with an add row function. I copy the previous row, modify some attributes for each cell/column(name, value) that contains an input field and add the row to the end of the table.
    Works great in FF, but in IE7 if I click a radio button in the newly created row, it affects the previous row (the one that was copied).
    But, when I submit the form it saves the data correctly.

    So I assume you can’t modify the name value at all in IE. Any thoughts on this?

    mataichi | 15 December 2006
  • Mataichi, I believe that this will happen in IE6, since you can’t modify the name attribute even on a ciopied element. But it’s interesting that it happens in IE7 too. I haven’t yet tested IE7, but it’s a bit sad if Microsoft still haven’t fixed this.

    Bennett | 10 January 2007
  • Bennett -

    Indeed this, along with number of other long-standing bugs / issues with the DOM, have not been fixed in IE7. See the third message on this blog post from Dave Massy, program manager at Microsoft from another irate developer ;-). He details all of the ones he knows about that haven’t been fixed yet:

    http://blogs.msdn.com/dmassy/archive/2006/11/30/vpc-to-run-ie6-and-ie7-on-the-same-machine.aspx

    Cheers,

    - Bill

    William J. Edney | 11 January 2007
  • It would be much better to check the correct way of creating an element on a specific browser/user-agent only once and not on every single createNamedElement call.

    You should use something like this:

    var createNamedElement=function (){};
    (function () {
    try {
    var el=document.createElement(”); //IE nasty way of creating named elements
    if (el.tagName != ‘DIV’ || el.name != ‘foo’) { throw ‘create element error’; }
    /* else… */
    createNamedElement = function (tag, name) {
    return document.createElement(”);
    };
    } catch (e) { //Good ol’ compliants way
    createNamedElement = function (tag, name) {
    var el = document.createElement(tag); el.name = name; return el;
    }
    }
    })();

    Amplexos.

    diego nunes | 24 January 2007
  • Diego, your approach is inefficient if you only plan to call the createNamedElement function a small number of times (as I do). Your method would indeed be more efficient if you were doing a lot of page manipulation for each page load — in that case the extra speed would be worth the added complexity.

    Bennett | 24 January 2007
  • Thanks for this. Ghod, I hate IE6 sometimes.

    I discovered that the same thing is (apparently) true for the “checked” property. I modified your function slightly to accommodate a “checked” parameter:

    function createNamedElement( type, name, checked ) {

    // Did you know that the IE6 dev team’s DNA is 98% similar to that of humans?

    var element = null;

    // Try the IE way; this fails on standards-compliant browsers
    try {
    element = document.createElement( ” );
    } catch (e) {
    }

    if (!element || element.nodeName != type.toUpperCase()) {
    // Non-IE browser; use canonical method to create named element
    element = document.createElement(type);
    element.name = name;
    element.checked = checked;
    }
    return element;
    }

    greenie2600 | 29 May 2007
  • I LOVE YOU FOR POSTING THIS ARTICLE!

    bhaidaya | 10 August 2007
  • Well, thank you. Even though I wrote this 2 years ago, it’s still relevant today. Last week at work we had a mysterious problem with our web application failing on IE. I pointed the developer at this page and 10 minutes later he had fixed it!

    Bennett | 10 August 2007
  • It has just occurred to me that the function as written may not work if your page is served as application/xhtml+xml. I haven’t tested it, but it seems to me that if your page is served as application/xhtml+xml then you should remove the “.toUpperCase()” from the function.

    If you try this, please let me know how it turns out.

    Bennett | 10 August 2007
  • Bless you for this article! and Thanks a ton!

    nj | 1 September 2007
  • It works…! I was having trouble accessing the dynamically created form elements…Well,it’s solved now..Thanks!

    Jobin Basani | 3 September 2007
  • /*
    This seems to work to create new input elements across browsers, but I welcome your opinions.
    parameters: (pa) a reference to the parent node of the new input, and (attr) an attributes object.
    */

    function Fieldname(pa,attr){
    var el= document.createElement(’input’);
    for(var p in attr) el[p]= attr[p];
    pa.appendChild(el);
    if(el.name) return el;

    //if the ‘name’ was not set, as in IE:
    var el2= document.createElement(’span’);
    var str= ”;
    pa.replaceChild(el2,el);
    return el2.firstChild;
    }
    //test case
    var el= new Fieldname(document.body,
    {type:’text’, name:’newInput’, size:’10′,
    onchange:function(){alert(this.name)}})

    //In practice, the first parameter would refer to a label or fieldset or form element

    mrHoo | 26 October 2007
  • error S:

    ttnet müzik | 4 January 2008
  • //if the ‘error’ was not set, as in IE:
    var el2= document.createElement(’span’);
    var str= ”;
    pa.replaceChild(el2,el);
    return el2.firstChild;
    }

    ttnet mp3 | 4 January 2008
  • I think I may have found another way around this bug.

    I posted the solution I found on my web development blog here:
    http://matts411.com/webdev/cre…..javascript

    Let me know what you guys think.

    Matt

    Matt Murphy | 14 January 2008
  • @Pablo

    You can not set an onclick on an element in IE as an attribute. This is because IE does not see it as an attribute, but as an object. Try e.g.:
    eval(”elem.onclick=’myScript()’”)

    Bert Zwep | 16 January 2008
  • Although still far from perfect, this would be a better solution, only applying the hack to IE, and letting the other browsers work as designed:

    var isOpera, isIE = false;
    if(typeof(window.opera) != ‘undefined’){isOpera = true;}
    if(!isOpera && navigator.userAgent.indexOf(’Internet Explorer’)){isIE = true);

    function createNamedElement(type, name, checked){
    var element = document.createElement(type);
    if(name){
    element.setAttribute(’name’, name);
    }
    if(checked){
    element.setAttribute(’checked’, ‘checked’);
    }
    return element;
    }

    //fix IE
    if(isIE){
    function createNamedElement(type, name, checked){
    var elemStr = ”;
    return document.createElement(elemStr);
    }
    }

    With this, the function is redefined if IE, to handle its broken DOM.

    Harvey | 10 February 2008
  • To set an attribute
    I use getAttribute(”XXX”).value.

    ex:
    var pass = document.getElementById(’txtPassword’); pass.getAttribute(”onfocus”).value = “javascript:blabla()”;

    Tested and worked on FF, IE7, IE6, IE5.5 ….

    tiago.santos | 23 February 2008

Other comment pages: « 1 [2]

Post a comment

(required)
(required)
Close
E-mail It