Jump to content

Javascript for loop keepings on looping with errors.


Go to solution Solved by imgrooot,

Recommended Posts

This is the code from my previous topic. It was for getting 3 countdown counters to work on the same page.  It does that.  But I didn't notice this up until now. 

It gives me this error and it keeps counting up the errors in firebug.

TypeError: document.getElementById(...) is null

This is the code. Can you tell me what's wrong with it?

<script>
$( document ).ready(function() {

    //Create object with the list of due dates
    //The 'name' will correspond to the field ID to populate the results
    var dueDates = {
        'date1':'<?php echo $global_payment_due_1; ?>',
        'date2':'<?php echo $global_payment_due_2; ?>',
        'date3':'<?php echo $global_payment_due_3; ?>'
    };

    var timer = setInterval(function() {
        //Instantiate variables
        var dueDate, distance, days, hours, minutes, seconds, output;
        //Set flag to repeat function
        var repeat = false;
        // Get todays date and time
        var now = new Date().getTime();
        //Iterate through the due dates
        for (var dueDateId in dueDates) {
            //Get the due date for this record
            dueDate = new Date(dueDates[dueDateId]);
            // Find the distance between now an the due date
            distance = dueDate - now;
            // Time calculations for days, hours, minutes and seconds
            days    = Math.floor(distance  / (1000 * 60 * 60 * 24));
            hours   = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            seconds = Math.floor((distance % (1000 * 60)) / 1000);
            //Determine the output and populate the corresponding field
            output = "OVERDUE";
            if (distance > 0)
            {
                output = days + "d " + hours + "h " + minutes + "m " + seconds + "s";
                repeat = true; //If any record is not expired, set flag to repeat
            }
            document.getElementById(dueDateId).innerHTML = output;
            //If flag to repeat is false, clear event
            if(!repeat)
            {
                clearInterval(timer);
            }
        }
    }, 1000);
});
</script>

  • Solution

Alright so I've managed to solve the issue. I'm not sure if this is the correct way but it works.

 

The issue was that if any one of those 3 dates were empty, then I would receiving the looping errors. All 3 dates have to be active.  Since I am retrieving the dates from the database, I simply did an if else to check if each date was empty or not.

 

Here's the updated code.

<script>
$( document ).ready(function() {

    //Create object with the list of due dates
    //The 'name' will correspond to the field ID to populate the results
    var dueDates = {
      <?php if($global_payment_due_1 == '0000-00-00 00:00:00') {} else { ?>
        'date1':'<?php echo $global_payment_due_1; ?>',
      <?php } ?>
      <?php if($global_payment_due_2 == '0000-00-00 00:00:00') {} else { ?>
        'date2':'<?php echo $global_payment_due_2; ?>',
      <?php } ?>
      <?php if($global_payment_due_3 == '0000-00-00 00:00:00') {} else { ?>
        'date3':'<?php echo $global_payment_due_3; ?>',
      <?php } ?>
    };

    var timer = setInterval(function() {
        //Instantiate variables
        var dueDate, distance, days, hours, minutes, seconds, output;
        //Set flag to repeat function
        var repeat = false;
        // Get todays date and time
        var now = new Date().getTime();
        //Iterate through the due dates
        for (var dueDateId in dueDates) {
            //Get the due date for this record
            dueDate = new Date(dueDates[dueDateId]);
            // Find the distance between now an the due date
            distance = dueDate - now;
            // Time calculations for days, hours, minutes and seconds
            days    = Math.floor(distance  / (1000 * 60 * 60 * 24));
            hours   = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            seconds = Math.floor((distance % (1000 * 60)) / 1000);
            //Determine the output and populate the corresponding field
            output = "OVERDUE";
            if (distance > 0)
            {
                output = days + "d " + hours + "h " + minutes + "m " + seconds + "s";
                repeat = true; //If any record is not expired, set flag to repeat
            }
            document.getElementById(dueDateId).innerHTML = output;
            //If flag to repeat is false, clear event
            if(!repeat) {
                clearInterval(timer);
            }
        }
    }, 1000);
});
</script>

Having an empty if() condition block is bad form. Besides, if you are pulling the data from the database, why don't you build the whole array dynamically? The fact that the names of your variables are global_payment_due_1, global_payment_due_2, global_payment_due_3 could be an indication of a poor database schema.

 

Are there always going to be three (and exactly three) events on the page or could it vary? This is really nothing more than a JSON array, so there isn't even any need to have all those if/else statements at all. Just query the data from the database in an appropriate matter and output the results as a JSON string. Can you show the code to retrieve the data and create those variables?

Having an empty if() condition block is bad form. Besides, if you are pulling the data from the database, why don't you build the whole array dynamically? The fact that the names of your variables are global_payment_due_1, global_payment_due_2, global_payment_due_3 could be an indication of a poor database schema.

 

Are there always going to be three (and exactly three) events on the page or could it vary? This is really nothing more than a JSON array, so there isn't even any need to have all those if/else statements at all. Just query the data from the database in an appropriate matter and output the results as a JSON string. Can you show the code to retrieve the data and create those variables?

 

Yes there are always going to be exactly three events on the page. It's just that starting out, the last 2 events will be hidden until the payment from the first event is paid. I can do it with empty if condition or simply hide them with css if they are not active.

 

Please show me your example of how you would do this properly.

 

This is how I am currently retrieving the data and creating the variables.

$findUser = $db->prepare("SELECT users.*, images.*, matrix.* FROM users
LEFT JOIN matrix ON users.user_id = matrix.user_id
LEFT JOIN images ON users.user_id = images.user_id
WHERE users.user_id = :user_id AND users.active = :active");
$findUser->bindParam(':user_id', $session_user_id);
$findUser->bindValue(':active', 1);
$findUser->execute();
$resultFindUser = $findUser->fetchAll(PDO::FETCH_ASSOC);
if(count($resultFindUser) > 0) {
   foreach($resultFindUser as $row) {

    $global_payment_due_1         = trim($row['d_1_payment_due']);
    $global_payment_approved_1    = trim($row['d_1_payment_approved']);

    $global_payment_due_2         = trim($row['d_2_payment_due']);
    $global_payment_approved_2    = trim($row['d_2_payment_approved']);

    $global_payment_due_3         = trim($row['d_3_payment_due']);
    $global_payment_approved_3    = trim($row['d_3_payment_approved']);
    
   }
}
Edited by imgrooot
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.