Forum Moderators: open

Message Too Old, No Replies

Custom countdown timer

Where a button click performs several functions

         

bsbarker

9:17 am on Jan 16, 2010 (gmt 0)

10+ Year Member



I've found dozens of different countdown timer scripts but none do exactly what I need. Unfortunately, I'm still in my copy/paste days of web programming, so I don't know what I'm doing well enough to modify them to meet my needs. Hopefully someone can take an existing script and modify it for me.

What I need is a timer script that:
1. Counts down from what ever time I specify in hh:mm:ss.

2. Stays in sync with the seconds on the server clock.

3. At the click of one button by the user:
a) Advance the timer UP to the next ten-second mark.
b) Add 1 point to a <div> that displays the number of clicks for that button.
c) As that <div> reaches certain various numbers of my choosing, change the contents (the prize) displayed in a second <div>.
d) Display (in a third <div>) the username of the user who most recently clicked the button.

4. Replaces the timer with the words "two" "one" when the countdown reaches 2, 1.

5. Checks the server for last-second button clicks when the countdown reaches 0, and:
a) Deactivates the button during this check.
b) Replaces the timer with the word "verifying" during this check.

6. If no last-second clicks are found:
a) Replace the timer with the words "game over".
b) The button remains deactivated.
c) Redirect the winner (the last user to click the button before 0) to another page to claim their prize.

7. Can accomodate as many separate and unique timer/button/<div> setups as I want on a single page.

Whew... that's a lot! This is VERY similar to what is used on several "penny auction" sites. Same idea with some different requirements. So if you want a visual of the idea I'm shooting for, do a google search for "penny auctions" and most of the first few listings should have a similar timer.

I realize a script exactly like this doesn't exist, so if anyone is willing to write it up for me I will think the world of you for taking the time!

Notes within the script would be wonderful, but I'll be happy with what ever I can get. :)

bsbarker

9:23 am on Jan 16, 2010 (gmt 0)

10+ Year Member



One clarification:

1. Counts down from what ever time I specify in hh:mm:ss.

Meaning I specify the time on the back end. This should not be changable from the page itself.

Please let me know if I'm unclear about anything (or all) else.

MichaelBluejay

2:50 am on Jan 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Whew, you're asking a lot. But also, WW isn't the place to find people to write scripts for you, it's the place to learn how to do things yourself. If you're deadset on hiring someone rather than learning, then I'll suggest you look at a site such as Elance or RentACoder. But assuming you want to learn, let's start there.

First off, you're going to need to get your server to feed the server time to your page, where JavaScript can grab it and use it. You can't use the current time according to JavaScript, because that's based on whatever the user's computer is set to. Here's one way of inserting the server time into the page, using SSI (server-side includes):

<!--#include virtual="servertime.cgi"-->

The contents of the servertime.cgi file is:

#! /usr/bin/perl

print "Content-type:text/html\n\n";
$servertime = time;
print "<input type=hidden name=servertime value='$time'>";

Now you have a hidden field on the page which JavaScript can access. For example:

<script type=text/javascript>
theServerTime = document.getElementById('servertime').value;
alert(theServerTime);
</script>

There is lots, lots more to your project, but let's make sure you understand everything above before we go further.

bsbarker

8:18 am on Jan 17, 2010 (gmt 0)

10+ Year Member



Hi Bluejay,

Thanks a ton for your reply and the clarification on WW's purpose. Your assumption is totally right that I'd like to learn to do this myself rather than hiring it out, so if you're willing to walk me through it then you rock and I am a sponge.

In that case, though, I'll need to get my site uploaded to a server before I can begin. Which I was going to do anyway since I just finished the design portion. So I'll do that and then we can continue.

I did create a "servertime.cgi" file with the contents you gave and inserted the #include comment into top of the <body> of my source page.
I also made a "servertime.js" file with the script you gave (minus the <script></script>) and pointed to it in the <head>.
However, I get an error with the .js file saying "Object required" on line 1, char 1. Is this just because I'm not on a server yet or did I do something wrong?

MichaelBluejay

10:38 am on Jan 17, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Great, we're making progress.

You don't actually have to upload your whole site, or even a finished page. You can work with scratch test files.

The first thing is to make sure your SSI (the "include virtual" bit) loads properly. If you've never used SSI's before, you have to add this line to your .htaccess file:

AddHandler server-parsed .htm .html

