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

problems reading the value of a textNode --- second attempt ---

P: n/a
Hi all,

I posted the same question this afternoon but my message isn't showing up, so I thought I'd give it another try....
in case you should see it later I apologize for posting the same question twice!
Here it is:
I am having problems reading the value of a text Node. I think it has to do with the fact that the text is in a <span> tag.
I have a table and in each <td> I have text + a checkbox. I want to retreive the text next to the checked checkboxes and concatenate it.

Here is my Code:
<body>
<table border="1">
<tr>
<td class="listColumn">
<span class="textItem">Hello</span>
<input type="Checkbox" Id="ChBox">
</td>
</tr>
<tr>
<td class="listColumn">
<span class="textItem">Hej</span>
<input type="Checkbox" Id="ChBox">
</td>
</tr>
</table>

<script language="JavaScript">
function getData(){
var values='';
for(i=0;i<document.getElementsByTagName('input').l ength;i++){
var x = document.getElementsByTagName('input')[i];
var a = x.parentNode.childNodes[1].nodeValue;
if (eval("x.checked") == true) {
values=values+'&p_Sample='+a;
}
}
document.write(values);
}
</script>
<input type="Button" value="Get Data" onclick="getData()">

</body>

If I run this example I get the following output:

&p_Sample=

Just as if the text were null.
I am pretty sure that I am pointing to the right object, because if I change "nodeValue" to nodeName I get "#text".

If I change my example, delete the <span> tags, and change "var a = x.parentNode.childNodes[1].nodeValue; " to "var a = x.parentNode.childNodes[0].nodeValue;
I get the expected result.

Could anybody help me understand why?

Thanks,

Anna

Jul 20 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Lee
Anna said:

This is a multi-part message in MIME format.
------=_NextPart_000_009D_01C3B858.7AE55AB0
Content-Type: text/html;
charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


Please post plain text to this newsgroup.

Jul 20 '05 #2

P: n/a
Anna wrote on 01 Dec 2003:
Hi all,

I posted the same question this afternoon but my message isn't
showing up, so I thought I'd give it another try.... in case you
should see it later I apologize for posting the same question
twice! Here it is:
I am having problems reading the value of a text Node. I think
it has to do with the fact that the text is in a <span> tag. I
have a table and in each <td> I have text + a checkbox. I want
to retreive the text next to the checked checkboxes and
concatenate it.

Here is my Code:
<body>
<table border="1">
<tr>
<td class="listColumn">
<span class="textItem">Hello</span>
<input type="Checkbox" Id="ChBox">
</td>
</tr>
<tr>
<td class="listColumn">
<span class="textItem">Hej</span>
<input type="Checkbox" Id="ChBox">
This is illegal. You already gave an element the id, ChBox. You also
gave neither checkbox a value (attribute), which is also illegal.
</td>
</tr>
</table>
I question the use of a table here. Is your data actually tabular?
<script language="JavaScript">
To specify the script language, use the type attribute, not language.
Language has been deprecated in favour of type. The above should
read:

<SCRIPT type="text/javascript">
function getData(){
var values='';
for(i=0;i<document.getElementsByTagName('input').l ength;i++){
The initialiser here declares i to be global. Use the var keyword.

Your condition expression is inefficient. It would be better to
obtain the length value outside of the loop and use a variable in the
condition.
var x = document.getElementsByTagName('input')[i];
That is also incredibly inefficient. Obtain the collection outside of
the loop, then index it inside.
var a = x.parentNode.childNodes[1].nodeValue;
The reason why you're not getting the correct value is because that
doesn't refer to the SPAN element. Even if it did, you wouldn't get
the value, because you have to access the first child node of the
SPAN. You'll also have a problem with this technique, as the input
button would be returned in the collection. You could solve this by
changing it to a BUTTON element instead, or checking the element
type.

To get the SPAN node, this would work:

inp.previousSibling.previousSibling

where inp is one of the checkboxes. This shows that there is another
node (the text node that you were getting) between the INPUT and the
SPAN elements (most likely, the whitespace). What I can't explain (I
don't know enough about the DOM) is why

inp.parentNode.childNodes[ 0 ]

will refer to the same node as the above. If the whitespace between
the INPUT and SPAN is a node, why isn't that between the TD and SPAN
elements?

Anyway, a full solution is included at the end of this post.
if (eval("x.checked") == true) {
*Gasp!!* Why on Earth are you using eval()?!? Whatever book told
you to do that needs to be ripped up and burnt.

OK, dropping the melodrama: you /really/ don't need to use eval()
here. In fact, there is never really any need to use eval().

if ( true == x.checked )

will work just fine.
values=values+'&p_Sample='+a;
}
}
document.write(values);
It's better to use an alert box when testing values. My browser did
some nasty things when it executed that line.

window.alert( values );

is just as clear and doesn't introduce the possibility of interfering
with the contents of the document.
}
</script>
<input type="Button" value="Get Data" onclick="getData()">
I hope you've specified the default script language...
</body>

