Help with number program I am writing

Hello. I’m FAR from finished with my first app and am a total beginner to JavaScript, but I need some help because of these things. First off, some background on the app. It’s not a serious app, it’s meant for me to hone my skills. The premise for the app is that it randomizes blocks of time that you would enter on a hypothetical time card. You would add round numbers (example from 0700 - 0930 which is 2.5 hours)(btw uses 24 hr time). The purpose of this is to take your nice round time and randomly add or subtract a random 0-5 minutes on the end of it. It also tallies your cumulative time from your round numbers, and seperately tallies it for the simulated numbers. My problem is where it is tallying numbers. it doesnt always give the correct answer for the totals.
Here is my JS:

var startTimeEntry = document.querySelector(".startTime");
var endTimeEntry = document.querySelector(".endTime");
var hoursTotal = document.querySelector(".totalHours");
var simStart = document.querySelector(".simStart");
var simEnd = document.querySelector(".simEnd");
var simActual = document.querySelector(".simActual");
var oldStartTime = startTimeEntry.value;
var calc = document.querySelector("#calculate");


calc.addEventListener("click",newStartTime, true);

function newStartTime() {
    var randomStart = Math.random(); 
    if (randomStart < 0.5 && startTimeEntry.value.charAt(2) !== "3"&& startTimeEntry.value.charAt(2) !== "1" && startTimeEntry.value.charAt(2) !== "4" ) {
        //&& startTimeEntry.value.charAt(2) !== "3"
        var randomNum = (Math.random() * -5) -40 ;        
        } 
    else if (randomStart < 0.5 && startTimeEntry.value.charAt(2) == "3") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && startTimeEntry.value.charAt(2) == "1") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && startTimeEntry.value.charAt(2) == "4") {
        var randomNum = (Math.random() * -5)  ;
    }
    else randomNum = Math.random() * 5;
    var roundNum = Math.floor(randomNum)   
    var numberx = parseInt(startTimeEntry.value);
    simStart.value =(roundNum + numberx);   
    if (simStart.value < 1000) {
        simStart.value = "0" + (roundNum + numberx);
        
}
}
calc.addEventListener("click",newEndTime, true);
                      
function newEndTime() {
    var randomStart = Math.random(); 
    if (randomStart < 0.5 && endTimeEntry.value.charAt(2) !== "3" && endTimeEntry.value.charAt(2) !== "1" && endTimeEntry.value.charAt(2) !== "4" ) {
        //&& startTimeEntry.value.charAt(2) !== "3"
        var randomNum = (Math.random() * -5) -40 ;        
        } 
    else if (randomStart < 0.5 && endTimeEntry.value.charAt(2) == "3") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && endTimeEntry.value.charAt(2) == "1") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && endTimeEntry.value.charAt(2) == "4") {
        var randomNum = (Math.random() * -5)  ;
    }
    else randomNum = Math.random() * 5;
    var roundNum = Math.floor(randomNum)   
    var numberx = parseInt(endTimeEntry.value);
    simEnd.value =(roundNum + numberx);   
    if (simEnd.value < 1000) {
        simEnd.value = "0" + (roundNum + numberx);
        
}
}
calc.addEventListener("click",totalHoursF,true);

function totalHoursF() {
    var startingMinutes = (endTimeEntry.value - startTimeEntry.value);
    var hundreds = startingMinutes / 100;
    var noRemainder = Math.floor(hundreds);
    var sixties = noRemainder * 60;
    var remainingMinutes = startingMinutes % 100;
    var totalMinutes = sixties + remainingMinutes;
    hoursTotal.value = totalMinutes / 60;
    
}

calc.addEventListener("click",actualHoursF,false);

function actualHoursF() {
    var startingMinutes = (simEnd.value - simStart.value);
    var hundreds = startingMinutes / 100;
    var noRemainder = Math.floor(hundreds);
    var sixties = noRemainder * 60;
    var remainingMinutes = startingMinutes % 100;
    var totalMinutes = sixties + remainingMinutes;
    simActual.value = totalMinutes / 60;
    
}

and here is the HTML:

<!DOCTYPE html>
<html lang = "en">
<head>
    </head>
    <body>
        <h1>Number Generator   <button id="calculate">Calculate</button></h1>
        <table style = "width 100%">
            <tr>
                <th>Serial Number</th>
                <th>Start Time</th>
                <th>End Time</th>
                <th>Total Hours</th>
                <th>Sim Start</th>
                <th>Sim End</th>
                <th>Sim Actual</th>
            </tr>
            <tr>
                <td><input type="text" class="workOrder" ></td>
                <td><input type="text" class="startTime"></td>
                <td><input type="text" class="endTime"></td>
                <td><input type="text" class="totalHours"></td>
                <td><input type="text" class="simStart"></td>
                <td><input type="text" class="simEnd"></td>
                <td><input type="text" class="simActual"></td>
            </tr>
            <tr>
                <td><input type="text" class="workOrder" ></td>
                <td><input type="text" class="startTime"></td>
                <td><input type="text" class="endTime"></td>
                <td><input type="text" class="totalHours"></td>
                <td><input type="text" class="simStart"></td>
                <td><input type="text" class="simEnd"></td>
                <td><input type="text" class="simActual"></td>
            </tr>
            <tr>

No problem. Here is a sreen shot

No, at this point you jsut enter a start time and an end time, and it will automatically populate the other fields. For some reason it only works on the first row right now I need to look into that as well.

