nextSibling doesn't work

B

BillKi

I am trying to use nextSibling to move focus to the next input (text
box).

Here's the script:
function CheckFieldLength(e, i)
{
// don't move automatically forward if a tab or shift-tab was just
entered
if (!(e.keyCode == 16 || e.keyCode == 9))
{
if(i.value.length == 4 )
{
if(i.nextSibling != null)
i.nextSibling.focus();
}
}
}

And here's the call
<input name="text1" size="4" type="text" maxlength="4"
onkeyup="CheckFieldLength(event, this);" />

After entering 4 chars, I get a Javascript error that says
object doesn't support this property or method.

Where am I going wrong? Thanks
 
L

Lasse Reichstein Nielsen

BillKi said:
I am trying to use nextSibling to move focus to the next input (text
box). ....
if(i.nextSibling != null)
i.nextSibling.focus(); ....
After entering 4 chars, I get a Javascript error that says
object doesn't support this property or method.

At what line? My bet is that it's the "focus" property that
is missing. How do you know that the next sibling is an input
element, and not, e.g., a text node? (which it probably is :)

So, try something like this instead:
---
do {
i = i.nextSibling;
} while (i != null && i.nodeName != "INPUT");
if (i != null) {
i.focus();
}
 
B

BillKi

The error occurs on the line where I try to determine if the
nextSibling is null
if(i.nextSibling != null)

Let me try your suggestion and see if that helps...

Thank you
 
B

BillKi

Whoops -- your example put me into an endless loop. Had to kill the
browser to get out of it!!
 
R

RobG

BillKi said:
Whoops -- your example put me into an endless loop. Had to kill the
browser to get out of it!!

Please quote what you are replying to. If you are using Google groups,
click the 'Show options' link and then the 'Reply' link below subject.


Here's a variation on Lasse's loop:

while ( i.nextSibling && ( 'INPUT' != i.nodeName ) ) {
i = i.nextSibling;
}
if ( i.focus ) i.focus();
 
L

Lasse Reichstein Nielsen

Please quote what you are responding to. The example was:
---
do {
i = i.nextSibling;
} while (i != null && i.nodeName != "INPUT");
if (i != null) {
i.focus();
}
---
Whoops -- your example put me into an endless loop. Had to kill the
browser to get out of it!!

Interesting ...

For that code to loop endlessly, it would mean that i never becomes
equal to "null". Since "undefined" is equal to "null", you must have
an infinite (most likely cyclic) chain of non-null nextSibling
elements.

Can we see the page that exhibits this behavior?

/L
 
L

Lasse Reichstein Nielsen

RobG said:
Here's a variation on Lasse's loop:

Almost :)
while ( i.nextSibling && ( 'INPUT' != i.nodeName ) ) {

If i.nodeName == 'INPUT', then the loop body is not executed, and i is
not changed. The next time through, i is still the same (input)
element. You need an extra i=i.nextSibling before the while loop.
i = i.nextSibling;
}
if ( i.focus ) i.focus();

/L
 
B

BillKi

Here's the whole page: The error occurs in the CheckFieldLength
function whereever I refer to i.nextSibling. The error message is
"object doesn't support this property or method"

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Testing Sibling Script</title></head>
<script type="text/javascript">
<!--
function CheckFieldLength(e, i)
{
// don't move automatically forward if a tab or shift-tab was just
entered
if (!(e.keyCode == 16 || e.keyCode == 9))
{
if(i.value.length == 4 )
{
if(i.nextSibling != null)
i.nextSibling.focus();
}
}
}

function CheckForEnter(e, f)
{
var keycode;
if (e.keyCode)
keycode = e.keyCode;
else
keycode = e.which;

if (keycode == 13)
{
f.submit();
}
}

// -->
</script>
<body>
<h1>Testing Sibling Script</h1>
<form action="testsiblings.htm" method="post" name="MainForm">
Voucher Number: <input name="text1" size="4" type="text" maxlength="4"
onkeyup="CheckFieldLength(event, this);" />
<input name="text2" size="4" type="text" maxlength="4"
onkeyup="CheckFieldLength(event, this);" />
<input name="text3" size="4" type="text" maxlength="4"
onkeyup="CheckFieldLength(event, this);" />
<input name="text4" size="4" type="text" maxlength="4"
onkeypress="CheckForEnter(event, this.form);" />
<br /><input name="btnSubmit" type="button" value="Submit" />
</form>
</body>
</html>
 