If I run this example I get the following output:

&p_Sample
Just as if the text were null.
I am pretty sure that I am pointing to the right object, because
if I change "nodeValue" to nodeName I get "#text".

If I change my example, delete the <span> tags, and change "var
a = x.parentNode.childNodes[1].nodeValue; " to "var a =
x.parentNode.childNodes[0].nodeValue; I get the expected
result.


<snipped HTML post>

The function should be written as:

function getData() {
var values = '';
var tags = document.getElementsByTagName( 'input' );
var length = tags.length;

for ( var i = 0; i < length; ++i ) {
var elem = tags[ i ];
if ( 'checkbox' != elem.type ) continue;
if ( true == elem.checked ) {
values += '&p_Sample='
+ elem.parentNode.firstChild.firstChild.nodeValue;
}
}
window.alert( values );
}

Mike

--
Michael Winter
M.******@blueyonder.co.uk.invalid (remove ".invalid" to reply)
Jul 20 '05 #3

P: n/a
Anna wrote:
I posted the same question this afternoon but my message isn't showing
up, so I thought I'd give it another try....
I hope you know that Usenet is not a real-time medium as chat is.
in case you should see it later
No dupes here.
I have a table and in each <td> I have text + a checkbox. I want to
retreive the text next to the checked checkboxes and concatenate it.

Here is my Code:
Is it the *complete* code in the document? If yes, the (X)HTML is
invalid even if you fix what I have noted below, thus you would then
get no reliable access to the DOM at all.
<body>
<table border="1">
<tr>
<td class="listColumn">
<span class="textItem">Hello</span>
<input type="Checkbox" Id="ChBox"> ^^^^^ </td>
</tr>
<tr>
<td class="listColumn">
<span class="textItem">Hej</span>
<input type="Checkbox" Id="ChBox"> ^^^^^
ID means identity. IDs need to be unique throughout a document.
If you need elements with the same name, use the `name' attribute.
</td>
</tr>
</table>

<script language="JavaScript">
The `language' attribute is deprecated and the `type' attribute
is not only required but also backward and forward compatible.

