onload option for <tr> or <td> tag.

V

venu madhav

Hi all,
I have a scenario where in my HTML page which gets rendered at
the server in CGI contains a table. For a particular column in that
table and for each row, I will get an epoch value from the server
which I've to convert to Human readable format. I tried calling that
Javascript function as shown in the below code but it didn't work. I
am new to Javascript. So, can someone help me in this regard.

CGI Script

for each ()
{
<tr ...>
....
html .= "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";
....
}

Javascript:
convert_time(epoch_time)
{
.... // Processing
document.getElementById('epoch').innerHTML= tme;
}


I tried to put the code as simple as possible. The <td> repeats in a
loop for each row and this function should be invoked for each row's
td. Please let me know if you need any more clarifications.

Thank you,
Venu.
 
A

Alexandre Morgaut

Hi all,
        I have a scenario where in my HTML page which gets rendered at
the server in CGI contains a table. For a particular column in that
table and for each row, I will get an epoch value from the server
which I've to convert to Human readable format. I tried calling that
Javascript function as shown in the below code but it didn't work. I
am new to Javascript. So, can someone help me in this regard.

CGI Script

for each ()
{
<tr ...>
...
html .=  "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";
...

}

Javascript:
convert_time(epoch_time)
{
 .... // Processing
document.getElementById('epoch').innerHTML= tme;

}

I tried to put the code as simple as possible. The <td> repeats in a
loop for each row and this function should be invoked for each row's
td. Please let me know if you need any more clarifications.

Thank you,
Venu.


my advise would be :

- put the epoch as class in the TD tag, when you do getElementById
JavaScript will be confused as you it must returns one only element
and you severals with the same id


html .= "<td class=\"epoch\">".$epoch."</td>";

- put an class "with-epoch" to tables to parse

<table class="with-epoch">

- in your javascript code

convert_time(epoch_time)
{
.... // Processing
return tme;

}

document.onload = function ()
{

var tables, cols, i, j;

tables = document.getElementsByTagName('table');
for (i = tables.length; i > -1; i -= 1)
{
if (tables.className === "with-epoch") {

cols = tables.getElementsByTagName('td');
for (j = cols.length; j > -1; j -= 1)
{

if (cols[j].className === "epoch") {

cols[j].innerHTML = convert_time(cols[j].innerHTML);

}

}

}


}

}
 
T

Thomas 'PointedEars' Lahn

venu said:
I have a scenario where in my HTML page which gets rendered at
the server in CGI contains a table. For a particular column in that
table and for each row, I will get an epoch value from the server
which I've to convert to Human readable format. I tried calling that
Javascript function as shown in the below code but it didn't work.
I am new to Javascript.

But you are not new to programming, are you? So the first thing you
should have considered is debugging, and providing a *useful* error
description in your posting, including the error message provided by
the runtime environment if debugging did not help.

<http://jibbering.com/faq/#posting> pp.

However:
So, can someone help me in this regard.

CGI Script

CGI (Common Gateway Interface) is but an interface specification; it would
have been helpful to tell the programming language that you are using with
it (e.g., Bourne-Shell compatible script, Perl, PHP, Python).
for each ()