That tells the server to look for SSI's to load in any file that ends in .htm or .html. This won't work when you view the file locally, since it's your web server that inserts the file. Oh, and your .htaccess file is at the same level as your <index.html> file. If you don't have one, you can create it, it's just a text file. Note that some file transfer programs don't display files that begin with a period, so you might have an .htaccess file but not be able to see it.

Next, you'll need to set the file permissions for your .cgi file to 755 to get it to run. You might be able to do this with your file transfer software, or if you're handy with UNIX, you'd log into your account and type:

chmod 755 servertime.cgi

Moving on, I suggest keeping your JavaScript on the page itself rather than an external file while you're building this project. That way there's only one file to edit. Once you've got everything working the way you want it, then you can stick the JS into a separate file.

Next, yes, you're getting the "Object required" error because you're not running the file on the server. The SSI is going to write the hidden servertime field onto your page, so your JS can access it. But since you didn't run the file from the server, then there is no hidden servertime field, so your JS can't find it, so it's complaining. Best thing is to upload your file to the server and run it there.

Okay, that ought to keep you busy.

bsbarker

8:59 am on Mar 3, 2010 (gmt 0)

10+ Year Member



Hello MichaelBluejay,

I apologize for such a long absence. To put it simply, I had to put this project on hold for a few weeks to focus on other things and to secure a test server. However, this will now be my main focus and I'm ready to hit the ground running if you're still able to help me out.


So, picking up where we left off, I:

1. Am now working on a server instead of my desktop.
2. Completed the three bits in your first reply.
3. Moved the JavaScript onto my page instead of an external file, as you suggested.
4. Added the AddHandler line to the bottom of my .htaccess file.
Note: My page is named index.php - do I need to add .php to that line as well? (I tried that and still got the error mentioned below)
5. Set the file permissions for servertime.cgi to 755 using my file transfer software (Ipswitch WS_FTP) since I have no experience using Linux.
Note: my file path is includes/servertime.cgi and my #include line reads:
<!--#include virtual="includes/servertime.cgi"-->


However, I am still getting the following error with the file on my server and using IE7:

Webpage error details

Message: Object required
Line: 20
Char: 1
Code: 0
URI: http://example.com/index.php

bsbarker

9:02 am on Mar 3, 2010 (gmt 0)

10+ Year Member



Haha, I guess I should tell you that Line 20 is:
theServerTime = document.getElementById('servertime').value;

in the JavaScript.

Fotiman

1:51 pm on Mar 3, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



If this is line 20, then the rest of your document hasn't loaded yet. Therefore, document.getElementById('servertime') is going to return null. Try moving your script to the end of your document (just before the closing </body> tag). Alternatively, you could try calling this when the onload event fires.

bsbarker

5:48 am on Mar 4, 2010 (gmt 0)

10+ Year Member



Thanks for the suggestion, Fotiman. Unfortunately I got the same error on the new line number when I moved my script to directly above the </body> tag.

However, before moving it, the rest of the page content below the script did display in the browser. So it does seem to be loading the rest of the document, unless I misunderstand your meaning.

Fotiman

3:13 pm on Mar 4, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What that error means is that it can't find the element on the page with id "servertime". If you view the source of the page, are you able to find an element with id "servertime"?

bsbarker

4:47 pm on Mar 4, 2010 (gmt 0)

10+ Year Member



Thanks for the explanation on the error, that's helpful. The source page is not showing that element. It is still showing the
<!--#include virtual="includes/servertime.cgi"--> line, which after some reading last night I believe should be replaced with the contents of my .cgi file and it sounds like that's what you're referring to.

Could this be caused by my document being named index.php? If so, is there a way to make this work in a .php doc?

Fotiman

5:33 pm on Mar 4, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, the syntax for server side includes is different for PHP. Replace this:
<!--#include virtual="includes/servertime.cgi"-->
with this:
<?php include("includes/servertime.cgi") ?>

For more in PHP includes:
[php.net...]

bsbarker

5:32 am on Mar 5, 2010 (gmt 0)

10+ Year Member



Thank you, that makes sense. It is now accessing my included file but is showing its exact contents in the page's source file.

The contents of my .cgi file are:
#! /usr/bin/perl

print "Content-type:text/html\n\n";
$servertime = time;
print "<input type=hidden name=servertime value='$time'>";

Therefor, the following text is displayed in the browser:
#! /usr/bin/perl print "Content-type:text/html\n\n"; $servertime = time; print "";