<script type="text/javascript">
function getData(){
var values='';
for(i=0;i<document.getElementsByTagName('input').l ength;i++){
Hold on. You don't know that `document' has a `getElementsByTagName'
property as this depends on the DOM and therefore on the user agent
(UA). It is wise to test objects and properties before accessing them:

---> http://pointedears.de.vu/scripts/test/whatami
---> http://pointedears.de.vu/scripts/dhtml.js

And you are declaring `i' global (the `var' keyword is missing) which
is bad style. Try this:

var aInputs = null;

// W3C-DOM compatibles
if (typeof document.getElementsByTagName == "function"
|| typeof document.getElementsByTagName == "object")
aInputs = document.getElementsByTagName

// IE 4.x and compatibles
else if (document.all && document.all.tags)
aInputs = document.all.tags('input');

if (aInputs)
{
var x = document.getElementsByTagName('input')[i];
var a = x.parentNode.childNodes[1].nodeValue;
You are not checking for objects and properties again.

var x = null;
var a = "";

for (var i = 0; i < aInputs.length; i++)
{
x = aInputs[i]; // resolve only once ==> faster
a = "";
if (x.parentNode
&& x.parentNode
&& x.parentNode.childNodes
&& x.parentNode.childNodes[1]
&& typeof x.parentNode.childNodes[1].nodeValue
!= "undefined")
{
a = x.parentNode.childNodes[1].nodeValue;

You will require an additional solution for IE 4.x, though, as started
above.
if (eval("x.checked") == true) {
Don't use eval(...) for this. You won't need eval(...) in most cases.

if (x.checked)
{
values=values+'&p_Sample='+a;
}
}
}
document.write(values);
document.write(...) after the document is loaded overwrites it and thus
clears all variables and functions defined therein. So you cannot use
document.write(...) in functions invoked in events handlers if you want
to preserve the current document. I presume you do that for debugging
purposes, use alert(...) instead. You can even use alert in the
location bar as I entered

javascript:alert(String(document.getElementsByTagN ame("input")[0].parentNode.childNodes[0]))

and similar while exploring the DOM tree of your document (in
Mozilla/5.0 rv:1.6b).
}
</script>
<input type="Button" value="Get Data" onclick="getData()"> ^^^^^^^^^ </body>
If I run this example I get the following output:

&p_Sample=
What error messages do you get in the JavaScript console or does
the browser show (you could have error messages disabled)?
Just as if the text were null.
I am pretty sure that I am pointing to the right object, because if I
change "nodeValue" to nodeName I get "#text".

If I change my example, delete the <span> tags, and change "var a =
x.parentNode.childNodes[1].nodeValue; " to "var a =
x.parentNode.childNodes[0].nodeValue;
I get the expected result.

Could anybody help me understand why?


If `x' references the `input' element (through the collection), its
parent element here (x.parentNode) is the `td' element and the *second*
child (x.parentNode.childNodes[1]) of it is the `span' element. (You
have included a text node as you wrote a newline after the td's start
tag which becomes the first child.) The nodeValue of the `span' element
is of course `null' since it contains a text node as first and only
child. The nodeValue property of this child is most certainly what you
are looking for.

If you remove the `span' element, the `input' element becomes the second
child of the `td' element (x.parentNode.childNodes[1]) while the first
child is still the empty text node created by the newline. That depends
on how you "delete the <span> tags", however. If you also remove the
newline, the first child will be the `input' element.

But why this complicated?

<form action="...">
Hello <input type="checkbox" name="p_Sample" value="Hello"><br>
Hej <input type="button" name="p_Sample" value="Hej"><br>
<input type="submit">
</form>

This submit even works without JavaScript. BTW, users are used to have
the label of a checkbox right to it.
HTH

PointedEars

P.S.
Please don't post Multipart HTML, Usenet is a text-only medium
except of few binary newsgroups (which this group is not.)
Jul 20 '05 #4

P: n/a
"Michael Winter" <M.******@blueyonder.co.uk.invalid> wrote in message
news:Xn*******************************@193.38.113. 46...
<snip>
if ( true == x.checked )

will work just fine.

<snip>

It will work fine but, as the if statement must resolve its expression
to a boolean value and any type converting comparison with a boolean
value will produce a value that is directly related to the
type-converted trueness of the other operand, it is always possible to
use the other operand as the expression for the if statement without the
comparison. So:-

if( x == true ){ ... } - or - if( x != false ){ ... }

- always produce the same result as:-

if( x ){ ... }

- and -

if( x != true ){ ... } - or - if( x == false ){ ... }

- always produce the same result as:-

if( !x ){ ... }

Though the checked property of checkboxes are boolean to start with so
type-converting doesn't come into play in this case.

Richard.
Jul 20 '05 #5

P: n/a
Michael Winter wrote:
Anna wrote on 01 Dec 2003:
<table border="1">
<tr>
<td class="listColumn">
<span class="textItem">Hello</span>
<input type="Checkbox" Id="ChBox">
</td>
</tr>
<tr>
<td class="listColumn">
<span class="textItem">Hej</span>
<input type="Checkbox" Id="ChBox">
This is illegal. You already gave an element the id, ChBox.


Full ACK
You also gave neither checkbox a value (attribute), which is also
illegal.
JFTR: It is not recommended, but not *invalid*.

,-<http://www.w3.org/TR/html4/strict.dtd>------------------------------
|
| <!ELEMENT INPUT - O EMPTY -- form control -->
| <!ATTLIST INPUT
| %attrs; -- %coreattrs, %i18n, %events --
| type %InputType; TEXT [...]
| name CDATA #IMPLIED -- submit as part of form --
| value CDATA #IMPLIED -- Specify for radio buttons
| and checkboxes --
| [...]
var a = x.parentNode.childNodes[1].nodeValue;


The reason why you're not getting the correct value is because that
doesn't refer to the SPAN element.


Depends on whether the UA considers the whitespace a text node of
the DOM.
What I can't explain (I don't know enough about the DOM) is why

