Another IE Gotcha - Dynamically Created Radio Buttons

As soon as I think I have it all worked out I bump into another oddity between Firefox and IE and handling the DOM. Specifically adding a radio button (or set of them) dynamically.

My initial javascript went something like this:


var rdo = document.createElement('input');
rdo.type = 'radio';
rdo.id = 'someUniqueID';
rdo.name = 'myRadio';
rdo.value = 1;

myDocumentsBody.appendChild(rdo);



This almost worked perfectly. The input was added, it was a radio button, but it was totally unselectable. I could select it via javascript but the normal “click” event didn’t cause the radio button to assume the “selected” state in IE? What gives?

Well, I don’t know what gives but it turns out I can’t assign the type independently of creating a radio control. Instead, I have to create my radio object like so:


var rdo = document.createElement("<input type=\"radio\" name=\"fldID\" >");


By specifying the type during the creation process the radio button was then selectable in the normal manner. This method works inboth IE and FF.

Update: 9 May 2006
Well, as has been reported by many people I was crazy when I said this technique worked in both IE and Firefox. What was I thinking? It doesn’t work in Firefox at all. However, there is a fairly easy solution that will insert a selectable radio button in both IE and Firefox - however, I’m sorry to say, it doesn’t work in Opera. Damn these browsers; well, really, damn IE for not working properly - and damn Opera for not throwing an error when we use IE’s crazy syntax.

So here is the javascript that is needed to create a radio button that will work in IE and Firefox:


try{
rdo = document.createElement('<input type="radio" name="fldID" />');
}catch(err){
rdo = document.createElement('input');
rdo.setAttribute('type','radio');
rdo.setAttribute('name','fldID');
}


Here is a demo page - just view the page source to see what I am doing and how it works. If anyone has a good solution that will work in all three browsers please let me know.

Final Update (18 July 2008) - the demo page is also updated to reflect this change.


try{
rdo = document.createElement('<input type="radio" name="fldID" />');
}catch(err){
rdo = document.createElement('input');
}
rdo.setAttribute('type','radio');
rdo.setAttribute('name','fldID');


That works in IE 7, FF 3, Opera 9, and Safari 3.1 for windows.

Comments

Anonymous
this post saved my ass after 8 hours of work. much much thanks.
Bill Rawlinson
At this point I'm not really trying to keep this working with more modern browsers. I wrote it when IE 7 Was considered modern in 2006.

There are much better ways to do it now. If you're doing a lot of dynamic html consider something like jquery.
Anonymous
not working in in IE9
Peter Laman
I always use this to work around the IE quirks with input elements:

// Stupid way of creating an element, that copes with IE mistreatment of input elements
function createInputElement(arrAttributes)
{
var span = document.createElement("span");
var html = "<input";
for ( var attName in arrAttributes)
{
attValue = arrAttributes[attName];
html += " "+attName + "=\"" + attValue + "\"";
}
html += "/>";
span.innerHTML = html;

// Throw away the span, since we only needed it to create the input!!
var input = span.firstChild;
span.removeChild( input );
return input;
}
thraddash
I looked through most of the comments and didn't see my current dilemma.

I've used the suggested try/catch method for creating dynamic radio buttons… but I found that if you remove the element, or even the parent of the element, and reattach it to the DOM again the radio button is now unselected.

parent.removeChild(radio1);
parent.appendChild(radio1);


I believe this is an IE6/IE7 gotcha, but I still need to support them somewhat.
craig stevens
Hi
This is great, exactly what I am looking for, however (excuse my ignorance) how do you remove the dots at the start of each line?

cheers
Craig
Arvind Kumar
Just take care of that element name while creating the radio button that will solve your problem, don't assign name after creating element that is the problem.

You can find detailed solution here

http://onlyprogrammers.blogspot.com/2010/10/ie6-ie7-radio-button-jquery-problem.html

Arvind Kumar
http://arvindlounge.wordpress.com/
jazzland
Hi Sir, I made me save a lot of waste with your advices many thanks
Regards from Italy
Bill
Patrick, I will take a look at this as soon as I get a chance but that might not be until this evening or tomorrow sorry.
Patrick
Bill,

Please see this link as it is related to this problem: http://www.telerik.com/community/forums/aspnet-ajax/upload/how-can-i-use-a-radiobutton-as-addtional-field.aspx
I'm using a Telerik upload control. I am adding a radio button list for the user to select the type of file that will be uploaded.

Then I want to retrieve the selected button, and hence the value of the radio button list, in my source code.

