By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,078 Members | 1,846 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,078 IT Pros & Developers. It's quick & easy.

getElementsByName undefined for dynamic elements (radio buttons)

P: n/a
I have a set of radio buttons that are created dynamically, after
rendered I try loop thru this set by getting the length of the set, but
I keep getting an error stating the element is undefined. I am using
getElelementsByName since these are radio buttons, but it seems that
the dynamic element is not seen!!!

This is my code... please let me know if there is anything that I am
doing wrong! - thanks
----
....
....
// this loops thru an ajax structure --- this is correct so I kow is
not an Ajax issue.

for(var i=0; i<ds.Tables[0].Rows.length; i++){
//creating nue input element
var r=document.createElement('<INPUT type=radio name=company >');
r.type="radio";
r.name ="company";
r.id ="myradiobutton" + i;
r.setAttribute("value",ds.Tables[0].Rows[i].roottype);
td_company.appendChild(r);
td_company.appendChild(document.createTextNode(ds. Tables[0].Rows[i].roottypedesc));
}

-----
My function trying to get the lenght of the set is called after the
radion buttons are rendered. If I find one that has an specific value,
I check it.

for(var n=0; n<document.getElementsByName("company").length; n++){
if (document.getElementsByName("company")[n].value == 'msde')
{
document.getElementsByName("country")[n].checked = "checked";
}
}

May 4 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
ASM
Saul a écrit :
I have a set of radio buttons that are created dynamically, after
rendered I try loop thru this set by getting the length of the set, but
I keep getting an error stating the element is undefined. I am using
getElelementsByName since these are radio buttons, but it seems that
the dynamic element is not seen!!!

This is my code... please let me know if there is anything that I am
doing wrong! - thanks
----
...
...
// this loops thru an ajax structure --- this is correct so I kow is
not an Ajax issue.

for(var i=0; i<ds.Tables[0].Rows.length; i++){
//creating nue input element
var r=document.createElement('<INPUT type=radio name=company >');
var r=document.createElement('INPUT');
r.type="radio";
r.name ="company";
r.id ="myradiobutton" + i;
r.setAttribute("value",ds.Tables[0].Rows[i].roottype);
roottype isn't it Java language ?
td_company.appendChild(r);
what is td_company ?
td_company.appendChild(document.createTextNode(ds. Tables[0].Rows[i].roottypedesc));
}

-----
My function trying to get the lenght of the set is called after the
radion buttons are rendered. If I find one that has an specific value,
I check it.

for(var n=0; n<document.getElementsByName("company").length; n++){
if (document.getElementsByName("company")[n].value == 'msde')
{
document.getElementsByName("country")[n].checked = "checked";
}
}


var R = document.getElementsByName("company");
var C = document.getElementsByName("country");
for(var n=0; n<R.length; n++)
if (R[n].value == 'msde') C[n].checked = "checked";

to avoid to re-built these two collections (R & C)
on each loop
--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #2

P: n/a
Saul said on 05/05/2006 7:01 AM AEST:
I have a set of radio buttons that are created dynamically, after
rendered I try loop thru this set by getting the length of the set, but
I keep getting an error stating the element is undefined. I am using
getElelementsByName since these are radio buttons, but it seems that
the dynamic element is not seen!!!

This is my code... please let me know if there is anything that I am
doing wrong! - thanks
----
...
...
// this loops thru an ajax structure --- this is correct so I kow is
not an Ajax issue.

for(var i=0; i<ds.Tables[0].Rows.length; i++){
Is ds.Tables an array of table elements? If so, and item[0] is a table,
then it has a 'rows' collection, not 'Rows' (note capitalisation). But
maybe it is some part of your XML structure that is called 'Rows', I
don't know.

Since you sequentially access all rows, it is also better to get a
reference to the row once and go from there.

It is more efficient to get the length attribute once and store it (the
saving may be insignificant if the number of rows is small, but it's the
thought that counts :-) ):