inp.parentNode.childNodes[ 0 ]

will refer to the same node as the above. If the whitespace between
the INPUT and SPAN is a node, why isn't that between the TD and SPAN
elements?
That differs from one UA to another. IIRC IE does not consider
leading whitespace a text node while Mozilla/5.0 does. Tests
with IE 5.00.3502.1000 and Mozilla/5.0 rv:1.6b on Win2k back
this up.
[....]
OK, dropping the melodrama: you /really/ don't need to use eval()
here. In fact, there is never really any need to use eval().
There are rare occasions where eval(...) is useful.
if ( true == x.checked )

will work just fine.


The additional comparison is not required, x.checked is boolean already.

if (x.checked)

will work fine and will also work if x.checked is somehow undefined.
PointedEars
Jul 20 '05 #6

P: n/a
Richard Cornford wrote on 02 Dec 2003:
It will work fine but, as the if statement must resolve its
expression to a boolean value and any type converting comparison
with a boolean value will produce a value that is directly
related to the type-converted trueness of the other operand, it
is always possible to use the other operand as the expression
for the if statement without the comparison. So:-


I know, I know, I know. I just copied the expression, removed the
eval() call and left it, without thinking of what it was actually
doing.

Mike

--
Michael Winter
M.******@blueyonder.co.uk.invalid (remove ".invalid" to reply)
Jul 20 '05 #7

P: n/a
Thomas 'PointedEars' Lahn wrote on 02 Dec 2003:
Michael Winter wrote:


<snip>
This is illegal. You already gave an element the id, ChBox.


Full ACK


Umm, excuse me? Even if ACK is used as the abbreviation of
acknowledgment, it still doesn't quite make sense (don't take that
badly, I just really don't know what you mean there).
You also gave neither checkbox a value (attribute), which is
also illegal.


JFTR: It is not recommended, but not *invalid*.


<snipped specification quote>

From further down the page:

value = cdata [p.50] [CA] [p.49]
This attribute specifies the initial value [p.220] of the control.
It is optional except when the type attribute has the value "radio"
or "checkbox".

The important phrase there is, "optional except".

<snip>
OK, dropping the melodrama: you /really/ don't need to use
eval() here. In fact, there is never really any need to use
eval().


There are rare occasions where eval(...) is useful.


That's why I said, "never really", rather than an absolute, "never".
if ( true == x.checked )

will work just fine.


The additional comparison is not required, x.checked is boolean
already.

if (x.checked)

will work fine and will also work if x.checked is somehow
undefined.


Please read my response to Mr Cornford's reply.

Mike

--
Michael Winter
M.******@blueyonder.co.uk.invalid (remove ".invalid" to reply)
Jul 20 '05 #8

P: n/a
"Michael Winter" <M.******@blueyonder.co.uk.invalid> wrote in message
news:Xn******************************@193.38.113.4 6...
It will work fine but, ...
<snip>I know, I know, I know. I just copied the expression, removed
the eval() call and left it, without thinking of what it was
actually doing.


Yes, sorry, I guessed that it was probably just an oversight on your
part but it is a bit of a bugbear for me so I don't like to see the
unnecessary use of comparisons with boolean values going uncommented.

Richard.
Jul 20 '05 #9

P: n/a
Michael Winter wrote:
Thomas 'PointedEars' Lahn wrote on 02 Dec 2003:
Michael Winter wrote:
This is illegal. You already gave an element the id, ChBox.
Full ACK


Umm, excuse me? Even if ACK is used as the abbreviation of
acknowledgment, it still doesn't quite make sense (don't
take that badly,


Not at all. It is better to ask than not to ask and to misunderstand.
I just really don't know what you mean there).


