?
Solved

Running several javascripts on a single ASP.NET page

Posted on 2009-02-18
13
Medium Priority
?
261 Views
Last Modified: 2012-05-06
Hello,

I have a javascript counter on my ASP.NET page that counts time down to zero. The result is displayed in one of the labels on the page.

I need to have several counters on my page - not a definite figure, can be quite a lot - up to 40-50 counters. But when I try to use the same code for my other label, the first script stopped and was reset.
Javascript code:
		// time = time in seconds to count down;
		// output = output control
		function CountDown( time, output )
		{
			// get hours, minutes, and seconds parts
			hours = Math.floor( time / 3600 )
			minutes = Math.floor(( time - hours * 3600 ) / 60 )
			seconds = time - hours * 3600 - minutes * 60
			
			// pad zeros if necessary
			seconds = AddZeros( seconds )
			minutes = AddZeros( minutes )
			
			// show the result
			document.getElementById( output ).innerHTML = hours + ":" + minutes + ":" + seconds
			
			// decrement the counter
			if( time > 0 )
				setTimeout( 'CountDown( ' + --time + ', "' + output + '")', 1000)
			else
				parent.history.go( 0 )
		}
 
** running the first counter: **
	protected void btnStart_Click( object sender, EventArgs e )
	{
		string time = lblTime1.Text;
		string hours = time.Substring( 0, time.IndexOf( ":" ) );
		string minutes = time.Substring( time.IndexOf( ":" ) + 1, 2 );
		string seconds = time.Substring( time.LastIndexOf( ":" ) + 1, 2 );
		int totalSeconds = Convert.ToInt32( hours ) * 3600 + 
			Convert.ToInt32( minutes ) * 60 + Convert.ToInt32( seconds );
		//Response.Write( hours + ":" + minutes + ":" + seconds );
 
		lblCompleted1.Visible = lblCountDown1.Visible = true;
 
		Page.RegisterStartupScript( "countdown1", "<script language=JavaScript>CountDown(" +
			totalSeconds + ", 'lblCountDown1' );</script>" );
	}
 
** running the second counter: **
	protected void btnStart2_Click( object sender, EventArgs e )
	{
		string time = lblTime2.Text;
		string hours = time.Substring( 0, time.IndexOf( ":" ) );
		string minutes = time.Substring( time.IndexOf( ":" ) + 1, 2 );
		string seconds = time.Substring( time.LastIndexOf( ":" ) + 1, 2 );
		int totalSeconds = Convert.ToInt32( hours ) * 3600 +
			Convert.ToInt32( minutes ) * 60 + Convert.ToInt32( seconds );
		//Response.Write( hours + ":" + minutes + ":" + seconds );
 
		lblCompleted2.Visible = lblCountDown2.Visible = true;
 
		Page.RegisterStartupScript( "countdown2", "<script language=JavaScript>CountDown(" +
			totalSeconds + ", 'lblCountDown2' );</script>" );
 
	}

Open in new window

0
Comment
Question by:Yurich
  • 7
  • 6
13 Comments
 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23676738
Here is a sample with multiple countdowns running at once:

http://www.javascriptjedi.com/countdown/
0
 
LVL 21

Author Comment

by:Yurich
ID: 23676926
thank you,
I'll have to see how I can apply this script to my script as I can't use that one as is.
0
 
LVL 21

Author Comment

by:Yurich
ID: 23687995
I can't make it working on my .NET page even for a single counter. I'm copying two functions from the page inside my <script> tags, and adding this function there as well:

            function AfterLoad()
            {
                  CreateCountdown("Time until July 4, 2121", "07-04-2121", document.body, 'myTimer');
            }

Then I add it to the body onload event:

<body onload = "AfterLoad()">

And it's not working, saying again that it wants an object.

As far as I understand from the script, I don't need to create any objects (labels, etc.) to load the countdown. The script is supposed to create a "div" element on its own and then populate it. Apparently, I'm doing something wrong... Any idea?

Thanks,
Yurich
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23688024
Are you using a master page?  If so the control ID would be something like ctl00_ContentPlaceHolder1_myTimer
0
 