var row, rows = ds.Tables[0].rows;
for(var i=0, len=rows.length; i<len; i++){
row = rows[i];

//creating nue input element
var r=document.createElement('<INPUT type=radio name=company >');
That method of dynamically adding elements is IE specific and will fail
in most (possibly all) other browsers, the W3C DOM standard method is:

var r = document.createElement('input');
r.type = 'radio';
r.name = 'company';

However, if that method is used, IE doesn't recognise the name attribute
in script, though the form will submit correctly. There is a thread
about it here:

<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_frm/thread/db95b9f62035bee6/a86500f9f5880246?q=name+createElement&rnum=2#a8650 0f9f5880246>

r.type="radio";
r.name ="company";
r.id ="myradiobutton" + i;
r.setAttribute("value",ds.Tables[0].Rows[i].roottype);
setAttribute is buggy in some browsers, it is better (though
non-standard) to access properties directly as you have above:

r.value = ds.Tables[0].Rows[i].roottype;

td_company.appendChild(r);
td_company.appendChild(document.createTextNode(ds. Tables[0].Rows[i].roottypedesc));
Using the suggested row & rows variables above, this becomes:

td_company.appendChild(document.createTextNode(row .roottypedesc));

}

-----
My function trying to get the lenght of the set is called after the
radion buttons are rendered. If I find one that has an specific value,
I check it.

