Link to home
Start Free TrialLog in
Avatar of Richard Morris
Richard MorrisFlag for Canada

asked on

Jquery Random Number Counter

@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

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

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.
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
Avatar of Richard Morris

ASKER

@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.
@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.
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?
@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.
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.
@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.
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 ...
@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?
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.
@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.
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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.
Thank you again for the compliments - not sure I can live up to them - but appreciated.