I doubt this is a meaningful statement in any programming language.
Probably you have omitted too much here.
{
<tr ...>
...
html .= "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";

This generates invalid HTML, see below. Besides, for this to work client-
side (or be Valid to begin with; ignoring the other problems, see below) it
matters what `$epoch' evaluates to, i.e. what the *client* receives.
...
}

Javascript:
convert_time(epoch_time)

Assuming that you have not omitted too much here:

The first thing one should do before first writing code in a programming
language is to RTFM of that language, to become familiar with its syntax
and semantics. This is J(ava)Script/ECMAScript, not e.g. Bourne-compatible
Shell-script. By contrast, you have not declared a function here, you have
tried to call one. As you apparently wanted to declare it instead, it was
probably not declared or defined before, so that unintentional call would
need to fail as `convert_time' could either not be resolved, or did not
resolve to a reference to a callable object.

So you probably want to precede this with the `function' keyword to make it
a function declaration.
{
.... // Processing
document.getElementById('epoch').innerHTML= tme;
}

Because the entire snippet could not be produced by the
/FunctionDeclaration/ production, and automatic semicolon insertion must
place the semicolon after the unintentional function call, the braces are
parsed as a Block statement. As a result, if the preceding statement did
not cause program abortion already, the statements in the Block statement
are immediately executed. It is possible that this would cause a(nother)
runtime error, for example if the elements being referred to had not yet
been parsed.
I tried to put the code as simple as possible. The <td> repeats in a
loop for each row and this function should be invoked for each row's
td. Please let me know if you need any more clarifications.

You really should learn the basics, in this case HTML, first. IDs must be
unique throughout a document (i.e. two elements MUST NOT have the same ID),
and TD elements certainly have no `onload' attribute. You can and should
search for those and further such mistakes by validating your markup:

<http://validator.w3.org/>

Perhaps you wanted to use the `onload' attribute of the BODY element to
call a function that used *different* `id' attribute values or same `class'
attribute values to fill the respective elements. But then the question
remained: Why would you not simply generate the element content with the
CGI script?

All in all, your current concept appears to lack severely in being thought
through. As always, you should try to explain what you want to achieve
instead of what problems you had to achieve it the way you thought, because
especially at your current experience level it is very likely, and almost
certain here, that you chose an unwise or completely wrong approach.


PointedEars
 
T

Thomas 'PointedEars' Lahn

Alexandre said:
venu said:
I have a scenario where in my HTML page which gets rendered at
the server in CGI contains a table. For a particular column in that
table and for each row, I will get an epoch value from the server
which I've to convert to Human readable format. I tried calling that
Javascript function as shown in the below code but it didn't work. I
am new to Javascript. So, can someone help me in this regard.

CGI Script

for each ()
{
<tr ...>
...
html .= "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";
...

}

Javascript:
convert_time(epoch_time)
{
.... // Processing
document.getElementById('epoch').innerHTML= tme;

}
[...]

[...]
- put the epoch as class in the TD tag,

when you do getElementById JavaScript will be confused

No, "it" won't. This has nothing to do with JavaScript, whatever you mean
by that (notice that there are several ECMAScript implementations in
browsrs). It is the _DOM implementation_ *accessible with* JavaScript (or
any other ECMASCript implementation, or bound programming language) that
"will be confused". More precisely, it depends on the DOM implementation
and therefore on the runtime environment implementing it (here, the Web
browser) what the return value of such a call made from within or on a
document tree of an invalid document would be:

The W3C DOM Level 3 Core Specification, which specifies this method for
objects implementing the Document interface, defines that the return value
would be not defined in that case, i.e. even in a standards-compliant DOM
implementation it can be anything. Bottom line: Avoid invalid markup.
as you it must returns one only element

No, if a standards-compliant DOM implementation encounters a document tree
with several element nodes with the same ID-type attribute in it, it is
free to return whatever its implementors saw fit. It would only appear
that many if not most implementors of HTML DOMs thought it would be the
best idea to return a reference to the element object that corresponds with
the first matching element in source code order.
and you severals with the same id

Yes, the markup is invalid and needs to be fixed before in any case.
html .= "<td class=\"epoch\">".$epoch."</td>";

<OT>
Suppose (as you appear to assume) this is PHP or Perl code (as indicated by
the `.=' and '.' operators), then the concatenation is unnecessary, and a
leading `$' would be missing (you cannot assign to constants):

$html .= "<td class=\"epoch\">$epoch</td>";

or

$html .= '<td class="epoch">' . $epoch . '</td>';

or (if PHP)

$html .= <<<HTML
<td class="epoch">{$epoch}</td>
HTML;

or (if Perl)

$html .= <<HTML;
<td class="epoch">$epoch</td>
HTML

It would be best, though, if the concatenation was avoided or its use
minimized. Therefore, one would probably not use the `.=' operator to
begin with.
</OT>

And, of course, much depends on the expanded value of `$epoch'.
- put an class "with-epoch" to tables to parse

<table class="with-epoch">

- in your javascript code

convert_time(epoch_time)

This is still no function declaration, so your suggestion will not help.
{
.... // Processing
return tme;

}

document.onload = function ()

Utter nonsense. This code should be executed by a call in the
`onload' attribute value of the `body' element, if at all.
{

var tables, cols, i, j;

tables = document.getElementsByTagName('table');

Did you know that you can declare and initialize a variable in the same
statement? And where are your feature tests?
for (i = tables.length; i > -1; i -= 1)

for (i = tables.length; i--;)

or (if you lose the declaration at the top)

for (var i = tables.length; i--;)

might be more efficient (lose one comparison, add one type conversion).
{
if (tables.className === "with-epoch") {


Did you know that newer DOM implementations have a built-in method to find
elements with a certain `class' attribute value?
cols = tables.getElementsByTagName('td');


This code can be more efficient if you assign `tables' to a local
variable.
for (j = cols.length; j > -1; j -= 1)

See above. Besides, the getElementsByTagName() method is not supported on
objects other than that referred to by the `document' property in some DOM
implementations. When in doubt, iterate over the `rows' and `cells'
NodeLists.
{

if (cols[j].className === "epoch") {

Did you know that a `class' attribute value can contain several class
names? And I would, with few exceptions, make a loose comparison where
host objects are involved.
cols[j].innerHTML = convert_time(cols[j].innerHTML);

Another possibility for decreased run time with regard to `cols[j]'.

And avoid `innerHTML', especially for text content. The standards-
compliant `textContent' and proprietary `innerText' properties are better
suited to this task (since we do not know whether the element already has
content, and so would need to test for the firstChild's nodeValue
otherwise.)


PointedEars
 
A

Alexandre Morgaut

Just to be quick

I tried to give to shortest and understandable working response with
some very few techniques like
- getting the JavaScript out of the HTML
- use class also to filter which HTML tree to work on (instead of all
the document)
- enhance a little for loops

I knew the code was perfectible



Sorry, in my hurry I forgot to type:
- "function" before "convert_time(epoch_time)"
- and ".body" before ".onload"
(I was going to take my train ;-) )





As specified in the most implemented DOM level 2
http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-102161490
And also in DOM level 3
http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-102161490

- getElementById is meant to return an "Element"

- while getElementsByTagName (note "s" at "elements") is meant to
return a "NodeList"


And yes it says about getElementById :

- "Behavior is not defined if more than one element has this ID.
" (DOM level 2)

- "If more than one element has an ID attribute with that value, what
is returned is undefined" (DOM level 3)

So yes I consider its confusing for the browser because what it must
do is not said
(and your code can't expect any specific behavior)






The way I wrote


html .= "<td class=\"epoch\">".$epoch."</td>";


used the same syntax as its code,


html .= "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";


only adding \ before some ", so there was good chance to be compatible
with
its server side language whatever it is

I could have suggested to use templates but it wasn't the point







I know this optimization

for (i = tables.length; i--;)

But it starts to make the code less understandable without more
explanation
I only use things like if I really have performance problem
And even then I would probably use
- the foreach Array method, but it requires to be added when not
available
- unrolled loops like with the Duff's device pattern

I prefer using var in top of the function, making no confusion for
less
experimented JavaScript developers who might think that i is only
available
in the loop scope despite JavaScript doesn't scope in loops

And the bonus is that it makes my code JSlint valid at "Good Parts"
level




I am aware about getElementsByClassName but as you said, it is not
supported
by all, even recent, browsers.

I am also aware that class can have multiple space separated class
names but it
will not be the case in this example, this case can be learned in a
next step.
(Well, now its done)

It will be just good if he, at least, starts to look at using the
class attribute.





I often use local variable to reference directly elements in loop like
you
suggest with code like "table = table;" but it is only interesting
when
the element is used several times in the iteration.
In this case it will be use 2 times by iteration at most, and only one
time
when the test fail. So the cost of the affectation may makes it
inefficient
for performance gain

There is still another advantage to do this affectation, and that's
why I may
have did it : clarity of the code...
"table" is really more readable than "tables"
and even "col.className" could have been more readable than
"cols[j].className"


I liked to use "rows“ and "cells" but you then need to be aware or
test if rows
are in a "tbody", a "thead", or in any of them, and here we didn't
knew.




Regards

Alexandre.
 
T

Thomas 'PointedEars' Lahn

Alexandre said:
Just to be quick

Quick replies are often terribly wrong (BTDT). We strive for quality here,
not quantity. It would have been better had you take your time in both
instances, did more research, and quoted what you were referring to, as it
is customary and appropriate on Usenet.
I tried to give to shortest and understandable working response with
some very few techniques like
- getting the JavaScript out of the HTML

It appears you have fallen victim to the common misconception that this
would generally be a good thing. Probably you have read a bad book from
someone who you consider a "JavaScript guru" and bought into all the
nonsense that they are spreading.
- use class also to filter which HTML tree to work on (instead of all
the document)

An ID for the table can fit the purpose of restricting the scope of the
application much faster.
- enhance a little for loops

I did not say anything against your `for' loops, did I?
[...]
Sorry, in my hurry I forgot to type:

If you can believe that.
- "function" before "convert_time(epoch_time)"
- and ".body" before ".onload"
(I was going to take my train ;-) )

It is still nonsense to rely on an unreliable proprietary feature when you
have full control over the generated document so you can use the reliable
standards-compliant one.

Your approach has little to nothing to do with the W3C DOM. Find me the
place in that Specification or W3C DOM Level 2 HTML where it says that
objects implementing the (HTML)Document or HTMLBodyElement interface have
an `onload' property.
- getElementById is meant to return an "Element"

Not in this case. Read the Specification.
- while getElementsByTagName (note "s" at "elements") is meant to
return a "NodeList"

Yes, but that does not matter here. Given a CGI script, we can generate
the IDs dynamically and then loop over the elements using IDs with an index
suffix passed to getElementById(). Considering the RegExp matching
required when using class names, that ID approach could be a lot faster,
and it is less likely to interfere with CSS.
And yes it says about getElementById :

- "Behavior is not defined if more than one element has this ID.
" (DOM level 2)

That was my point.
- "If more than one element has an ID attribute with that value, what
is returned is undefined" (DOM level 3)

So yes I consider its confusing for the browser because what it must
do is not said (and your code can't expect any specific behavior)

You are attributing human behavior to a machine which implements relentless
mechanical logic. And AISB the browser has little to nothing to do with
it.
The way I wrote

html .= "<td class=\"epoch\">".$epoch."</td>";

used the same syntax as its code,

Which was pointless from the outset ...
html .= "<td id = "epoch" onload='convert_time(".$epoch.");'></td>";

only adding \ before some ", so there was good chance to be compatible
with its server side language whatever it is

You are arguing from your level of experience.
I could have suggested to use templates but it wasn't the point

This has nothing to do with templates. I did not suggest them, did I?
I know this optimization

for (i = tables.length; i--;)

But it starts to make the code less understandable without more
explanation

You are arguing from your level of experience.
I only use things like if I really have performance problem

Try it out, and see for yourself. But be aware it does not apply to Array
initialization because of some built-in sparse array optimizations.
And even then I would probably use
- the foreach Array method, but it requires to be added when not
available

It would be breaking a fly on the wheel here, and a lot less efficient
because of all the function calls. Incidentally, I did not suggest it.
- unrolled loops like with the Duff's device pattern

You would.
I prefer using var in top of the function, making no confusion for
less experimented JavaScript developers who might think that i is only
available in the loop scope despite JavaScript doesn't scope in loops

JavaScript (and any other implementation of ECMAScript up to Edition 5)
with few exceptions has lexical scoping everywhere, not only in loops.
Anyone so "less experimented" as you describe should not be writing code
in an ECMAScript implementation in the first place. At least not outside
of their home network.
And the bonus is that it makes my code JSlint valid at "Good Parts"
level

JSLint and Crockford's "Good Parts" have their own problems, as discussed
here before. In fact, with regard to *browser scripting*, Crockford has a
lot of problems of his own (like advocating to use `window' to define
global variables). (Told you.)
I am aware about getElementsByClassName but as you said, it is not
supported
by all, even recent, browsers.

It does not hurt to try. Feature detection can readily find out whether it
is supported or not as well, and any built-in implementation must be a lot
faster than any user-defined one.
It will be just good if he, at least, starts to look at using the
class attribute.

Apparently you have not noticed that their main problem is that they don't
know HTML to begin with.
I often use local variable to reference directly elements in loop like
you suggest with code like "table = table;"


You would know that this is not only pointless but harmful if you knew what
you were talking about. But perhaps I am supposed to believe that this is
yet another obvious mistake because of a "quick reply" on your part.
but it is only interesting when the element is used several times in the
iteration.

The _object_ *is* accessed several times here.
In this case it will be use 2 times by iteration at most, and only one
time
when the test fail. So the cost of the affectation may makes it
inefficient
for performance gain

It is not. Try it out.

And either don't use Google Groups (given its recent References bug, you
would be well-advised to do so) or learn where the automatic line-breaks
happen. Your posting is a PITA to read for that alone (view the source,
that is how non-Googlodytes read it).
There is still another advantage to do this affectation,
Affectation?

and that's why I may have did it : clarity of the code...
"table" is really more readable than "tables"
and even "col.className" could have been more readable than
"cols[j].className"


You don't say.
I liked to use "rows“ and "cells" but you then need to be aware or
test if rows are in a "tbody", a "thead", or in any of them,

No, and that's the beauty of it.
and here we didn't knew.

Irrelevant.


PointedEars
 
T

Thomas 'PointedEars' Lahn

kangax said:
Thomas said:
Alexandre said:
I tried to give to shortest and understandable working response with
some very few techniques like
- getting the JavaScript out of the HTML
It appears you have fallen victim to the common misconception that this
would generally be a good thing. [...]

Depending on what is meant by "Javascript in HTML", this could certainly
be a good thing. For one, replacing "inline" script elements with
"external" ones, allows to take advantage of caching.

Not doing what you describe also allows to take advantage of caching.
And, as you can see, unfortunately what you describe was not meant here.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top