Protected Sub RadGrid1_UpdateCommand(ByVal source As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs)
Dim upload As RadUpload = TryCast(e.Item.FindControl("RadUpload1"), RadUpload)
Dim proposalNumber As String = TryCast(e.Item.FindControl("lblProposalInEdit"), Label).Text

If upload.UploadedFiles.Count > 0 Then
For Each file As UploadedFile In upload.UploadedFiles

Dim fileType As String = file.GetFieldValue("fileType")

If fileType = "AO" Then
SaveAOFile(upload, file.GetName, proposalNumber)
ElseIf fileType = "Contract" Then
SaveContractFile(upload, file.GetName, proposalNumber)
End If

Next
Else : MsgBox("Please select a file to upload", MsgBoxStyle.Information, "Select a file")
End If
End Sub

I can programmatically specify that one of the buttons is checked and the value shows up the source code, but I still cannot check the buttons when the app is running. I also tried using the innerHTML attribute of a span element, to no avail.

Thanks for your help,
Patrick
Bill
I don't really understand what you're trying to do. Perhaps you can create a very simple demo of your desired functionality (broken still) and point me to it and I can look at it and give you a hand?
Patrick
Thanks so much for all of the great info here. I'm trying to add a group of 2 radio buttons to an upload box and then get the value from the button list. I've tried everything possible and still cannot get the value from my source code. Please help!!

Thanks,
Patrick
Anonymous
thanks a bunch man, saved me alot of code rewriting :D
patrick
Thank’s a lot …
rooter
just wanted to chime in to say thanks! also, you should google ‘createElements’ - great article about a function which allows you to define elements with JSON. I had to modify their code with yours to get the radio buttons to work :)
valli
Excellent. I could not make radio buttons work in IE, and some page said you cant. I just checked browser and if IE, then do it with html and if Firefox or others, normally create the radio button(s).
Kevin
AWESOME! I could’ve spent hours on this if I didn’t find your page! Thanks!
dan
thanks for this write-up! it saved my morning!
Chris Sladky
RM-if you’re having any issues with setting radios to checked, be sure you add them to the page first. I was having weird issues with making radios checked in both firefox 2 and IE. After some Googling, I learned that if you add them to the page first, then select what you just added to the page and mark those as checked, the issues disappear.
Hope that helps!
Bill
RM - if you want to make a radio button checked you need to use the “CHECKED” attribute. Changing the value attribute will just mess you up when you submit the form and this odd value is passed on.
John Trupiano
Thanks, you saved me loads of time today!
RM
But to make it selected via the javascript, do you use the “value” or the “checked” attribute?
Bill
Chris Sladky’s suggested fix works fine in all four browsers on windows so I updated the post to include that change.
live_fiercely
Great post, it saved me about an hour of digging around the web and cursing IE - AGAIN.

I tried your solution in IE7, IE6, IE5.5, FF, and Safari; worked perfect in all of those.

Thanks for the help.

Algie
Chris Sladky
Sorry for the double-post; I got the bracket directions wrong last time.

Opera fix here:
Simply leave in the rdo.setAttribute(“name”, “yourNameHere”) line-IE ignores it and it works with firefox and opera. Basically, move the line “rdo.setAttribute(‘name’,’fldID’);” out of the catch loop. Actually, you don’t have to set type in the catch loop either.
The following is the changed code that should work across browsers:
try{
rdo = document.createElement(‘<input name=”fldID” />’);
}catch(err){
rdo = document.createElement(‘input’);
}
rdo.setAttribute(‘name’,’fldID’);
rdo.setAttribute(‘type’,’radio’);
Chris Sladky
Opera fix here:
Simply leave in the rdo.setAttribute(“name”, “yourNameHere”) line-IE ignores it and it works with firefox and opera. Basically, move the line “rdo.setAttribute(‘name’,’fldID’);” out of the catch loop. Actually, you don’t have to set type in the catch loop either.
The following is the changed code that should work across browsers:
try{
rdo = document.createElement(‘>input name=”fldID” /<’);
}catch(err){
rdo = document.createElement(‘input’);
}
rdo.setAttribute(‘name’,’fldID’);
rdo.setAttribute(‘type’,’radio’);
Bill
The final example (using the try catch) in the actual post works pretty well (though, admittedly, it does have a problem in Opera).

You can see that technique working in the example I mentioned in an earlier comment:

http://rawlinson.us/blog/documents/jsradio.html
Anonymous
So, as you can see above there are 3 methods to add a radio input.
1) a=CreateElement(‘input’);a.type=’radio’;a.name=..;
2) a=CreateElement(’< input name=".."/>’);a.type=’radio’;
3) parent.innerhtml=’< input..>’;

