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.
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.
52 comments:
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 ><)
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 ><)
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?
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
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.
I am getting the same error in FF. Did anyone figured what could have been causing this.
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.
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
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.
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
just:
rdo=document.createElement('input');
rdo.setAttribute('type','radio');
rdo.setAttribute('name','fldID');
should work both in IE and Firefox (dunno about Opera).
it should work in IE but it doesn't. The radio button isn't selectable.
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.
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?
"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?
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.
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
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
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.
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.
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);
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
Shailesh, how big of a tree are you describing?
How big is your largest single node?
These comments have been invaluable to me as is this whole site. I thank you for your comment.
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')));
Woot! Thanks, this got it! :)
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);
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.
Thank you so much i have faced same problem and this post really helped me...!!!
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.
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>
Thanks for sharing your workaround and overall good humor.
Thank you so much for helping me out with this, I was tearing my hair out!
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.
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 :/
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.
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
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
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');
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');
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's suggested fix works fine in all four browsers on windows so I updated the post to include that change.
But to make it selected via the javascript, do you use the "value" or the "checked" attribute?
Thanks, you saved me loads of time today!
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.
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!
thanks for this write-up! it saved my morning!
AWESOME! I could've spent hours on this if I didn't find your page! Thanks!
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).
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 :)
Thank's a lot ...
thanks a bunch man, saved me alot of code rewriting :D
Post a Comment