`ACK' can (and should here) also be understood as agreement, approval,
endorsement, consent, acceptance. (As English is not my native language,
I took the latter terms from the translation in babylon.com's
dictionary; HTH).

See also http://catb.org/~esr/jargon/html/A/ACK.html and similar
dictionaries.
You also gave neither checkbox a value (attribute), which is
also illegal.


JFTR: It is not recommended, but not *invalid*.


<snipped specification quote>

From further down the page:

value = cdata [p.50] [CA] [p.49]
This attribute specifies the initial value [p.220] of the control.
It is optional except when the type attribute has the value "radio"
or "checkbox".

The important phrase there is, "optional except".


That is why it is not recommended. The DTD, however, specifies the
attribute value as #IMPLIED which means (AIUI) the attribute name is
optional in valid HTML 4.01 Strict. I find this understandable as
a checkbox (or a radiobutton) can be used merely as a control object
and not a form element where the latter would require a value to make
the submitted data make sense.
OK, dropping the melodrama: you /really/ don't need to use
eval() here. In fact, there is never really any need to use
eval().


There are rare occasions where eval(...) is useful.


That's why I said, "never really", rather than an absolute, "never".


ACK (again ;-))
if (x.checked)

will work fine and will also work if x.checked is somehow
undefined.


Please read my response to Mr Cornford's reply.


[x] done
\V/ Live long and prosper

PointedEars
Jul 20 '05 #10

P: n/a
Thomas 'PointedEars' Lahn wrote on 02 Dec 2003:

<snip>
Not at all. It is better to ask than not to ask and to
misunderstand.
My thoughts exactly.

<snip>
See also http://catb.org/~esr/jargon/html/A/ACK.html and similar
dictionaries.


Interesting. I wanted a good jargon guide. So many acronyms and
abbreviations...
From further down the page:

value = cdata [p.50] [CA] [p.49]
This attribute specifies the initial value [p.220] of the
control. It is optional except when the type attribute has
the value "radio" or "checkbox".

The important phrase there is, "optional except".


That is why it is not recommended. The DTD, however, specifies
the attribute value as #IMPLIED which means (AIUI) the attribute
name is optional in valid HTML 4.01 Strict. I find this
understandable as a checkbox (or a radiobutton) can be used
merely as a control object and not a form element where the
latter would require a value to make the submitted data make
sense.


Agreed. A strict SGML parser won't complain, as the grammar of HTML
is general - no exceptions related to specific control types are
made. However, I would have thought that that was the result of a
limitation in the grammar. The intention would be that authors
respected that exception an included values. Nevertheless, as form
controls are regularly used as GUI elements (as in this case), not
just as form components, the exception doesn't always apply (an
exception to the exception :). Point conceded.

Mike

--
Michael Winter
M.******@blueyonder.co.uk.invalid (remove ".invalid" to reply)
Jul 20 '05 #11

P: n/a
Hi Thomas,

thank you so much for answering.
Is it the *complete* code in the document? If yes, the (X)HTML is
invalid even if you fix what I have noted below, thus you would then
get no reliable access to the DOM at all.
Well it 's just a chunk of code taken from my page...but why would it be
invalid if I fix it as you suggest?

But why this complicated?

<form action="...">
Hello <input type="checkbox" name="p_Sample" value="Hello"><br>
Hej <input type="button" name="p_Sample" value="Hej"><br>
<input type="submit">
</form>


As I said in my other post, my table is generated by a reporting tool and I
am just trying to add some script to make it more interactive.

Thanks again,

Anna
Jul 20 '05 #12

P: n/a
Anna wrote:
thank you so much for answering.


You are welcome.
Is it the *complete* code in the document? If yes, the (X)HTML is ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid even if you fix what I have noted below, thus you would then
get no reliable access to the DOM at all.


Well it 's just a chunk of code taken from my page...but why would it be
invalid if I fix it as you suggest?


Because the assumption seems not to apply, my conclusion is most
certainly not applicable here. However, if it were the complete
code, the DOCTYPE declaration and a bunch of HTML elements (the
`html' element at least) would be missing for valid HTML.

---> http://validator.w3.org/
But why this complicated?

<form action="...">
Hello <input type="checkbox" name="p_Sample" value="Hello"><br>
Hej <input type="button" name="p_Sample" value="Hej"><br>
<input type="submit">
</form>


As I said in my other post, my table is generated by a reporting tool
and I am just trying to add some script to make it more interactive.


I am afraid that there is neither another posting from you here nor have
you mentioned the reporting tool in the OP.

How does the reporting tool create the table, is it a server-side or a
client-side application? If the former and it returns not only the
table but the whole document, it is nearly impossible (at least it is
not possible reliably as it depends on the users in the target group)
to add functionality without breaking HTML validity.
PointedEars
Jul 20 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.