Solved

Jquery Random Number Counter

Posted on 2014-04-07
15
901 Views
Last Modified: 2014-04-09
@julianH helped me previously with this script and was awarded 500 points for an excellent job, not sure if I need to mention that here or not?

Counter 4 and counter 6 are suppose to stay in sync with counter 1 however they fail to do so if the starting value is 0, (they seem to work when the starting value is 1 and up) please help.

Regardless of if the starting value is 0 through infinity the counters linked to counter 1 must stay in sync.

Please note there is a slight delay in counters 1, 4 and 6 to allow a different JavaScript to generate the starting value to base the count on.

<!doctype html>
<html>
<head>
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'></script>
</head>
<body>

<div style="display: inline;" id="WFItem2402702">
<span class="wf-counter" style="display:  block !important;">
<span name="https://app.getresponse.com/display_subscribers_count.js?campaign_name=eds2014&var=0" class="wf-counterq" id="counter_1">-</span>
</span>
</div>
<script type="text/javascript" src="http://app.getresponse.com/view_webform.js?wid=2402702&mg_param1=1&u=B49N"></script>

<span id="counter_2">1,627</span>
<br>
<span id="counter_3">1</span>

<div style="display: inline;" id="WFItem2402702">
<span class="wf-counter" style="display:  block !important;">
<span name="https://app.getresponse.com/display_subscribers_count.js?campaign_name=eds2014&var=0" class="wf-counterq" id="counter_4">-</span>
</span>
</div>
<script type="text/javascript" src="http://app.getresponse.com/view_webform.js?wid=2402702&mg_param1=1&u=B49N"></script>

<span id="counter_5">48,000</span>

<div style="display: inline;" id="WFItem2402702">
<span class="wf-counter" style="display:  block !important;">
<span name="https://app.getresponse.com/display_subscribers_count.js?campaign_name=eds2014&var=0" class="wf-counterq" id="counter_6">-</span>
</span>
</div>
<script type="text/javascript" src="http://app.getresponse.com/view_webform.js?wid=2402702&mg_param1=1&u=B49N"></script>

<script type="text/javascript">
var values1 = [0, 100, 200, 300, 400, 500, 234];
var counter1 = 0, counter2 = 0, counter3 = 0, counter4 = 0, counter5 = 0, counter6 = 0;
var count = 0;
$(function() {
    // We drop the delay - the counter not being set will be handled in the 
    // functions getCounterValue and UpdateCount
    counter1 = getCounterValue('#counter_1');
    counter2 = getCounterValue('#counter_2');
    counter3 = getCounterValue('#counter_3');
    counter4 = getCounterValue('#counter_4');
    counter5 = getCounterValue('#counter_5');
    counter6 = getCounterValue('#counter_6');
    setInterval("UpdateCount()", 1000);
});