1) is not working in IE (option will be not selectable). It’s because the IE is not allow you to set name dynamically. And have a big problem in FF. For example you already have an option named ‘mainProduct’. When you add an option by this method you get TWO independent groups of radios with ONE name (maybe I’m wrong, but I have this problem)
2) Works fine in IE, but not works at all in FF
3) The worse, but the most working solution

Use 3). As I understand only 3) works fine everywhere
Bill
I’m pretty sure I have submitted forms using the dynamically created radio buttons before. I’ll try to find some time to build up a working example and then I’ll post it here when I do.
Anonymous
Hi there, bit old but anyways… I wonna post those dynamically cereated inputs but it doesn’t POST anything :( My code is perfectly fine but for some reason it just doen’t work… I generated input tag with innerHTMland create element… so both ways doen’t work. Prety stupid :/
Anonymous
Thanks! Your solution is perfect! This is what I like: a simple workaround for a bothersome bug. It worked for me in IE, Firefox, and Opera.
Ewan
Thank you so much for helping me out with this, I was tearing my hair out!
Bill
Thanks for sharing your workaround and overall good humor.
Anonymous
Hi,

This happens on all input elements. IE will not throw an error if you attempt to set the NAME attribute. Its not hard.. deal with it.


use this, name is optional

function newElement(tag, name) {
var ele = (document.all && name) ? document.createElement(‘<’ + tag + ’ name=”’ + name + ‘”>’) : document.createElement(tag);
if (!document.all && name) {
ele.name = name;
}
return ele;
}

If all browsers worked the same where would the job security and high pay go? And what would be the point of having more than one browser?

Plus… all you people who like to complain about “standards” would have nothing to be huffy about.

And if you are going to write code for the public… please… idiot proof it.

To Test:



<body onload=”var ele = newElement(‘input’, ‘test’); ele.type=’radio’; document.getElementById(‘tform’).appendChild(ele); alert(document.forms[0].elements[‘test’]);”>
<script type=”text/javascript”>
function newElement(tag, name) {
var ele = (document.all && name) ? document.createElement(‘<’ + tag + ’ name=”’ + name + ‘”>’) : document.createElement(tag);
if (!document.all && name) {
ele.name = name;
}
return ele;
}
</script>
<form id=”tform”>
</form>
</body>
Ann
Me too! Wouldn’t you know, I used to have innerHTML in my code, but changed it to use the DOM, which of course works beautifully in FF… Thanks so much for this post and discussion.
Prakash
Thank you so much i have faced same problem and this post really helped me…!!!
Bill
Because I was trying to use the DOM to add the nodes and, at the time I was trying to do this, using innerHTML wasn’t a standard way to do things; in fact it was generally frowned upon.
Anonymous
Just use innerHTML. This is what the attribute was designed for and it works on IE and FF.

var span = document.createElement(‘span’);

span.innerHTML = ‘<input type=”radio” name=”radgroup”>’;

document.body.appendChild(span);
iambanese
Woot! Thanks, this got it! :)
Anonymous
I am trying to generate radio buttons using jquery and jquery-dom plugin and the code is as follows
In the below code that plugin first generates tr,td and then radio buttons.
my problem is it generates radio button but showing all buttons selected but it should show only last button selected coz if I copy paste the generated code that code shows me only last button selected.

but if i tried to generate only radio buttons code works perfectly.



tableElementForACategory.append($.TR({className:”,id: ‘H’}, $.TD({}, $.INPUT({NAME:’hood’,type:’radio’,value:$(“value”, this).text(),checked:’checked’,classname:’standard_paint’}), $.LABEL({forname:’C23899_P1’})), $.TD({}, ‘aaa’)));

tableElementForACategory.append($.TR({className:”,id: ‘H’}, $.TD({}, $.INPUT({NAME:’hood’,type:’radio’,value:$(“value”, this).text(),checked:’checked’,classname:’standard_paint’}), $.LABEL({forname:’C23899_P1’})), $.TD({}, ‘aaa’)));
annerose
These comments have been invaluable to me as is this whole site. I thank you for your comment.
Bill
Shailesh, how big of a tree are you describing?

How big is your largest single node?
Shailesh
Hi All,
I am new here and want to get some help for speeding up and resolving IE issue while creating tree using ajax.

My tree contains radio buttons at each level and I am getting all tree data from database. To speed up, what I am doing is to have tree in session at server side
and whenever ajax needs the tree , it sends appropriate tree key request and get the tree object from server.

My problem starts while processing huge tree. I have products tree object which is very huge and IW is taking 15 secs to build the tree and also hangs for 15 seconds. Firefox and mozilla hands this tree creation pretty neatly.