LVL 21

Author Comment

by:Yurich
ID: 23688064
no, just a page. I don't really see where this script is using any control ID:

       CreateCountdown("Time until July 4, 2121", "07-04-2121", document.body, 'myTimer');

"Time until..." = title
"07-..." = date
document.body = where you want to attach/place a new element
'myTimer' = just a tag for the future dynamically created element

I have tried to pass a control id in fact instead of document.body (using document.getElementById), but it didn't work either...
0
 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23688116
Look at the function declaration.

function CreateCountdown(iTitle, iCountdownDate, iAttachToElement, iCountdownNodeId) {
    var nodeId = "countdownDiv";
    if (iCountdownNodeId &&
        typeof iCountdownNodeId == "string" && iCountdownNodeId.length > 0) {
        nodeId = iCountdownNodeId;
    }

It says right there to use a div with the ID of "countdownDiv", UNLESS iCountdownNodeId is specified, if so use that ID.


<div ID="MyLittleTimer"></div>

CreateCountdown("Time until July 4, 2121", "07-04-2121", document.body, 'MyLittleTimer');
0
 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23688196
Actually, after looking at the source to the timers page, I found this...  You have to specify the "container" for the 3rd option, document.getElementById('timers')

CreateCountdown("3 days from now", sDate1, document.getElementById('timers'), 'myTimer');

<div id="timers"></div>

iCountdownNodeId (optional): the Id you want the elements to have.
            
So, it would result in this:
<div id="timers">
      <div id="myTimer">
            <div id="myTimer-title">[ iTitle gets put here]</div>
            <div id="myTimer-timer">[ timer data is updated here ]</div>
      </div>
</div>
0
 
LVL 21

Author Comment

by:Yurich
ID: 23688247
have you tried to run it yourself?

I have and still doesn't work. I'm attaching my page as I have it. If you have tried running it and it did work for you, you may probably attach your page here as well. The source code is empty.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="BigJSCountDown.aspx.cs" Inherits="BigJSCountDown" %>
 
<!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 runat="server">
    <title>Untitled Page</title>
    <script type = "text/javascript">
function CreateCountdown(iTitle, iCountdownDate, iAttachToElement, iCountdownNodeId) {
    var nodeId = "countdownDiv";
    if (iCountdownNodeId &&
        typeof iCountdownNodeId == "string" && iCountdownNodeId.length > 0) {
        nodeId = iCountdownNodeId;
    }
    var rightNow = new Date;
    var endDate = DateStringToDateObject(iCountdownDate);
    if (rightNow.getTime() >= endDate.getTime()) {
        return false;
    }
    if (iAttachToElement) {
        var countdownDiv = document.createElement("div");
        countdownDiv.id = nodeId;
        countdownDiv.className = "countdownContainer";
        countdownDiv.endDateMilliseconds = endDate.getTime();
        var titleDiv = document.createElement("div");
        titleDiv.id = nodeId + "-title";
        titleDiv.className = "countdownTitle";
        titleDiv.innerHTML = iTitle;
        countdownDiv.appendChild(titleDiv);
        var timerDiv = document.createElement("div");
        timerDiv.id = nodeId + "-timer";
        timerDiv.className = "countdownTimer";
        countdownDiv.appendChild(timerDiv);
        countdownDiv.interval = setInterval("UpdateTimer(document.getElementById(\"" + nodeId + "\"));", 1000);
        iAttachToElement.appendChild(countdownDiv);
    }
}    
 
function UpdateTimer(iCountdownNode) {
    var now = new Date;
    if (iCountdownNode &&
        ((iCountdownNode.endDateMilliseconds - now.getTime()) > 0)) {
        var timerNodeId = iCountdownNode.id.split("-")[0];
        var timerDiv = document.getElementById(timerNodeId + "-timer");
        var timeStr = "";
        var diff = iCountdownNode.endDateMilliseconds - now.getTime();
        var msPerSec = 1000;
        var msPerMin = 60 * msPerSec;
        var msPerHour = 60 * msPerMin;
        var msPerDay = 24 * msPerHour;
        var days = Math.floor(diff / msPerDay);
        var left = diff % msPerDay;
        var hours = Math.floor(left / msPerHour);
        left = left % msPerHour;
        var min = Math.floor(left / msPerMin);
        left = left % msPerMin;
        var sec = Math.floor(left / msPerSec);
        timeStr = days + " days " + hours + " hours " + min + " minutes " + sec + " seconds left";
        timerDiv.innerHTML = timeStr;
    } else {
        clearInterval(iCountdownNode.interval);
        iCountdownNode.parentNode.removeChild(iCountdownNode);
    }
}
 
		function AfterLoad()
		{
			CreateCountdown("3 days from now", "23-02-2009", document.getElementById('timers'), 'myTimer');			
		}
 
    </script>
    
    
    
</head>
<body onload = "AfterLoad();">
    <form id="form1" runat="server">
    <div>
		<div id="timers">
			<div id="myTimer">
				<div id="myTimer-title"></div>
				<div id="myTimer-timer"></div>
			</div>
		</div>    
    </div>
    </form>
</body>
</html>

Open in new window

0
 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23688312
Yes, you are adding way to much in to your code.  Here is what mine looks like.  Note that I am including countdown.js which can be downloaded on the link that I gave you earlier.  Here it is if you need it.

http://www.javascriptjedi.com/countdown/countdown.js

<html>
<head>
    <script src="countdown.js" type="text/javascript"></script>    
    <script type="text/javascript">
        function AfterLoad() {
            CreateCountdown("3 days from now", "2-22-2009", document.getElementById('timers'), "myTimer");
        }
    </script>
    <style type="text/css">
        #myTimer-title { color:Blue; }
        #myTimer-timer { color: Red; }
    </style>
</head>
<body onload="AfterLoad()">
    <form id="form1" runat="server">
       <div id="timers"></div>
    </form>
</body>
</html>

Open in new window

0
 
LVL 21

Author Comment

by:Yurich
ID: 23706151
I did exactly as above and unfortunately it's not working for me. still javascript error saying "object expected"

Even if I get it working, it's not actually what I'm after - I was just trying to get somewhere with this article you gave me. Apparently somehow it does create multiple timers (which I haven't seen), but I can't get it working and I don't really need all this stuff in the file. What I really need is to modify the piece of code attached that when I click any of the buttons, the counter starts for a particular label (the code is attached). I can put the code later in .js file it doesn't really matter at this point.


=================== ASPX file =============================
 
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="DynamicJSCountdown.aspx.cs" Inherits="DynamicCountdown" %>
 
<!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 runat="server">
    <title>Untitled Page</title>
    <link rel = "Stylesheet" type = "text/css" href = "App_Themes/css/StyleSheet.css" />
    <script type = "text/javascript">
		// time = time in seconds to count down;
		// output = output control
		function CountDown( time, output )
		{
			// get hours, minutes, and seconds parts
			hours = Math.floor( time / 3600 )
			minutes = Math.floor(( time - hours * 3600 ) / 60 )
			seconds = time - hours * 3600 - minutes * 60
			
			// pad zeros if necessary
			seconds = AddZeros( seconds )
			minutes = AddZeros( minutes )
			
			// show the result
			document.getElementById( output ).innerHTML = hours + ":" + minutes + ":" + seconds
			
			// decrement the counter
			if( time > 0 )
				setTimeout( 'CountDown( ' + --time + ', "' + output + '")', 1000)
			else
				__doPostBack('btnFinished','');
		}
 
		// pad a zero for the time display
		function AddZeros( i )
		{
			return ( i < 10 ) ? "0" + i : i
		}							
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
		<asp:Label ID="Label1" runat="server" Text="The task #1 will take:"></asp:Label>
		<asp:Label ID="lblTime1" runat="server" Text="0:00:10"></asp:Label><br />
		<asp:Button ID="btnStart1" runat="server" Text="Start Task #1" OnClick="btnStart_Click" /><br />
		<asp:Label ID="lblCompleted1" runat="server" Text="The task #1 will be completed in " Visible="False"></asp:Label>
		<asp:Label ID="lblCountDown1" runat="server" Visible="False"></asp:Label><br />
		<br />
		<asp:Label ID="Label2" runat="server" Text="The task #2 will take:"></asp:Label>
		<asp:Label ID="lblTime2" runat="server" Text="1:34:56"></asp:Label><br />
		<asp:Button ID="btnStart2" runat="server" Text="Start Task #2" OnClick="btnStart2_Click" /><br />
		<asp:Label ID="lblCompleted2" runat="server" Text="The task #1 will be completed in "
			Visible="False"></asp:Label>
		<asp:Label ID="lblCountDown2" runat="server" Visible="False"></asp:Label><br />
		<br />
		<asp:LinkButton ID="btnFinished" runat="server" OnClick="btnFinished_Click" Text="Button" /></div>
    </form>
</body>
</html>
 
============= END OF ASPX file =========================
 
============= CODE BEHIND ==============================
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class DynamicCountdown : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
		//lblTime.Text = "2:35:46";
    }
	protected void btnStart_Click( object sender, EventArgs e )
	{
		string time = lblTime1.Text;
		string hours = time.Substring( 0, time.IndexOf( ":" ) );
		string minutes = time.Substring( time.IndexOf( ":" ) + 1, 2 );
		string seconds = time.Substring( time.LastIndexOf( ":" ) + 1, 2 );
		int totalSeconds = Convert.ToInt32( hours ) * 3600 + 
			Convert.ToInt32( minutes ) * 60 + Convert.ToInt32( seconds );
		//Response.Write( hours + ":" + minutes + ":" + seconds );
 
		lblCompleted1.Visible = lblCountDown1.Visible = true;
 
		Page.RegisterStartupScript( "countdown1", "<script language=JavaScript>CountDown(" +
			totalSeconds + ", 'lblCountDown1' );</script>" );
	}
	protected void btnStart2_Click( object sender, EventArgs e )
	{
		string time = lblTime2.Text;
		string hours = time.Substring( 0, time.IndexOf( ":" ) );
		string minutes = time.Substring( time.IndexOf( ":" ) + 1, 2 );
		string seconds = time.Substring( time.LastIndexOf( ":" ) + 1, 2 );
		int totalSeconds = Convert.ToInt32( hours ) * 3600 +
			Convert.ToInt32( minutes ) * 60 + Convert.ToInt32( seconds );
		//Response.Write( hours + ":" + minutes + ":" + seconds );
 
		lblCompleted2.Visible = lblCountDown2.Visible = true;
 
		Page.RegisterStartupScript( "countdown2", "<script language=JavaScript>CountDown(" +
			totalSeconds + ", 'lblCountDown2' );</script>" );
 
	}
	protected void btnFinished_Click( object sender, EventArgs e )
	{
		Response.Write( "done..." );
	}
}
============= END OF CODE BEHIND ==============================