// Function to get a value from a counter if it exists or to return 0 
// if it does not
function getCounterValue(id)
{
    // use regular expression  replace to clean number of non-numeric chars
    val = parseInt($(id).html().replace(/[^0-9\.]+/g, ''));
    // if is NaN (not a number) then set to 0.
    if (isNaN(val)) {
        val = 0;
    }
    return val;
}
// Generic function for handling counters.
function UpdateCount()
{
    // The count variable is incremented everytime this function is run
    // i.e. every second. We use it to determine when to fire updates
    // on our various counters. This way we can do updates in a single 
    // function irrespective of how many counters we have

    count++;

    // what we are doing here is only firing the update if the 
    // count is a multiple of 2 (every 2 seconds)
    // in addition we are only firing if counter1 > 0 so only after
    // the counter1 delay has fired.

    if (counter1 == 0 ) {
        counter1 = getCounterValue('#counter_1');
    }

    if (counter4 == 0 ) {
        counter4 = getCounterValue('#counter_4');
    }

    if (counter6 == 0 ) {
        counter6 = getCounterValue('#counter_6');
    }

    if (count % 2 == 0) {
        // ADD RANDOM NUMBER TO counter1 (between 0 and 11)
        counter1 += Math.floor(Math.random() * 11);
        var s = addCommas(counter1);
        if (counter1 > 0) {
           $('#counter_1').html(s);
        }
        if (counter4 > 0) {
           $('#counter_4').html(s);
        }
        if (counter6 > 0) {
           $('#counter_6').html(s);
        }
    }

    // No really necessary but shown for completeness.
    if (counter2 == 0 ) {
        counter2 = getCounterValue('#counter_2');
    }
    // here we are only firing every 5 seconds.
    if (count % 5 == 0) {
        // ADD RANDOM NUMBER TO counter2 (between 0 and 22)
        counter2 += Math.floor(Math.random() * 11);
        var s = addCommas(counter2);
        $('#counter_2').html(s);
    }

    // No really necessary but shown for completeness.
    if (counter3 == 0 ) {
        counter3 = getCounterValue('#counter_3');
    }
    // here we are only firing every 60 seconds.
    if (count % 60 == 0) {
        // ADD RANDOM NUMBER TO counter3 (between 1 and 2)
        counter3 += 1 + Math.floor(Math.random() * 2);
        var s = addCommas(counter3);
        $('#counter_3').html(s);
    }

    // No really necessary but shown for completeness.
    if (counter5 == 0 ) {
        counter5 = getCounterValue('#counter_5');
    }
    // here we are only firing every 3 seconds.
    if (count % 3 == 0) {
        // GET A RANDOM VALUE FROM THE values ARRAY and add to counter5
        counter5 += values1[Math.floor(Math.random() * values1.length)];
        var s =  '$' + addCommas(counter5);
        $('#counter_5').html(s);
    }
}

function addCommas(nStr) {
    nStr += '';
    var x = nStr.split('.');
    var x1 = x[0];
    var x2 = x.length > 1 ? '.' + x[1] : '';
    var rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
        x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + x2;
}
</script>

</body>
</html>

Open in new window

0
Comment
Question by:Richard Morris
  • 7
  • 7
15 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39985216
How are counter 4 and 6 meant to be initialised? Currently they are set to '-' but never seem to be updated.

With counter_1 your javascript code initialises the counter - which is why we have the test for > 0 in the update - we are waiting for the counter to be initialised before updating it.

Somewhere you need to have something initialise counter_4 and counter_6 so they can start synching - otherwise they will always evaluate to 0 and the update code will never update them.
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 39985577
Please also be advised that JS cannot handle timers using timeout well. Any processing on the page or on the PC may delay the event. To have a better timer, use the Date object and have it check that the time is what it thinks it is rather than have a one second tick
0
 

Author Comment

by:Richard Morris
ID: 39985939
@julianH

Counter 4 and 6 and any other counter linked to counter 1 should be initialized the same way as counter 1 is my guess.

The dash is just a placeholder so that the other JavaScript can generate a starting value which is currently 0 at the moment.

Yes, I need a very simple way to initialize counter 4 and 6 plus the ability to initialize more counters too as I continue to add more and more counters to this script over time.
0
 

Author Comment

by:Richard Morris
ID: 39985965
@mplungjan

This JavaScript doesn’t use a timeout does it?

Yes, these counters need to handle delays in processing my pages which is very often the case when third party apps get stuck loading such as Facebook, etc.

Okay on using the Date object to have it check that the time is what it thinks it is rather than have a one second tick but not sure how to go about that?

Sometimes my page loads in a couple of seconds, sometimes 10 to 30 seconds if something hangs, I certainly do not want my counters to fail if any of my pages get stuck loading.

Please help.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39985986
There are two types of counters we could be dealing with.

One that is counting seconds acurate to a clock.

One that is just counting - for instance a gaming site that wants to clock a jackpot - could have a counter that has nothing to do with the time.

But before we get sidetracked - the question was about why counter 4 and 6 where not running. So lets solve that and then deal with the accuracy of the timer.

Can you answer my last post - which was what process is meant to initialise counter 4 and 6?
0
 

Author Comment

by:Richard Morris
ID: 39986060
@julianH

Counting seconds accurate to a clock sounds good to me.

