Help with number program I am writing

Help with number program I am writing
0

#1

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>

#2

Can you show a screenshot of how the fields should be filled out before the Calc button is clicked? Also, using the screenshot data as an example, explain what should display after the Calc button is clicked. I am just wanting to make sure I understand any inputs and the expected outputs.


#3

No problem. Here is a sreen shot


#4

So all the fields with information in them above are entered before clicking Calculate?


#5

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.


#6

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


#7

Going out for a long run. Should be back online in about 4 hours. I will take a look at the code again and let you know what I think.


#8

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


#9

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.


#10

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++) {........}


#11

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.


#12

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!


#13

Could you post a Codepen of the project? That way, we can always see the current version as we are giving you advice.


#14

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);
    }
}
}

#15

ok let me make one real quick


#16

#17

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;

#18

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


#19

There were a couple of other bugs with your calculations. One bug was how it was adding the random minutes. If the random minute was -5 and start time was 0700, then sim start time was 0695 which is invalid.

I have refactored your original project to pre-populate the html with values for the start and end times. You can still change them, but it at least starts with something for all the rows.

I simplified your random minute functions by making them one function instead of 4. Also, there is only one click event instead of 4.

https://fiddle.jshell.net/et803r9t/5/


#20

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