Forum Moderators: open

Message Too Old, No Replies

Print to Either Textfield

         

treeleaf20

1:40 pm on Jul 13, 2004 (gmt 0)

10+ Year Member



I want to try and create a typewriter effect to simulate a demo. My problem is that I want it to typewrite to the textfield that I select. This is the code I have that doesn't work:

<html>
<head>
<title>Typewriter for Demo</title>
<script>
<!--
var i = 0
var showString= ""
var location = ""
function marquee(location,myString)
{
showString = showString + myString
showString = myString
var stringLength= showString.length
document.show.location.value= document.show.location.value + showString.charAt(i)
i++
var timeID= setTimeout("marquee(location,showString)",100)
if (i >= stringLength)
{clearTimeout(timeID); i=0}
}

//-->
</script>
</head>

<body>
<form name="show">
<input type="text" name="text1" value="" onClick="javascript:marquee('text1','0123456');">
<input type="text" name="text2" value="" onClick="javascript:marquee('place2','9999999');">
</form>
</body>
</html>

Code that works but will only print to the first textfield even if you click on the second textfeild is this:

<html>
<head>
<title>Typewriter for Demo</title>
<script>
<!--
var i = 0
var showString= ""
function marquee(myString)
{
showString = showString + myString
showString = myString
var stringLength= showString.length
document.show.text1.value= document.show.text1.value + showString.charAt(i)
i++
var timeID= setTimeout("marquee(showString)",100)
if (i >= stringLength)
{clearTimeout(timeID); i=0}
}

//-->
</script>
</head>

<body>
<form name="show">
<input type="text" name="text1" value="" onClick="javascript:marquee('0123456');">
<input type="text" name="text2" value="" onClick="javascript:marquee('9999999');">
</form>
</body>
</html>

Can anyone please help?

DrDoc

3:44 pm on Jul 13, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



A reference to
document.show.location
will cause the browser to look for an element whose name is 'location', and that's not what you want. There are a couple different ways you can solve this... One way would be to use
eval()
to get the correct object. You could also give the text fields an ID, and use
document.getElementByID
(or
document.all
for old IE) as a reference to the text area... Or, you can simply change the way you refer to the text areas, which is what I did below.


<html>
<head>
<title>Typewriter for Demo</title>
<script>
<!--
var i = 0
var showString= ""
var location = ""
function marquee(location,myString)
{
showString = showString + myString
showString = myString
var stringLength= showString.length
document.forms[0].elements[location].value= document.forms[0].elements[location].value + showString.charAt(i)
i++
var timeID= setTimeout("marquee(location,showString)",100)
if (i >= stringLength)
{clearTimeout(timeID); i=0}
}

//-->
</script>
</head>

<body>
<form name="show">
<input type="text" name="text1" value="" onClick="javascript:marquee(0,'0123456');">
<input type="text" name="text2" value="" onClick="javascript:marquee(1,'9999999');">
</form>
</body>
</html>

treeleaf20

6:04 pm on Jul 13, 2004 (gmt 0)

10+ Year Member



Ok new problem. I have this code:
<html>
<head>
<title>Typewriter for Demo</title>
<script>
<!--
var i = 0
var showString = ""
var showName = ""
function marquee(myName,myString)
{
showName = myName
showString = myString
var stringLength= showString.length

if (document.getElementById(myName).value==myString)
{
document.getElementById(myName).value="";
}

document.getElementById(myName).value=document.getElementById(myName).value + showString.charAt(i)
//document.show.text1.value= document.show.text1.value + showString.charAt(i)
i++
var timeID= setTimeout("marquee(showName,showString)",100)
if (i >= stringLength)
{clearTimeout(timeID); i=0}
}
//-->
</script>
</head>

<body>
<form name="show">
<input type="text" name="text1" id="text1" value="" onClick="javascript:marquee(this.name,'0123456');">
<input type="text" name="text2" id="text2" value="" onClick="javascript:marquee(this.name,'test');">
</form>
</body>
</html>

When the document loads I want all the fields in the form to be populated with the information that I'm currently pass when I do the onClick command. Anyone kno whow to help. Thanks.

treeleaf20

6:06 pm on Jul 13, 2004 (gmt 0)

10+ Year Member



I thought about doing onLoad in the text fields as the action but that didn't work...

DrDoc

9:33 pm on Jul 13, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Why not just set the
value
attribute? :)

treeleaf20

10:06 pm on Jul 13, 2004 (gmt 0)

10+ Year Member



Because I want to it to be like a demo. Once the user clicks the link the fields start to populate with the information that we determined before hand. Like actually show the data being populated instead of setting the value = "" attribute and having the data already entered into the fields when the page is displayed. I want the visual effect of like someone had typed the fields in and we were watching them do it....I'm not sure if this can be done but if you can help that would be so greatly appreciated. Thanks in advance.

DrDoc

4:29 am on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



<body onload="marquee('text1','0123456');marquee('text2','test');">

treeleaf20

12:07 pm on Jul 14, 2004 (gmt 0)

10+ Year Member



That doesn't give me any errors but for the first text box it only prints out a single 0 and for the second text box it prints out esttest. I'm not sure why this would be the case. Here is the full code that I used as well:

<html>
<head>
<title>Typewriter for Demo</title>
<script>
<!--
var i = 0
var showString = ""
var showName = ""
function marquee(myName,myString)
{
showName = myName
showString = myString
var stringLength= showString.length

if (document.getElementById(myName).value==myString)
{
document.getElementById(myName).value="";
}

document.getElementById(myName).value=document.getElementById(myName).value + showString.charAt(i)
//document.show.text1.value= document.show.text1.value + showString.charAt(i)
i++
var timeID= setTimeout("marquee(showName,showString)",100)
if (i >= stringLength)
{clearTimeout(timeID); i=0}
}
//-->
</script>
</head>