L

Lasse Reichstein Nielsen

BillKi said:
Here's the whole page: The error occurs in the CheckFieldLength
function whereever I refer to i.nextSibling. The error message is
"object doesn't support this property or method"

In FireFox, I get the error messsage:
---
Error: i.nextSibling.focus is not a function
---
Also, I know that Gecko based browsers will have a text node as
next sibling for this HTML code, so that error is easily explained.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Ah, XHTML, then the nodeName is probably in lower case, not
upper case as my code suggested.
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Testing Sibling Script</title></head>
<script type="text/javascript">

The script element must be inside either the head or body element
in HTML. Just move the said:

That HTML comment is not necessary.
function CheckFieldLength(e, i)
{
// don't move automatically forward if a tab or shift-tab was just
entered

(Be careful when posting code that your news client doesn't wrap lines.
It's a good idea to keep the posted code to 72 chars to avoid that ...
or use a client that doesn't automatically wrap lines)
if (!(e.keyCode == 16 || e.keyCode == 9))
{
if(i.value.length == 4 )
{

Ok so far ...
if(i.nextSibling != null)
i.nextSibling.focus();

I suggest changing these two lines to:
---
do {
i = i.nextSibling;
} while (i && !i.tagName ||
i.tagName.toLowerCase() != "input");
if (i != null) {
i.focus();
}
---
This is slightly longer than the previous example, because it
cares about the case of tag names.

It works in FireFox and IE.

Good luck.
/L
 
B

BillKi

I suggest changing these two lines to:
---
do {
i = i.nextSibling;
} while (i && !i.tagName ||
i.tagName.toLowerCase() != "input");
if (i != null) {
i.focus();
}
This is slightly longer than the previous example, because it cares
about the case of tag names.

It works in FireFox and IE. <<<<

And it works for me!!

Thank you for your help - Bill
 
T

Thomas 'PointedEars' Lahn

Lasse said:
[...] it's the "focus" property that is missing. How do you know that the
next sibling is an input element, and not, e.g., a text node? (which it
probably is :)

So, try something like this instead:
---
do {
i = i.nextSibling;
} while (i != null && i.nodeName != "INPUT");
if (i != null) {
i.focus();
}
---

Not this way.
If you want to call focus(), test for *it*, not anything else:

var t;
if ((t = typeof i.focus) == "function" || (t == "object" && i.focus))
{
i.focus();
}

<http://pointedears.de/scripts/test/whatami>, §2.


PointedEars
 
L

Lasse Reichstein Nielsen

Thomas 'PointedEars' Lahn said:
Lasse Reichstein Nielsen wrote: ....

Not this way.
If you want to call focus(), test for *it*, not anything else:

It's not testing for "focus", admitted, but it isn't testing for
anything else either, except the existence of a following input
element.

Since the "focus" method on an input element has existed in all
browsers since Netscape 2, as well as being part of the W3C DOM for
HTML since version 1, it's not something I would bother to test for.

It would be more reasonable to test for the nextSibling and tagName
properties (which the next version I posted used instead of nodeName).
var t;
if ((t = typeof i.focus) == "function" || (t == "object" && i.focus))

This would error if "i" is null, and would not otherwise make anything
safer. Remember, when we exit the previous loop, i either points to
an input element or is null.


The original poster allowed himself to assume that all the relevant
input elements of his form were siblings. I find that unlikely, and
if not, more complicated code will be needed, but this code (or rather,
the updated version posted later) solves the stated problem.

/L
 
T

Thomas 'PointedEars' Lahn

Lasse said:
[...]
Since the "focus" method on an input element has existed in all
browsers since Netscape 2, as well as being part of the W3C DOM for
HTML since version 1, it's not something I would bother to test for.

I read of UAs here that don't support it anyway, so disagreed. I came to
recognize that it is best to test for all host features prior to usage
rather than taking chances.
It would be more reasonable to test for the nextSibling and tagName
properties (which the next version I posted used instead of nodeName).
ACK


This would error if "i" is null, and would not otherwise make anything
safer. Remember, when we exit the previous loop, i either points to
an input element or is null.

Yes, should be

var t;
if (i && ((t = typeof i.focus) == "function"
|| (t == "object" && i.focus)))

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top