The counter already seems very accurate, the second problem is the counter might fail to run if my page hangs (doesn't load quickly), that is a big concern now too because I don’t want my counters to fail on account of my webpage loading too slowly and yes my webpage often loads very slowly. :(

As I already said, I think counter 1 is supposed to initialize counter 4 and 6 because they are supposed to be the same counter but different IDs because you told me in a different thread that you cannot use the same ID more than once.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39986614
If counter4 and 6 are copies of counter1 then all you need to do is change this
   if (count % 2 == 0) {
        // ADD RANDOM NUMBER TO counter1 (between 0 and 11)
        counter1 += Math.floor(Math.random() * 11);
        var s = addCommas(counter1);
        if (counter1 > 0) {
           $('#counter_1').html(s);
        }
        if (counter4 > 0) {
           $('#counter_4').html(s);
        }
        if (counter6 > 0) {
           $('#counter_6').html(s);
        }
    }

Open in new window

To this
   if (count % 2 == 0) {
        // ADD RANDOM NUMBER TO counter1 (between 0 and 11)
        counter1 += Math.floor(Math.random() * 11);
        var s = addCommas(counter1);
        if (counter1 > 0) {
           $('#counter_1').html(s);
           $('#counter_4').html(s);
           $('#counter_6').html(s);
        }
    }

Open in new window

See if that solves that problem and we can deal with the timing issue separately.

And to confirm - ID's must be unique.
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:Richard Morris
ID: 39986678
@julianH

Problem is now solved and I must admit that you really make this coding stuff look easy when you piece it all together line by line even though I could not have figured it out without you, amazing work my friend.

You are correct that I really need the counters to still function if there is a lengthy lag such as 30 seconds at my website. Please note my site normally loads in about 2 seconds but sometimes it takes up to 30 seconds give or take because sometimes third-party scripts freeze up my website temporarily during load up because I use AddThis, Disqus, various Facebook plugins and other miscellaneous plugins that often make my website load slowly.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39986843
Not sure I see how the loading delay will affect anything. The purpose of the if > 0 checks is precisely to enable counters only when they are ready to go.

Maybe I missted a step though ...
0
 

Author Comment

by:Richard Morris
ID: 39986883
@julianH

We will need to create an artificial load delay in order to test the script to see if it fails after a load delay.

Unfortunately I do not know how to make a load delay in order to do such a thorough test?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39986981
What you can do is add the following line of code
<script src="delay.php"></script>

Open in new window

Either in your <head> or just before your </body> tag.

delay.php would then be
<?php
$delay = 15; // Time in seconds to delay
sleep($delay);
?>

Open in new window

Requires PHP the server where the delay.php script is located - but this can be anywhere on the internet - just update your src attribute to where it is located.
0
 

Author Comment

by:Richard Morris
ID: 39987108
@julianH

This is not the type of delay I am referring to because all this does is hold the entire page from loading and then everything loads perfectly normal thereafter. I would call this a hold rather than a delay which are two different things.

The type of delay I’m talking about is when the page is partly loaded while several other plugins are hanging causing other scripts to hang too such as the script that generates the base number for the counter, I need to recreate that type of a scenario, the type of scenario that might happen when you have dozens of scripts hosted at dozens of different servers and a few of the servers are working very slowly making your page hang so that the base number loads about 30 seconds late after the rest of the page is already loaded, that is the type of scenario I want to test for because that actually does happen to me sometimes so it really scares me a lot. Unfortunately this is not a problem I can recreate whenever I want to look at it because it is a problem that can only be anticipated unless of course you know of away to recreate the problem artificially for testing purposes? Example, load the entire page but stall the script that generates the base number by about 30 seconds in order to see if the counter script still works after such a long delay, now that would be a really good and reassuring test.
0
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 500 total points
ID: 39987271
The solution I posted earlier will do that - simulates a script taking a long time to load. Same as if you were pulling a javascript file and it was taking a long time to arrive.

Having said that - the whole point of the tests for > 0 was to ensure that the counters are set before doing anyting with them. The script should be fairly bulletproof in that regard.
0
 

Author Closing Comment

by:Richard Morris
ID: 39989388
@julianH

Glad the test is now complete based upon your expertise.

Yes, this script should be bulletproof indeed.

Thank you for all of your support and expert answers.

You are perhaps the smartest man I have ever known.
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 39989571
Thank you again for the compliments - not sure I can live up to them - but appreciated.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
This article discusses how to create an extensible mechanism for linked drop downs.
The viewer will learn how to dynamically set the form action using jQuery.
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)

744 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now