I am also building this tree on back ground on page load so that I have the tree ready when user clicks on + sign to get the tree.

I am building tree by using this method recursively.

function createMLNode(tagId,tagDesc){
var liElm = null;
var radioElm = null;

// Creating List Item - html tag
liElm = document.createElement(“li”);
liElm.id = tagId;

// treeSelected is global variable contains information about
// which tree + sign has clicked.
// replacing < with [ for posting
radioElm = document.createElement(‘[input type=”radio” name=”’+ “radio_” + treeSelected + ‘” /]’);

radioElm.className=”height”;

radioElm.id = “radio-” + tagId;

radioElm.onclick = function(evt) {selectTagIdForRadio(tagId , treeSelected);} ;
liElm.appendChild(radioElm);
liElm.appendChild(document.createTextNode(tagDesc));

return liElm;
}

Please help me so that I can encounter the IE hang issue or any other advice which can speed up tree building for large tree.

Thanks for your valuable suggestions.

Shailesh
John Medema
Try this for IE/FF/Opera:

try
{ tempNode = document.createElement(“[input type=’hidden’ name=’myName’ value=’myValue’/]”); }
catch(err)
{ tempNode = document.createElement(“input”); }

tempNode.setAttribute(“Type”, “hidden”);
tempNode.setAttribute(“Name”, “myName”);
tempNode.setAttribute(“Value”, “myVal”);
document.appendChild(tempNode);
Andy S.
In reply to Paddy’s answer–
Thanks for explaining the innerHTML thing! I was trying for the longest time the past couple of days to figure out why a piece of Javascript wasn’t working with IE but WAS working with FF/Safari, etc. And it turned out to be because I was trying to set a NAME attribute for a dynamically-generated form… with setAttribute. So I changed it to use innerHTML for now. Reading around, it sounds like innerHTML IS faster… but I like how setAttribute works better in some ways.
Brian McAllister
Hi guys, I’m a bit late on adding my comment here but anyways…

The little used IE-only conditional compilation might just come in handy here e.g.

function createRadioButton(parent, id, name) {
// Internet Explorer (windows <= v6)
/*@cc_on
/*@if (@_jscript_version == 5.6)
var elem = document.createElement(‘[input type=”radio” name=”’+name+’” id=”’+id+’” /]’);
parent.appendChild(elem);
return;
/*@end
@*/

// All other browsers
var rdo = document.createElement(‘input’);
rdo.setAttribute(‘type’,’radio’);
rdo.setAttribute(‘name’,name);
rdo.setAttribute(‘id’,id);
parent.appendChild(rdo);
}

Of course, I’ve never tested the code but it should work.

P.S. HTML tags have been mangled to pass the blogger comment system.
Paddy
Adding to the last comment:

innerHTML compatability: http://www.quirksmode.org/dom/w3c_html.html
something to be careful of in IE5.0:
http://www.quirksmode.org/bugreports/archives/2004/10/innerhtml_and_o.html

Basically its sound in everything except for IE5.2 on the Mac
Paddy
Hi there, not sure if this now an old topic but I reached it through google so feel I should add a comment that may help future people passing by :)

The reason that these elements don’t work in IE is because it doesn’t support the ‘name’ attribute being added dynamically (*grumble*) as documented at http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp

Now, IE has its own native ability to use createElement with the full HTML tag and attributes there, which is great (well, it works) - so this is one solution. However, I don’t have opera installed - and someone else suggests it doesn’t work in opera.

So, the best solution is actually to use innerHTML. Until yesterday I was avoiding this like the plague, but some research has revealed that (in no small part thanks to XMLHTTPRequest) attitudes have changed - while its not a W3C standard it has become a widely supported de facto standard. The key is not that its a nice way of doing it, but that its quicker - check out the benchmarks at http://www.quirksmode.org/dom/innerhtml.html a / read the comments at http://domscripting.com/blog/display/35 / consider the views of Ajaxian (clearly experienced JS players) http://ajaxian.com/archives/dhtml-versus-dom-comparing-both-approaches

The only instance whereby this is not a suitable solution for the radio button issue is if you dynamically want to change which button is checked. This is something I actually wanted to be the case, but found that in internet explorer the reset button will always revert to the original pageload selections regardless of any JS manipulation. As a result I had already changed to the approach of ‘refreshing’ the radio buttons - i.e. recreating them, thus dynamically changing their ‘checked’ status is no longer a problem and I can use innerHTML.

:o
Bill
As for the “file” field input being added dynamically I do this:

// create the file input control..
var f = document.createElement(‘input’);
f.type = ‘file’;
f.name = ‘#Attributes.Name#’ + fileFieldCount;
f.id = ‘#Attributes.Name#’ + fileFieldCount;
f.className = ‘filefield’;
f.onchange=copyAttachmentPath;

var c = r.insertCell(1);

c.appendChild(f);

// create a hidden control to store the origional file name
var h = document.createElement(‘input’);
h.type = ‘hidden’;
h.name =’#Attributes.Name#’+ fileFieldCount + ‘ref’;
h.id = ‘#Attributes.Name#’+ fileFieldCount + ‘ref’;

c.appendChild(h);


function copyAttachmentPath(){
getStyleObject(this.id+’ref’).value = this.value;
}

and it works fine in both IE and FF.
Anonymous
“But problem is that i can’t get post data while form is submit in FF. but it works well in IE.”

Hey! I have this exact problem.. the form is submitted with elements in IE but not in FireFox. Whats going on there?
Anonymous
I have used

obj = document.createElement(“input”);
obj.setAttribute(‘type’,’file’);
obj.setAttribute(‘name’,’file’+iteration);
obj.setAttribute(‘id’,’file’+iteration);
obj.setAttribute(‘style.color’,’#cccccc’);
obj.setAttribute(‘style.fontSize’,’9px’);
obj.setAttribute(‘style.fontFamily’,’Verdana, Arial, Helvetica, sans-serif’);
obj.setAttribute(‘size’,’25’);




it works well in both IE and FF.
But problem is that i can’t get post data while form is submit in FF. but it works well in IE.

Please help me what was the problem is there?
Anonymous
Adding to the post that has the functions - if anyone does want to use them the addRadio function needs ALL the attributes in the attributes object. That is it needs the ‘type’ attribute set to radio so the catch in the function will work.
Bill
it should work in IE but it doesn’t. The radio button isn’t selectable.
Anonymous
just:

rdo=document.createElement(‘input’);
rdo.setAttribute(‘type’,’radio’);
rdo.setAttribute(‘name’,’fldID’);

should work both in IE and Firefox (dunno about Opera).
Bill
I have fixed my post - those of you who mentioned the Firefox error were correct - sorry.

I have also put up a sample file that demonstrates how the code works in IE/Firefox - and how it still won’t work in Opera 8.

Demo at: http://rawlinson.us/blog/documents/jsradio.html
Bill
I will put together a more feature complete demo at some point today and put a link to it here. Perhaps we can figure out why some of us are having an error and others aren’t.
Dmitri Colebatch
Hi Bill,

I’ve got the same problem that others are reporting, here’s some snippets of code:
[code]
var i = 4;
function addRow()
{
var tbody = document.getElementById(“optionsTableBody”)
var tr = document.createElement(“<TR id="optionsTableRow_” + i + “">”);
….
}
[/code]

I get the same error as others - the line it appears on is the createElement(tr…) line.

A bit of experienting shows me that as soon as I put the <> tags around the tr I get the error (I of course have a whole bunch of elements to create).

This looks pretty similar to what you had in your post so I’m a little confused as to the cause. Using FF 1.5.0.3.

cheers
dim
Bill
once again I need someone to send me some code so I can take a look at what is happening to you - I will be happy to try to help with some additional info.
Anonymous
I am getting the same error in FF. Did anyone figured what could have been causing this.
Bill
I would need to see your code. YOu can send it to me as an attachment at my gmail account using my user name of bill.rawlinson

Once I have it perhaps I can see what is going wrong. I pretty much always develop for Firefox first - then IE - so I know what I did worked in FF - but perhaps I explained it in a flawed manner on the post.
Anonymous
doesn’t work in Mozilla get the error: Error: uncaught exception: [Exception… “String contains an invalid character” code: “5” nsresult: “0x80530005 (NS_ERROR_DOM_INVALID_CHARACTER_ERR)” location: “http://127.0.0.1/testcode/javascriptInsertHTML.html Line: 54”]
I escaped everything
Bill
i forgot to escape the characters when i was posting initially. But yes the technique does work in both IE and FF.

Which browser are you using where it doesn’t work?
Anonymous
I couldnĀ“t make it work on both ie and ff. Are you sure it works on both?
Since the html got rendered above I suppose it should be:
var rdo = document.createElement(‘”[input name=’name’ type=’radio’]”’);
(changing the above ][ for ><)
Anonymous
I couldnĀ“t make it work on both ie and ff. Are you sure it works on both?
Since the html got rendered above I suppose it should be:
var rdo = document.createElement(‘”[input name=’name’ type=’radio’]”’);
(changing the above ][ for ><)