Open in new window

0
 
LVL 15

Accepted Solution

by:
aibusinesssolutions earned 2000 total points
ID: 23706178
Well you are doing postbacks, which will not work with multiple counters.

Every time you click a button on page, the counters will reset, because they are client side counters.

For example, if I have a javascript counter that says 23 minutes remaining, and I let it count down to 20 minutes remaining, and then click a button on the page, it's going to start back over at 23 because there is nothing tracking that on the server side, it's all client side.
0
 
LVL 15

Expert Comment

by:aibusinesssolutions
ID: 23706184
The only way to do what you are wanting to do would be with ajax, so the entire page never posts back, only a partial post back.

You would have to put your counters in individual update panels, and have the corresponding button as a trigger for that counter.
0
 
LVL 21

Author Comment

by:Yurich
ID: 23706982
OK, thanks, got your point about posting back.
the buttons were not essential, running two counters at the same time was.

So I have achieved it by starting to scripts for two labels in one button click event. Now I just need to figure out the best way of storing the data when one of the timers is up.

But at this point, I got what I wanted. Thank you very much.

Regards,
Mik
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
Article by: DanRollins
This article describes a JavaScript program that creates a maze made of hexagonal cells.  In Part 2 (http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_7850-Hex-Maze-Part-2.html), we'll extend the program by adding a depth-…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

621 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question