Also, when the page loads there is a pop-up message titled "Message from webpage" and the message displayed is the value of the hidden input:
$time

Does the code inside my .cgi file need to be altered as well?

MichaelBluejay

6:28 am on Mar 5, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hi bsbarker, responding to your PM for assistance. I don't know anything about including files via PHP, only with SSI, though my gut feeling is that you've got some kind of server configuration problem that your webhost can fix for you. Hopefully someone more knowledgeable than I will reply. In the meantime, I can try to help you with the regular SSI include: <!--#include virtual="includes/servertime.cgi"-->

To get that to work you need to add this line to your .htaccess file:

AddHandler server-parsed .html

The .htaccess file is at the root level of your website (the same level as the first index.html). It might not already exist, and if not you can just create one. It's a simple text file. The only hitch is that the filename starts with a period, and some file transfer software and operating systems make such files invisible, so one might already be there, but you might not be able to see it. I use Transmit file transfer software on a Mac, which does show invisible files, by the way, as long as "Show invisible files" in the View menu is checked.

Also, for the above code to work, your filename has to end in .html and not .php.

bsbarker

8:27 am on Mar 6, 2010 (gmt 0)

10+ Year Member



Hello and thanks for the reply. I've switched back to your SSI method and changed my index page to .html. The AddHandler line is already in my .htaccess file and the .cgi file seems to be included on my page now because when I view source I see the following code instead of the include virtual line:
<input type=hidden name=servertime value=''>

However, when the page loads I am still getting the aformentioned "Message from webpage" pop-up, only now there is no actual message, just a blank pop-up.

MichaelBluejay

8:49 am on Mar 7, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What do you mean, "pop up message"? Do you mean a dialog box, with an OK and/or Cancel button? If so, you likely have a JavaScript "alert()" command somewhere.

When troubleshooting anything you can't solve in a few minutes, or when getting help on a message board like this one, it's best to start from scratch with the bare minimum you need to reproduce your problem. If your code actually works with the bare minimum, then keep adding bits until it breaks. I think for now you'd want your minimum HTML file to be:

<html>
<!-- #include virtual="includes/servertime.cgi">
<script type=text/javascript>
alert(document.getElementById('servertime').value);
</script>
</html>


...and your Perl file as above, except the last line is:

print "<input type=hidden name=servertime value='$time' id=servertime>";


Adding the id= will help JavaScript find it later.

When loading the page, you should see a dialog box with a number like 1267596000. If you do, then you've successfully gotten Perl to insert the timecode into the page, and JavaScript to read it. You can then keep building your app from there.

bsbarker

8:05 pm on Mar 7, 2010 (gmt 0)

10+ Year Member



That's correct, it's a dialog box with an OK button. Sorry, I realize I can be confusing since I don't know all the terminology yet.

I'm now working with minimum HTML as you suggested. When I included the HTML you gave above I was getting an error, so I tried the HTML you gave me before which is slightly different and the error is gone. The only contents of my document are now:
<html>

<!--#include virtual="includes/servertime.cgi"-->

<script type=text/javascript language="javascript">
theServerTime = document.getElementById('servertime').value;
alert(theServerTime);
</script>

</html>

I also added the id to my .cgi file, so it now reads:
#! /usr/bin/perl

print "Content-type:text/html\n\n";
$servertime = time;
print "<input type=hidden name=servertime value='$time' id=servertime>";

The dialog box still appears on the page load but it is still blank. My assumption is that I'm not successfully getting Perl to insert the timecode into the page because everything else seems to be working now. Can you see what I'm doing wrong?

I've tried to follow the code backwards to understand it and I think I do for the most part, except I don't know what code is actually accessing the server time. Could you expain that part to me? I assume it's something to do with the first two lines in my .cgi file but I'm drawing a blank since I'm not yet familiar with SSI.

MichaelBluejay

8:28 pm on Mar 12, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I found the problem, made one small change, and it works now. But before I give you the solution, let me tell you some other things that are just as useful.

The first is not to get discouraged that your first programming project takes forever just to get something simple working. It's like that for most of us. You might be tempted to abandon the learning because you can't imagine spending so much time on simple projects in the future, but the point is you won't have to. It does get easier.

The second is that right now, every time you hit a wall, you're not sure what to do. But once you get more experience, you'll know how to troubleshoot yourself. Troubleshooting is just as important a skill as programming itself. Once you get a handle on that, development goes much quicker, because you can identify the source of problems yourself.