also serial number field doesnt do anything just ignore that i havent written any code for it yet.

Thanks. I’ll be trying to work the bugs out until then. Appreciate all your help!

Hi,
The reason it only work for the first row is because of how class selectors work.

// this will get a node list of all the rows
var startTimeEntry = document.querySelector(".startTime");

// this will only address the value of the first row
startTimeEntry.value

You will need to loop through all the rows and process them one at a time.

Hey I appreciate the good advice. Should I wrap the function in a for loop like this? I might be doing it wrong:
for (var i = 0; i < document.querySelector(".startTime").length; i++) {........}

Also want to add I’ve been experimenting with it. One interesting thing I’ve found concerning the erratic behaviour of the newStartTime function is that when I mess with it and make it so it doesn’t run, no data is entered as a start time for actualHoursF to use for its calculations, it defaults to a value of zero. That by itself is uninteresting, but coupled with the fact that function actualHoursF takes the zero default and the floating point number supplied by newEndTime, and runs its calculations on those two and they are ALWAYS RIGHT!!! Interesting right? Somehow I feel this is relevant.

The code for the HTML has 20 table data rows in real life, but I copied only the first two cause that would be a lot of text!

Ok I’m trying to iterate through the startTimeEntry variable to hit the .startTime class. I may have made a syntatic as well as logic mistakes but here is my code for the function in question so far (what am I doing wrong):

    for (var i = 0; i < startTimeEntry.length; i++) {
    var randomStart = Math.random(); 
    if (randomStart < 0.5 && startTimeEntry[i].value.charAt(2) !== "3"&& startTimeEntry[i].value.charAt(2) !== "1" && startTimeEntry[i].value.charAt(2) !== "4" ) {
        
        var randomNum = (Math.random() * -5) -40 ;        
        } 
    else if (randomStart < 0.5 && startTimeEntry[i].value.charAt(2) == "3") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && startTimeEntry[i].value.charAt(2) == "1") {
        var randomNum = (Math.random() * -5)  ;
    }
    else if (randomStart < 0.5 && startTimeEntry[i].value.charAt(2) == "4") {
        var randomNum = (Math.random() * -5)  ;
    }
    else randomNum = Math.random() * 5;
    var roundNum = Math.floor(randomNum)   
    var numberx = parseInt(startTimeEntry[i].value);
    simStart.value =(roundNum + numberx);   
    if (simStart.value < 1000) {
        simStart.value = "0" + (roundNum + numberx);
    }
}
}

ok let me make one real quick

I should have said you need to use .querySelectorAll to get a node list of all the rows. Then you can loop through them with a for loop or .forEach

var startTimeEntries = document.querySelectorAll(".startTime");

for (i = 0; i < startTimeEntries.length; i++) {
  currentRow = startTimeEntries[i];
  // calculate results
}

You will have to use querySelectorAll and [i] indexing for simStart, endtime and other values in each row too.

// instead of simStart.value = something
simStart[i].value = something;

Thanks man I appreciate that! Chalk that one up to just starting out. Been doing JS only a few months but I know HTML and CSS so it helps a little. When I get back from my run I’m planning on having a beer and implementing changes to the code based on what you have said. Thanks again

In the event you enter in something like 0700 for a start time, there is code in there which does all the other operations but in addition it will subtract an additional 40 from the number. so if it goes negative and uses 5 for the random number it should give you 0655

I used .charAt to look for the third digit in the number to stop it from subtracting 40 except in the case that the number entered for the startTime is an hour that is on the hour.

Hello. I’ve been away from FCC for awhile because I have been busy, but I have not stopped working on my program. Its a lot of code so I made it into a codePen. Here is the link:

I have gotten most of the bugs out of it by now (i’ve been coding since maybe August in JS I work in the trades). I really enjoy the algorithm scripting part of JS the most, and my program does that.

The problem I am having here is that the actualHoursF() function is supposed to tally up the simulated hours and give you a value in the simActual box. I think I’m doing something stupid. When you click the “calculate” button, it populates the simulated totals, but I have multiple event listeners on that button, and actualHoursF() is one of them. If you click the button again, the actualHoursF() function adds the sim totals up, but by then my other functions are poulating the table with new data that doesn’t match what the actualHours total is. It lags behind by one cycle. If someone could help me I’d be really happy.

The other problem is I’m getting NaN sometimes in my sim totals. I notice it only happens when newEndTime() produces a positive integer. newEndTime basically takes the end time that is entered in endTimeEntry and randomly adds or subtracts a number between 0 and 3 to it, giving a simulated time. I also should mention that newStartTime does the same thing for the startTimeEntry. my “cleanUpXXX” functions are there to go from base 10 math and convert into base 60 math by subtracting 40 in certain conditions, and leaving it alone in other conditions. There is 4 of those, two for the manually entered times and two for the simulated times that it comes up with. Also there is a function all the way at the bottom called “newSimStart” and what that does is it starts at line 2, and overwrites the simulated start time with the end time from the previous iteration (pretty cool huh :slight_smile:) This makes it more realistic. Thanks ahead of time guys I know its a lot of code and its not written very well. Also I have some dumb variable names I know I shouldn’t do this but I was being lazy. Thanks!!

Pretty sure this old thread is dead.

Update: I have solved the cycling question by myself. It was simply the way my functions were sequenced. I have them all firing simultaneously now. just need to figure out the NaN problem and it will be perfect, but at this point is usable.