<body onload="marquee('text1','0123456');marquee('text2','test');">
<form name="show">
<input type="text" name="text1" id="text1" value="">
<input type="text" name="text2" id="text2" value="">
</form>
</body>
</html>

DrDoc thanks for the help so far. I really appreciate it!

Bernard Marx

12:36 pm on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The problem lies with Asynchronicity (that's close to Confusionsville).

<body onload="marquee('text1','0123456');marquee('text2','test');">

This calls the function twice. You need to remember that every _Timeout is a new thread, so the 2nd function call will be executed straight after the first timer has been set in the first call. Since quite a few variables used are global, there will be a fair amount of interference. We need to keep everything passed 'within the loop', without using global vars.

Bernard Marx

12:47 pm on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member




note!:replace ¦¦ with unbroken pipes

function marquee(boxId,text,i) 
{
i = i¦¦0
var box = document.getElementById(boxId)
if(i==0) box.value = ""

box.value += text.charAt(i)

if(++i < text.length)
setTimeout("marquee('"+boxId+"','"+text+"',"+i+")",100)
}

// alternative

function marquee(boxId, text)
{
var i = 0
var box = document.getElementById(boxId)
var str = ""
box.value = ""
repeat()
function repeat()
{
str += text.charAt(i++)
box.value = str
if(i<text.length)
setTimeout(repeat,100)
}
}

treeleaf20

2:39 pm on Jul 14, 2004 (gmt 0)

10+ Year Member



Thanks, that works great. One last thing if it can be done. Is there a way so that onLoad it still fills in all the fields but the the second text field won't start typing until the first one has been populated. So for example the first text field gets populated with test and after test has been typed in with the onLoad function the second text field will be populated with test2. i hope that makes sense and you can help me out just more one time. Thanks in advance.

Bernard Marx

4:03 pm on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Again, the 2 alternatives. The reason I included an alternative before was that it is much easier to take things further with it. The only reason that I still included the first (with all its string concats) is that there is a question mark hanging over the alternative version's support in certain PDA user-agents, because it uses a function reference as the timer's 1st argument. I have no further information on this. It seems fine in 'normal' browsers, so perhaps this is OK for you.

The 'standard' version gets trickier to play with, as you can see (or maybe it just gets that way when I do it).

In both versions, you add the statement to execute later as an optional last argument, in the form of an anonymous function, but, in the 'standard' ver, if you are adding such a function, you also need to fill in the 'i' argument with a zero, to fill the place. In the 'alternative' you don't need to do that.

STANDARD

marquee('test1','test text',0, function(){alert('finished')})
// or
marquee('test1','test text',0,function(){ marquee('test2','more text')})

ALTERNATIVE

marquee('test1','test text',function(){alert('finished')})
// or
marquee('test1','test text',function(){ marquee('test2','more text')})

A handy tip:

If you want to use a long string, you can assign it to a variable in the script, then put the variable into the call in marquee(). You'd probably already guessed that. You can do the same thing with a complicated function.

-- script --

var text = "_a_very_long_string_"

function doThings()
{
// lots off stuff
}

-- fn call --

marquee('test1',text,doThings)


// STANDARD (replace ¦¦ again)

function marquee(boxId,text,i,nextFn)
{
i = i¦¦0
var box = document.getElementById(boxId)
if(!box.marquee_nextFn)
box.marquee_nextFn = nextFn

if(i==0) box.value = ""

box.value += text.charAt(i)

if(++i < text.length)
setTimeout("marquee('"+boxId+"','"+text+"',"+i+")",100)
else if(box.marquee_nextFn)
{
box.marquee_nextFn()
box.marquee_nextFn = null
}
}

// ALTERNATIVE

function marquee(boxId, text, nextFn)
{
var i = 0
var box = document.getElementById(boxId)
var str = ""
box.value = ""
repeat()
function repeat()
{
str += text.charAt(i++)
box.value = str
if(i<text.length)
setTimeout(repeat,100)
else if(nextFn)
nextFn()
}
}

treeleaf20

6:07 pm on Jul 14, 2004 (gmt 0)

10+ Year Member



I used this as my body onLoad command:
<body onload="marquee('test1','test text',function(){ marquee('test2','more text')});">

This is my function:
function marquee(boxId, text, nextFn)
{
var i = 0
var box = document.getElementById(boxId)
var str = ""
box.value = ""
repeat()
function repeat()
{ str += text.charAt(i++)
box.value = str if(i<text.length)
setTimeout(repeat,100)
else
if(nextFn)
nextFn()
}
}

I get an error message saying Object Expected on the on the line where the body onload command is. Any idea why this woudl be the case?

Bernard Marx

6:16 pm on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



That suggests that marquee isn't available. Try this:

<body onload="alert(marquee)">

If the result doesn't look positive, then that's it.
Is the function in an external .js file?

treeleaf20

6:27 pm on Jul 14, 2004 (gmt 0)

10+ Year Member



It said that marquee is undefined....I'm not sure why but when I run the code before the filled in all the fields at one time it worked great. Now when I try to do that new thing it doesn't find the function. Also the file is in the page...its not external js

Bernard Marx

7:36 pm on Jul 14, 2004 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hmm. I think you'll have to post (or sticky me) the whole page.

I should mention that, being lazy, I don't put in semi-colons at the end of statements most of the time. This, combined with WebmasterWorld's formatting quirks, can duck up scripts a little. For instance, the function you posted had a line:

box.value = str if(i<text.length)

Which should be:

box.value = str; 
if(i<text.length)

It may be something as simple as that.