for(var n=0; n<document.getElementsByName("company").length; n++){
if (document.getElementsByName("company")[n].value == 'msde')
{
document.getElementsByName("country")[n].checked = "checked";


Similarly here:

var el, els = document.getElementsByName("company");
for(var n=0, len=els.length; n<len; n++){
el = els[i];
if (el.value == 'msde') {
el.checked = true;
}

--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
May 5 '06 #3

P: n/a
ASM
RobG a écrit :
Saul said on 05/05/2006 7:01 AM AEST: [...]
for(var n=0; n<document.getElementsByName("company").length; n++){
if (document.getElementsByName("company")[n].value == 'msde')
{
document.getElementsByName("country")[n].checked = "checked";

Similarly here:


Similarly but not duplicately ( "company" != "country" )
var el, els = document.getElementsByName("company");
for(var n=0, len=els.length; n<len; n++){
el = els[i];
if (el.value == 'msde') {
el.checked = true;
}


var el, els = document.getElementsByName("company");
var en, ens = document.getElementsByName("country");
for(var n=0, len=els.length; n<len; n++){
el = els[n]; // and not els[i]
if (el.value == 'msde') {
en = ens[n];
en.checked = true;
}
}
--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #4

P: n/a
ASM said on 05/05/2006 12:31 PM AEST:
RobG a écrit :
Saul said on 05/05/2006 7:01 AM AEST:


[...]
for(var n=0; n<document.getElementsByName("company").length; n++){
if (document.getElementsByName("company")[n].value == 'msde')
{
document.getElementsByName("country")[n].checked = "checked";


Similarly here:

Similarly but not duplicately ( "company" != "country" )


Yeah, well, depends on the country, doesn't it? ;-)

var el, els = document.getElementsByName("company");
for(var n=0, len=els.length; n<len; n++){
el = els[i];
if (el.value == 'msde') {
el.checked = true;
}

var el, els = document.getElementsByName("company");
var en, ens = document.getElementsByName("country");
for(var n=0, len=els.length; n<len; n++){
el = els[n]; // and not els[i]
if (el.value == 'msde') {
en = ens[n];
en.checked = true;


If I'd seen company/country I'd likey have done:

var companys = document.getElementsByName("company");
var countries = document.getElementsByName("country");
var n = companys.length;
while (n--){
countries[n].checked = (companies[n].value == 'msde');
}

Of course it's not very tollerant of cases where companys.length is less
than countires.length, but neither was the OP. :-)
--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
May 5 '06 #5

P: n/a
RobG said on 05/05/2006 12:49 PM AEST:
[...]
var companys = document.getElementsByName("company");
var companies = ...
var countries = document.getElementsByName("country");
var n = companys.length;
var n = companies.length;
while (n--){
countries[n].checked = (companies[n].value == 'msde');
}

Of course it's not very tollerant of cases where companys.length is less


... companies.length ...

--
Rob
Group FAQ: <URL:http://www.jibbering.com/FAQ>
May 5 '06 #6

P: n/a
thanks for your replies...

ds is a dataset coming from an Ajax call and roottype is an element of
this set... I am sure the Ajax call is not the issue(since the data is
obtained and rendered correctly) and this is why I focused in the
javascript part to find the problem.

The elements are createed correctly when I loop thru the array. The
radio buttons are there and are visible inside the div tag "td_company"
The issue arises when trying to reference the element "company" which
is the name given to all the radio buttons created dynamically.

if I write an alert from inside the function creating the radio
buttons, to output the company.length ... I get the correct value.
If I write the alert outside the function I always get a zero. So
trying"

document.getElementsByName("company").length

in the caller function always returns zero and therefore i cannot loop.
- but the radio buttons are there, how can it be zero!
Also using document.getElementsByName("company")[0].value to find out
the value of the first element of the set of radio buttons returns
document.getElementsByName(...)[...].value is undefined.

I tried the different recommendations above, but still get the same
issue! - Any other suggestions

May 5 '06 #7

P: n/a
thanks for your replies...

ds is a dataset coming from an Ajax call and roottype is an element of
this set... I am sure the Ajax call is not the issue(since the data is
obtained and rendered correctly) and this is why I focused in the
javascript part to find the problem.

The elements are createed correctly when I loop thru the array. The
radio buttons are there and are visible inside the div tag "td_company"
The issue arises when trying to reference the element "company" which
is the name given to all the radio buttons created dynamically.

if I write an alert from inside the function creating the radio
buttons, to output the company.length ... I get the correct value.
If I write the alert outside the function I always get a zero. So
trying"

document.getElementsByName("company").length

in the caller function always returns zero and therefore i cannot loop.
- but the radio buttons are there, how can it be zero!
Also using document.getElementsByName("company")[0].value to find out
the value of the first element of the set of radio buttons returns
document.getElementsByName(...)[...].value is undefined.

I tried the different recommendations above, but still get the same
issue! - Any other suggestions

-thanks

May 5 '06 #8

P: n/a
Saul wrote:
thanks for your replies...
Please quote the relevant parts of what you are replying to.

ds is a dataset coming from an Ajax call and roottype is an element of
this set... I am sure the Ajax call is not the issue(since the data is
obtained and rendered correctly) and this is why I focused in the
javascript part to find the problem.
I'll guess that -ds.Tables[0].Rows- is referring to your XML structure,
not the HTMLElement structure suggested by the names you've used.

The elements are createed correctly when I loop thru the array. The
radio buttons are there and are visible inside the div tag "td_company"
The issue arises when trying to reference the element "company" which
is the name given to all the radio buttons created dynamically.
Exactly. IE has trouble with the name attribute of elements added
dynamically - from Microsoft's documentation:

"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."

<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/...>
Read the thread I suggested provides 2 work-arounds, here it is again;

<URL:http://groups.google.co.uk/group/comp.lang.javascript/browse_frm/thread/db95b9f62035bee6/a86500f9f5880246?q=name+createElement&rnum=2#a8650 0f9f5880246>
[...]
I tried the different recommendations above, but still get the same
issue! - Any other suggestions


Try one of the methods in the suggested thread. Here's mine, I'm sure
you can adapt it to your circumstance:
<script type="text/javascript">

function addRadios(form, grpName, num)
{
var oRadio, e;
var dom = true;
for (var i=0; i<num; ++i){
if (dom){

// Create radio button, give it a name and add to form
oRadio = document.createElement('input');
oRadio.name = grpName;
form.appendChild(oRadio);

// Test if can access radio button group
// If not, remove element and set dom
if ( 0 == i && !document.getElementsByName(grpName).length){
dom = false;
form.removeChild(oRadio);
}
}

// If dom set to false, use IE method to add element
if (!dom){
try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
} catch (e){ e = true;}

// If got to here and no error, add attributes to element
// and element to document
}
if (!e){
oRadio.type = 'radio';
oRadio.onclick = rbClicked;
oRadio.value = grpName + ' ' + i;
form.appendChild(document.createTextNode('rad-' + i));
form.appendChild(document.createElement('br'));
}
}
}

// A play onclick function to show name is set
function rbClicked(){
alert('Clicked me!'
+ '\nName: ' + this.name
+ '\nValue: ' + this.value);
}
</script>

<form action="" name="aFrom"><div>
<input type="button" value="Add radios"
onclick="addRadios(this.form, 'rBtnGrp', 4);"><br>
<input type="button" value="Click second radio"
onclick="
alert('There are ' + document.getElementsByName('rBtnGrp').length
+ ' radio buttons');
this.form.rBtnGrp[1].click();
"><br>
</div></form>

--
Rob
May 5 '06 #9

P: n/a
RobG wrote:

Exactly. IE has trouble with the name attribute of elements added
dynamically - from Microsoft's documentation:

"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."

<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/...>


Sorry, should be:

<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp>
--
Rob
May 5 '06 #10

P: n/a
VK

Saul wrote:
The elements are createed correctly when I loop thru the array. The
radio buttons are there and are visible inside the div tag "td_company"
The issue arises when trying to reference the element "company" which
is the name given to all the radio buttons created dynamically.


<http://www.fleegix.org/articles/2006/04/29/dom-fun-with-ie6-and-form-elements>

May 5 '06 #11

P: n/a
ASM
RobG a écrit :

Try one of the methods in the suggested thread. Here's mine, I'm sure
you can adapt it to your circumstance:
splendid !
that would answer to my IE's bug : type is read only
i.e. when we do : oRadio.type = 'radio';
<script type="text/javascript">

function addRadios(form, grpName, num)
{
var oRadio, e;
var dom = true;
for (var i=0; i<num; ++i){
if (dom){

// Create radio button, give it a name and add to form
oRadio = document.createElement('input');
oRadio.name = grpName;
form.appendChild(oRadio);

// Test if can access radio button group
I'm not sure(*) my IE (Mac) won't acces this new collection
so I prefer to put away all IEs

ie=false; /*@cc_on ie=true; @*/
// If not, remove element and set dom
if ( 0 == i && !document.getElementsByName(grpName).length){
if ( !ie ||
(0==i && !document.getElementsByName(grpName).length)
){
dom = false;
form.removeChild(oRadio);
}
}

// If dom set to false, use IE method to add element
if (!dom){
try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
} catch (e){ e = true;}

// If got to here and no error, add attributes to element
// and element to document
}
if (!e){
oRadio.type = 'radio';
oRadio.onclick = rbClicked;
oRadio.value = grpName + ' ' + i;
form.appendChild(document.createTextNode('rad-' + i));
form.appendChild(document.createElement('br'));
}
}
} < + '\nValue: ' + this.value); }
</script>

(*) I've tried your example in my IE : yes it knows the new collection
and stops on : oRadio.type = 'radio';
in your function

--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #12

P: n/a
ASM
RobG a écrit :
RobG said on 05/05/2006 12:49 PM AEST:
[...]
var companys = document.getElementsByName("company");


var companies = ...


hu? var compagnies = ...
why to use absolutly correct english about variables ?


--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #13

P: n/a
On 05/05/2006 02:34, RobG wrote:

[snip]
setAttribute is buggy in some browsers, it is better (though ^^^^^^ non-standard) to access properties directly [...]

^^^^^^^^^^^^
Not at all. The short cut properties are specified in the W3C DOM HTML
module. Their use is entirely 'standard' within a HTML document.

[snip]

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
May 5 '06 #14

P: n/a
VK

Michael Winter wrote:
On 05/05/2006 02:34, RobG wrote:

[snip]
setAttribute is buggy in some browsers, it is better (though ^^^^^^
non-standard) to access properties directly [...]

^^^^^^^^^^^^
Not at all. The short cut properties are specified in the W3C DOM HTML
module. Their use is entirely 'standard' within a HTML document.


AFAIK they are dealing with completely different domains. While
setAttribute sets *string* values of element attribute node,
element.something = something works with the provided DOM reference.
The first is respectively good only for string values, the second can
hold any data including references. In this aspect I'm aware of any
bugs in setAttribute (?)

But IE indeed has a number of bugs in handling dymanically created form
elements. The relevant bug in application to radio buttons is described
in the article I linked in my previous post.

Here is the bug in action (this is what OP is hitting) :

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>$Template$</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<style type="text/css">
html {
margin: 0px 0px;
padding: 0px 0px}
body {
margin: 10px 10px;
padding: 0px 0px;
font: 1em serif;
color: #000000;
background-color: #FFFFFF}
</style>
<script type="text/javascript">

var fs = null;

function init() {
fs = document.getElementById('fs01');
var rb = null;
for (var i=0; i<10; i++) {
rb = document.createElement('INPUT');
rb.type = 'radio';
rb.name = 'company';
rb.value = i;
fs.appendChild(rb);
}
window.setTimeout('show()',1000);
}

function show() {
var rb = document.getElementsByName('company');
alert(rb.length);
// Firefox shows 10
// IE shows 0
}

window.onload = init;
</script>
</head>

<body<form name="myForm" action=""
<fieldset id="fs01"
<legend>Test</legend
</fieldset
</form
</body>

</html>

May 5 '06 #15

P: n/a
ASM
ASM a écrit :
RobG a écrit :

Here's mine
splendid !


pfft ! unlovely, no it is not :-(

here is what I get with my IE :
http://cjoint.com/?ffp4aJKJf3
after my supposed corrections ...

It appears that :

try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
}

won't work in my IE (try() works but no result)

I don't understand what is supposed to do :
catch (e){ e = true;}

Anyway in my IE !e is true
so, as oRadio was removed, I don't more have errors and only
form.appendChild(document.createTextNode('rad-' + i));
form.appendChild(document.createElement('br'));
do something
If I code :
try {
oRadio = document.createElement('p');
oRadio.innerHTML= '<input type="radio"' +
' name="' + grpName + '" onclick="rbClicked();">';
form.appendChild(oRadio);
} catch (e){ e = true;}

new radios are 8 ! ! (of course only 4 are visible)
and they have no name :-(
by the way
this.form.rBtnGrp[1].click();
can't reach second button ==> error 'rBtnGrp' unknown

<script type="text/javascript">

function addRadios(form, grpName, num)
{
var oRadio, e;
var dom = true;
for (var i=0; i<num; ++i){
if (dom){

// Create radio button, give it a name and add to form
oRadio = document.createElement('input');
oRadio.name = grpName;
form.appendChild(oRadio);

// Test if can access radio button group


ie=false; /*@cc_on ie=true; @*/
// If not, remove element and set dom
if ( 0 == i && !document.getElementsByName(grpName).length){


// correction : if( ie ...
if ( ie ||
(0==i && !document.getElementsByName(grpName).length)
){
dom = false;
form.removeChild(oRadio);
}
}

// If dom set to false, use IE method to add element
if (!dom){
try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
} catch (e){ e = true;}

// If got to here and no error, add attributes to element
// and element to document
}
if (!e){
oRadio.type = 'radio';
oRadio.onclick = rbClicked;
oRadio.value = grpName + ' ' + i;
form.appendChild(document.createTextNode('rad-' + i));
form.appendChild(document.createElement('br'));
}
}
}


< + '\nValue: ' + this.value);
}
</script>

--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #16

P: n/a
ASM
VK a écrit :

But IE indeed has a number of bugs in handling dymanically created form
elements. The relevant bug in application to radio buttons is described
in the article I linked in my previous post.
and anyway, with IE Mac it's worst :-(

[...] <script type="text/javascript">

var fs = null;

function init() {
fs = document.getElementById('fs01');
var rb = null;
for (var i=0; i<10; i++) {
rb = document.createElement('INPUT');
rb.type = 'radio';


here my IE stops : IE cry on this big error ( type is read only :-( )

--
Stephane Moriaux et son [moins] vieux Mac
May 5 '06 #17

P: n/a
VK

ASM wrote:
and anyway, with IE Mac it's worst :-(

[...]
<script type="text/javascript">

var fs = null;

function init() {
fs = document.getElementById('fs01');
var rb = null;
for (var i=0; i<10; i++) {
rb = document.createElement('INPUT');
rb.type = 'radio';


here my IE stops : IE cry on this big error ( type is read only :-( )


Who needs a IE Mac solution?? This browser is not supported anymore and
not available for download for a year at least.

If rb.type is read-only, then it's the end of the line I guess....

May 5 '06 #18

P: n/a
On 05/05/2006 09:31, RobG wrote:
[snip]
// If dom set to false, use IE method to add element
if (!dom){
try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
} catch (e){ e = true;}


[snip]

An alternative version that avoids exception handling could look
something like:

/* Takes three arguments and returns a boolean to indicate
* success (true) or failure (false).
*
* groupName - Name used for the new radio button group.
* quantity - Number of radio buttons to add.
* container - Reference to a block-level element, to
* which the new controls will be added.
*/
var addRadioButtons = function() {
function create(name) {
var element = document.createElement('input');

if (element) {
element.name = name;
element.type = 'radio';
}
return element;
}

/* If the host is IE, the function declaration below
* will override the one above.
*/
/*@cc_on @*/
/*@if (@_jscript)
function create(name) {
return document.createElement('<input type="radio" name="'
+ name + '">');
}
@end @*/

return document.createElement && document.createTextNode
? function(groupName, quantity, container) {
if (!container.appendChild) return false;
for (var i = 0; i < quantity; ++i) {
var element, label, text;

if (!(element = create(groupName))
|| !(label = document.createElement('label'))
|| !label.appendChild
|| !(text = document.createTextNode(' radio-' + i)))
return false;
element.value = groupName + '-' + i;
label.appendChild(element);
label.appendChild(text);
container.appendChild(label);
}
return true;
} : function() {
return false;
};
}();

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
May 5 '06 #19

P: n/a
On 05/05/2006 15:02, VK wrote:

[setAttribute versus equivalent HTML short cut properties]
AFAIK they are dealing with completely different domains.
They are not.
While setAttribute sets *string* values of element attribute node,
element.something = something works with the provided DOM reference.


The defined short cut properties all have types. If the right-hand
operand is not of that type, it will be coerced upon assignment.

For a highly visible example, create a text input element and assign an
object reference to its value property.

[snip]

Mike

--
Michael Winter
Prefix subject with [News] before replying by e-mail.
May 5 '06 #20

P: n/a
JRS: In article <44***********************@news.wanadoo.fr>, dated Fri,
5 May 2006 15:36:22 remote, seen in news:comp.lang.javascript, ASM
<st*********************@wanadoo.fr.invalid> posted :
RobG a écrit :
RobG said on 05/05/2006 12:49 PM AEST:
[...]
var companys = document.getElementsByName("company");


var companies = ...


hu? var compagnies = ...
why to use absolutly correct english about variables ?


It's good to inform foreigners (including the chronologically retarded)
about correct spelling, if it is done economically.

OTOH, there is much to be said for using (on pages in English) variable
names which are not true English words (humor, for example), since then
when using text-searching tools an author can discriminate between the
concealed javascript form and the form shown to the page reader.

--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
<URL:http://www.jibbering.com/faq/> JL/RC: FAQ of news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
May 6 '06 #21

P: n/a
Michael Winter wrote:
On 05/05/2006 09:31, RobG wrote:
// If dom set to false, use IE method to add element
if (!dom){
try {
oRadio = document.createElement('<input type="radio"'
+ ' name="' + grpName + '">');
form.appendChild(oRadio);
} catch (e){ e = true;}


[snip]

An alternative version that avoids exception handling could look
something like:

/* Takes three arguments and returns a boolean to indicate
* success (true) or failure (false).
*
* groupName - Name used for the new radio button group.
* quantity - Number of radio buttons to add.
* container - Reference to a block-level element, to
* which the new controls will be added.
*/
var addRadioButtons = function() {
function create(name) {
var element = document.createElement('input');

if (element) {
element.name = name;
element.type = 'radio';
}
return element;
}

/* If the host is IE, the function declaration below
* will override the one above.
*/
/*@cc_on @*/
/*@if (@_jscript)
function create(name) {
return document.createElement('<input type="radio" name="'
+ name + '">');
}
@end @*/
[...]


Here is a more general solution to this problem:

/**
* Creates an element of the type specified, using the
* <code>document.createElement()</code> method if supported.
* This method works with MSIE, too, for if JScript is used,
* it is tried to use the start tag as is instead of passing
* only the element type, and adding properties later.
*
* @author
* (C) 2004, 2006 Thomas Lahn &lt;dh******@PointedEars.de&gt;
* @partof
* http://pointedears.de/scripts/dhtml.js
* @param sTag : string
* Start tag or element type of the element to be created.
* Passing a start tag even works if the UA is not MSIE,
* as attributes and values given are parsed from left to
* right into the corresponding element object properties.
* @return type object
* A reference to a new <code>Element</code> object with the
* <code>nodeName</code> property set to <code>sTagName</code>,
* and the <code>localName</code>, <code>prefix</code>,
* and <code>namespaceURI</code> properties set to
* <code>null</code>.
* @see
* @link{dom2-core#ID-2141741547},
* @link{msdn#workshop/author/dhtml/reference/methods/createelement.asp}
* http://pointedears.de/scripts/JSdoc/
*/
function createElement(sTag)
{
var o = null;

if (sTag
&& typeof document != "undefined"
&& dhtml.isMethod(document.createElement))
{
/*@cc_on @*/
/*@if (@_jscript)
o = document.createElement(sTag);
@end @*/

if (!o)
{
var aTagComponents = sTag.replace(/^<?\s*|\s*>?$/g, "")
.replace(/\s+/, " ").replace(/ = /g, "=").split(" ");
o = document.createElement(aTagComponents[0]);
if (o)
{
aTagComponents.shift();
var attrs = aTagComponents.join(" ");
var m;
while ((m = /([^\s=]+)\s*(=\s*(\S+)\s*)?/g.exec(attrs)))
{
setAttr(o, m[1].toLowerCase(), m[3]);
}
}
}
}

return o;
}

/**
* Sets the value of an attribute of an HTMLElement object.
*
* @author
* (C) 2003, 2006 Thomas Lahn &lt;dh******@PointedEars.de&gt;
* @partof
* http://pointedears.de/scripts/dhtml.js
* @param sAttrName: string
* Name of the attribute for which the value should be set.
* Attribute names for which an ECMAScript language binding
* is defined in W3C DOM Level 2 HTML, are automatically
* mapped to the corresponding element object property.
* All attribute names are automatically mapped to their
* camelCased equivalent.
*
* Semicolon-separated style property declarations (in
* form of colon-separated name-value pairs each) of a
* <code>style</code> attribute value are mapped to the
* corresponding properties of the object referenced by
* the <code>style</code> property of the element object.
* Declarations are evaluated from left to right, where
* property values complement or replace the previously
* defined ones.
* @param attrValue
* Value of the attribute to be set. The value is
* converted to number if it can be interpreted as such.
* @returns
* The value of the attribute of the element object;
* a null-string if no matching object exists or if the DOM
* does not provide retrieval of the attribute's values.
*/
function setAttr(o, sAttrName, attrValue)
{
var result = "";

if (o && sAttrName)
{
var attrMap = {
alink: "aLink",
accesskey: "accessKey",
bgcolor: "bgColor",
cellpadding: "cellPadding",
cellspacing: "cellSpacing",
"char": "ch",
charoff: "chOff",
"class": "className",
codebase: "codeBase",
codetype: "codeType",
datetime: "dateTime",
frameborder: "frameBorder",
htmlfor: "htmlFor",
ismap: "isMap",
longdesc: "longDesc",
maxlength: "maxLength",
marginheight: "marginHeight",
marginwidth: "marginWidth",
nohref: "noHref",
noresize: "noResize",
noshade: "noShade",
nowrap: "noWrap",
readonly: "readOnly",
rowspan: "rowSpan",
tabindex: "tabIndex",
usemap: "useMap",
valuetype: "valueType",
vlink: "vLink"
};

// camel-case specific attribute names
if (typeof attrMap[sAttrName] != "undefined")
{
sAttrName = attrMap[sAttrName];
}

var
hyphenatedToCamelCase = function(s)
{
return s.replace(
/-([a-z])/g,
function(match, p1, offset, input)
{
return p1.toUpperCase();
})
},

strToValue = function(s)
{
s = s.replace(/^["']|["']$/g, "");
return isNaN(s) ? s : +s;
};

// camel-case hyphenated attribute names
sAttrName = hyphenatedToCamelCase(sAttrName);

if (typeof attrValue != "undefined")
{
attrValue = strToValue(attrValue);
if (sAttrName == "style" && typeof attrValue == "string")
{
var styleProps = attrValue.split(/\s*;\s*/);
for (var j = 0, len = styleProps.length; j < len; j++)
{
var
stylePair = styleProps[j].split(/\s*:\s*/),
stylePropName = stylePair[0].toLowerCase(),
stylePropVal = stylePair[1];

dhtml.setStyleProperty(o,
hyphenatedToCamelCase(stylePropName),
strToValue(stylePropVal));
}
}
else
{
result = o[sAttrName] = attrValue;
}
}
else if (!(o[sAttrName] = true))
{
result = o[sAttrName] = sAttrName;
}
}

return result;
}
PointedEars
--
http://members.ud.com/download/gold/
http://folding.stanford.edu/
http://alien.de/seti/
http://setiathome.ssl.berkeley.edu/
May 16 '06 #22

P: n/a
Michael Winter wrote:
On 05/05/2006 15:02, VK wrote:
[setAttribute versus equivalent HTML short cut properties]
AFAIK they are dealing with completely different domains.
They are not.


True. The domains are not completely different. But they are
slightly different.

HTML shortcut properties are live with both writing and reading.
setAttribute() is "live" on write access; however, getAttribute()
is not "live" on read access: e.g. when the form control value is
changed as compared to the default, .value evaluates to a different
value than getAttribute("value"), and getAttribute("value") returns
the same value as .defaultValue evaluates to.
While setAttribute sets *string* values of element attribute node,
element.something = something works with the provided DOM reference.


The defined short cut properties all have types. If the right-hand
operand is not of that type, it will be coerced upon assignment.


It is implicit type conversion through a setter.
For a highly visible example, create a text input element and assign an
object reference to its value property.


See above.
PointedEars
--
Let us not judge others because of their religion, color or nationality.
We are all just human beings living together on this planet. (poehoe.de)
May 16 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.