So now let me explain what the code does. And then I won't just explain the solution, but just as important I'll explain how I *found* it.

Your HTML file is what your visitors see. Previously you were working with only "static" pages with no programming, but now you've taken it to the next level, making "dynamic" pages which run some programming code every time a visitor accesses them. When the user requests your HTML file, then *before* the server sends the page to your user's computer, it runs all the SSI's first, inserting the SSI's into the page, and *then* sending the page to the user's browser.

An SSI can be a simple snippet of HTML. For example, on my sites, I pull in the header of the site (logo + menus) with SSI like so on each page:

<!--#include virtual="/parts/header.html"-->

The "header.html" file contains something like:

<table border=0 cellpadding=5 cellspacing=0><tr>
<td><a href=/><img src=/parts/logo.jpg></a></td>
<td><a href=/>Home</a></td>
<td><a href=/products/>Products</a></td>
<td><a href=/about.html>About Us</a></td>
</tr></table>


After the server has inserted all the includes into the page, *then* it sends it to the user's browser.

In your case, the SSI isn't a plain HTML file, it's a program, so the server runs the Perl program and then inserts the *output* of that program into your HTML file.

Your Perl program is supposed to output this line, which should get inserted into your page:

<input type=hidden name=servertime value='1268423838' id=servertime>

So here's your HTML file as it exists on the server, before the server inserts the includes:

<html>

<!--#include virtual="includes/servertime.cgi"-->

<script type=text/javascript language="javascript">
theServerTime = document.getElementById('servertime').value;
alert(theServerTime);
</script>

</html>


And here it is *after* the SSI has been run. This is what's sent to the user's browser:

<html>

<input type=hidden name=servertime value='1268423838' id=servertime>

<script type=text/javascript language="javascript">
theServerTime = document.getElementById('servertime').value;
alert(theServerTime);
</script>

</html>



See how the SSI line has been replaced with the output of the Perl script?

Okay, so now let's look at what the Perl file is doing, line by line.

#! /usr/bin/perl -- This is just the standard first line that starts any Perl script.
print "Content-type:text/html\n\n" -- You have to put this line in your script before the first time you print anything to a web page. After that, your script can print normally, as many times as it wants.
$servertime = time; -- Perl variables are marked with the $ sign. For example, $weight=165, $age=31, $population=300000000. So you're storing the current time into the variable called $servertime. In Perl, the word "time" is special and holds the current time, which is how we can store the time into our variable.
print "<input type=hidden name=servertime value='$servertime' id=servertime>"; -- Finally, here's the output of our script. This is what we want to get inserted into the HTML file. Note that we're putting that $servertime variable that we loaded, into the output.


And now let's breakdown the HTML and JavaScript in the HTML file.

<input type=hidden name=servertime value='1268423838' id=servertime> -- The "name=servertime" isn't needed in this case. We could remove it with no problems. The "name=#*$!" bit is for if you're submitting a form to an external program to process it. We're not doing that here.

The "value='1268423838'" is the whole point of our program. This is the data that our Perl program generated for us.

The "id=servertime" tags our data so we know how to access it. JavaScript accesses data by ID, so we give our data an ID so we can tell JavaScript how to find it. That's what we're doing with the line theServerTime = document.getElementById('servertime').value;.

Okay, here's how I found the problem:

I copied the code to files on my server and ran it, and I had the same problem as you, an empty dialog box. So then I chose "View Source" in my browser, to see the HTML of the page. Here's what I saw:

<html>

<input type=hidden name=servertime value='' id=servertime>

<script type=text/javascript language="javascript">
theServerTime = document.getElementById('servertime').value;
alert(theServerTime);
</script>

</html>


That told me that the Perl script was writing out the <input...> line, but that it wasn't putting the time into the value='' place. So the problem had to be with the Perl file. So I opened the Perl file, and I saw that we called our variable $servertime, but what we told the script to output was $time. I changed $time to $servertime and that fixed it.

bsbarker

8:16 pm on Mar 13, 2010 (gmt 0)

10+ Year Member



Wow, that's an excellent explanation and it was very helpful. Thanks for taking the time to help me understand it! Both the "how it works" and the troubleshooting.

The encouragement is also much appreciated. I must admit that this project has been a bit frustrating without the knowledge to do it myself. But your help is definitely cutting down that frustration and I'll just use the small bit that's left over to motivate myself. One thing's for sure, this is something I would very much like to learn and complete, so abandonment is not an option for me. :)

And the fix worked! Now the dialogue box shows a numerical value like your example. Excellent! I also went ahead and removed the "name=servertime" part.

Is the next step to creat a visible countdown timer? I assume I'll want to get rid of the dialoge box as well now that we know the server time is being pulled in. Do I want to do that now?

In interest of saving your scrolling finger, here is the list of timer functions from my first post:
What I need is a timer script that:

1. Counts down from what ever time I specify in hh:mm:ss.

2. Stays in sync with the seconds on the server clock.

3. At the click of one button by the user:
a) Advance the timer UP to the next ten-second mark.
b) Add 1 point to a <div> that displays the number of clicks for that button.
c) As that <div> reaches certain various numbers of my choosing, change the contents (the prize) displayed in a second <div>.
d) Display (in a third <div> ) the username of the user who most recently clicked the button.

4. Replaces the timer with the words "two" "one" when the countdown reaches 2, 1.

5. Checks the server for last-second button clicks when the countdown reaches 0, and:
a) Deactivates the button during this check.
b) Replaces the timer with the word "verifying" during this check.

6. If no last-second clicks are found:
a) Replace the timer with the words "game over".
b) The button remains deactivated.
c) Redirect the winner (the last user to click the button before 0) to another page to claim their prize.

7. Can accomodate as many separate and unique timer/button/<div> setups as I want on a single page.

MichaelBluejay

10:23 am on Mar 14, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, your next step is to create a visible countdown timer. The alert() command is really helpful for troubleshooting, to check that the value of a variable is really what you think it's supposed to be. But now that we know the value is good, yes, we now use that value elsewhere.

Here's an example of how to get the value onto the page. Somewhere in your HTML, put:

<div id=showTimeHere></div>

And replace the alert() line of your JavaScript with:

document.getElementById('showTimeHere').innerHTML = theServerTime;

That will put the time on the page.

Your next step after that will be converting the time to the hh:mm:ss format. Google "JavaScript time" and you'll find a load of help on that.

Your 1-7 is all extremely do-able. However, I'm afraid I'm going to be pretty busy and probably won't be able to help here again. Good luck!

bsbarker

9:28 pm on Mar 14, 2010 (gmt 0)

10+ Year Member



Thanks for the time and help you've given me, MichaelBluejay. You've been very helpful. Best of luck to you!

Is anyone able to help me finish up this last step to get the servertime to display on my page?

I'm using the following code to get the servertime to display in the <div>:
<html>

<!--#include virtual="includes/servertime.cgi"-->

<script type=text/javascript language="javascript">
theServerTime = document.getElementById('servertime').value;
document.getElementById('showTimeHere').innerHTML = theServerTime;
</script>

<div id="showTimeHere"></div>

</html>

But the line document.getElementById('showTimeHere').innerHTML = theServerTime; results in the following error:
Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2)
Timestamp: Sun, 14 Mar 2010 21:22:55 UTC


Message: 'document.getElementById(...)' is null or not an object
Line: 7
Char: 1
Code: 0

Can anyone see what I did wrong here?

Fotiman

4:20 pm on Mar 15, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You put the document.getElementById('showTimeHere') before the <div id="showTimeHere"></div>, therefore, it is not defined yet. Move the script to appear below the showTimeHere div.

Side note: Your opening script tag looks like this:
<script type=text/javascript language="javascript">
It should look like this:
<script type="text/javascript">
Quote the attribute value, and get rid of the language attribute (it's invalid and doesn't do anything).

bsbarker

12:50 am on Mar 16, 2010 (gmt 0)

10+ Year Member



Perfect, it's working. Thanks for your help, Fotiman.

For anyone looking for help with this in the future, here is what I ended up with to get the servertime to display on my page:

I created a file called "servertime.cgi" in a folder called "includes". The file contains the following:
#! /usr/bin/perl

print "Content-type:text/html\n\n";
$servertime = time;
print "<input type=hidden value='$servertime' id=servertime>";

and I place the following in my HTML <body>:
<html>

<div id="showTimeHere">Server Time</div>

<!--#include virtual="includes/servertime.cgi"-->

<script type="text/javascript">
var theServerTime = document.getElementById('servertime').value;
document.getElementById('showTimeHere').innerHTML = theServerTime;
</script>

</html>

Thanks again to MichaelBluejay and Fotiman for the help.