So Im having trouble with my form. There are numurous validation techniques set up.
Two of my most obvious problems are an alert that pops upen at the start of the program but should only pop up if an onblur() is activated and my update() function returns a false value.
And aswell, my regular Expressions insist on providing me with false condition when I test them against my strings.
The finished form should validate various information and update values placed in the expenses inputs.
Really stuck on this...
window.onload = initPage;
/*initPage()
Initializes the contents of the Web page */
function initPage() {
//declare array variable dataFields points to input elements from the expenseEntry class
var dataFields = new Array();
var allElems = document.getElementsByTagName("*");
for( var i = 0; i < allElems.length; i ++) {
if(allElems[i].className == "expenseEntry") dataFields.push(allElems[i]);
}
//add onblur event that runs update() function whenever focus leaves a datafield.
for(var i = 0; i < dataFields.length; i++) {
dataFields[i].onblur = update();
}
//event handler that runs validateForm() upon submitting the form.
document.forms[0].onsubmit = validateForm;
}
/* testLength()
Tests a field for its length. */
function testLength(field) {
if (field.value.length == 0) {
// Change the background color to white or yellow depending on the lenght.
field.style.backgroundColor = "yellow";
return false;
}
else field.style.backgroundColor = "white";
return true;
}
/* testPattern()
Tests a field for its pattern. */
function testPattern(field, regx) {
if (regx.test(field)) {
field.style.backgroundColor = "white";
field.style.color = "black";
return true;
}
else field.style.backgroundColor = "yellow";
field.style.color = "red";
return false;
}
/* validateForm()
Validates a Web form */
function validateForm() {
var isValid = true;
//testLength function with lname field also for fname, address, and summary to make sure an entry has been made.
if (testLength(document.forms[0].lname) == false) {
isValid = false;}
if (testLength(document.forms[0].fname) == false) {
isValid = false;}
if (testLength(document.forms[0].address) == false) {
isValid = false;}
if (testLength(document.forms[0].summary) == false) {
isValid = false;}
//must match ACT followed by six digits
if (testPattern(document.forms[0].account,/^ACT\d{6}$/) == false)
{isValid = false;}
//dept field. regx should match DEPT followed by three digits
if (testPattern(document.forms[0].department.value,/^DEPT\d{3}$/) == false)
{isValid = false;}
//Project field with regx should match PROJ followed by five digits
if (testPattern(document.forms[0].project,/^PROJ\d{5}$/) == false)
{isValid = false;}
//call testPattern function to test SSN. match 9 digits or text string
if (testPattern(document.forms[0].ssn,/^\d{3}-\d{2}-\d{4}$/) == false)
{isValid = false;}
if (isValid == false)
{alert("Please fill out all required fields in the proper format.");}
return isValid;
}
/* calcRow
Calculates the costs within one row of the travel report */
function calcRow(row) {
var travel = parseFloat(document.forms[0].elements["travel"+row].value);
var lodge = parseFloat(document.forms[0].elements["lodge"+row].value);
var meal = parseFloat(document.forms[0].elements["meal"+row].value);
return travel+lodge+meal;
}
/* calcTotal()
Calculates the total cost of the travel */
function calcTotal() {
//create a variable totalEXP
var totalExp = 0;
//create a for loop that runs 1 t0 4
for (var i = 1; i <= 4; i++)
// increase the value of totalExp by value returned for calcRow
{ totalExp += calcRow(i);}
return totalExp;
}
/* upDate()
Updates the total travel cost */
function update() {
//create a variable numRegExp
var numRegExp = /^\d*(\.\d{0,2})?$/;
// Test weather the currently selected object matches the numRegExp pattern
if (numRegExp.test(this.value)){
// Display the value of the current object to 2 decimal places.
parseInt(this.value).toFixed(2);
//insert a for loop that runs 1 to 4 for all the expense rows in the form
for (var i = 1; i < 4; i++) {
//Set the value of sub[i] field to the value returned by calcRow()
document.forms[0].elements["sub" + i].value = calcRow(i).toFixed(2);
//set the value of the total field equal to the value returned by the calTotal() function
document.forms[0].total.value = calcTotal().toFixed(2);
}
}
//if the condition is not met display alert and change value.
else if (numRegExp.test(this.value) == false) {
alert("Invalid currency value");
(this.value = "0.00");
this.focus();
}
}
body {background: white url(back.jpg) repeat-y scroll 0px 0px}
#links {position: absolute; top: 10px; left: 0px}
#main {border: 1px solid black; width: 640px; padding: 5px;
background-color: white; margin-left: 100px; margin-top: 0px}
span {color: red; font-family: Arial, Helvetica, sans-serif; font-size: 9pt}
table {font-size: 8pt; width: 630px; margin-top: 5px; margin-bottom: 0px}
th {background-color: rgb(153,204,255); text-align: left; font-weight: normal;
font-family: Arial, Helvetica, sans-serif}
#reporttitle {background-color: white; text-align: center; font-family: Arial, Helvetica, sans-serif;
font-size: 18pt; color: rgb(153,204,255); font-weight: bold}
input {width: 100%; font-size: 8pt}
select {width: 100%; font-size: 8pt}
#lname, #fname {width: 150px}
#account, #department, #project {width: 150px}
#traveltable th {text-align: center}
#subhead {width: 100px}
#travelexphead, #lodgeexphead, #mealexphead {width: 80px}
#date1, #date2, #date3, #date4 {text-align: center}
#travel1, #travel2, #travel3, #travel4 {text-align: right}
#lodge1, #lodge2, #lodge3, #lodge4 {text-align: right}
#meal1, #meal2, #meal3, #meal4 {text-align: right}
#sub1, #sub2, #sub3, #sub4,#total {text-align: right}
#traveltable #totalhead {text-align: right}
textarea {height: 100px; width: 100%}
#main #psub {text-align: center}
#main p input {width: 190px; background-color: rgb(153,204,255); color: black;
letter-spacing: 5}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--
New Perspectives on JavaScript, 2nd Edition
Tutorial 5
Case Problem 2
Expense Report Form
Author: Gavin Macken
Date: 8 March `15
Filename: exp.htm
Supporting files: back.jpg, exp.css, links.jpg, logo.jpg, report.js
-->
<title>Expense Report</title>
<link href="exp.css" rel="stylesheet" type="text/css" />
<script src = "report.js" type = "text/javascript"></script>
</head>
<body>
<form id="expform" method="post" action="done.htm">
<div id="links"><img src="links.jpg" alt="" /></div>
<div id="main">
<p><img src="logo.jpg" alt="DeLong Enterprises" /></p>
<table cellspacing="2">
<tr>
<th colspan="5" id="reporttitle">Travel Expense Report</th>
</tr>
<tr>
<th>Name (Last)<span>*</span></th>
<th>(First)<span>*</span></th>
<th>(Initial)</th>
<th>Account<span>*</span></th>
<td><input name="account" id="account" /></td>
</tr>
<tr>
<td><input name="lname" id="lname"/></td>
<td><input name="fname" id="fname"/></td>
<td><input name="init" id="init"/></td>
<th>Department<span>*</span></th>
<td><input name="department" id="department" /></td>
</tr>
<tr>
<th>Social Security Number<span>*</span></th>
<td colspan="2"><input name="ssn" id="ssn" /></td>
<th>Project<span>*</span></th>
<td><input name="project" id="project" /></td>
</tr>
</table>
<table cellspacing="2">
<tr>
<th>Send Check to:<span>*</span></th>
<th>Trip Summary<span>*</span></th>
</tr>
<tr>
<td>
<textarea id="address" name="address" rows="" cols=""></textarea>
</td>
<td>
<textarea id="summary" name="summary" rows="" cols=""></textarea>
</td>
</tr>
</table>
<table id="traveltable" cellspacing="2">
<tr>
<th id="datehead">Travel Date</th>
<th id="travelexphead">Travel Cost</th>
<th id="traveltypehead">Type</th>
<th id="lodgeexphead">Lodging</th>
<th id="mealexphead">Meals</th>
<th id="subhead">Total</th>
</tr>
<tr>
<td><input name="date1" id="date1" /></td>
<td><input name="travel1" id="travel1" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype1" id="traveltype1">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge1" id="lodge1" value="0.00" class="expenseEntry" /></td>
<td><input name="meal1" id="meal1" value="0.00" class="expenseEntry" /></td>
<td><input name="sub1" id="sub1" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date2" id="date2" /></td>
<td><input name="travel2" id="travel2" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype2" id="traveltype2">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge2" id="lodge2" value="0.00" class="expenseEntry" /></td>
<td><input name="meal2" id="meal2" value="0.00" class="expenseEntry" /></td>
<td><input name="sub2" id="sub2" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date3" id="date3" /></td>
<td><input name="travel3" id="travel3" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype3" id="traveltype3">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge3" id="lodge3" value="0.00" class="expenseEntry" /></td>
<td><input name="meal3" id="meal3" value="0.00" class="expenseEntry" /></td>
<td><input name="sub3" id="sub3" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<td><input name="date4" id="date4" /></td>
<td><input name="travel4" id="travel4" value="0.00" class="expenseEntry" /></td>
<td><select name="traveltype4" id="traveltype4">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td><input name="lodge4" id="lodge4" value="0.00" class="expenseEntry" /></td>
<td><input name="meal4" id="meal4" value="0.00" class="expenseEntry" /></td>
<td><input name="sub4" id="sub4" value="0.00" readonly="readonly" /></td>
</tr>
<tr>
<th colspan="5" id="totalhead">TOTAL</th>
<td><input id="total" name="total" readonly="readonly" value="0.00" /></td>
</tr>
<tr>
<td colspan="6"><span>* - Indicates a required field</span></td>
</tr>
</table>
<p id="psub">
<input type="submit" value="Submit Report" />
</p>
</div>
</form>
</body>
</html>
You're testing the DOM element against the regexp, which doesn't make sense. The argument to regx.test() must be a string. You need to use the value of the field:
if (regx.test(field.value)) {
You're setting the onblur property wrong. It should be set to the update function, but you're calling the function at that time. It should be:
dataFields[i].onblur = update;
And you were using the .value property when you called testPattern for the department field. But testPattern expects the argument to be the element, not the value. It should be:
if (testPattern(document.forms[0].department, /^DEPT\d{3}$/) == false)
window.onload = initPage;
/*initPage()
Initializes the contents of the Web page */
function initPage() {
//declare array variable dataFields points to input elements from the expenseEntry class
var dataFields = new Array();
var allElems = document.getElementsByTagName("*");
for (var i = 0; i < allElems.length; i++) {
if (allElems[i].className == "expenseEntry") dataFields.push(allElems[i]);
}
//add onblur event that runs update() function whenever focus leaves a datafield.
for (var i = 0; i < dataFields.length; i++) {
dataFields[i].onblur = update;
}
//event handler that runs validateForm() upon submitting the form.
document.forms[0].onsubmit = validateForm;
}
/* testLength()
Tests a field for its length. */
function testLength(field) {
if (field.value.length == 0) {
// Change the background color to white or yellow depending on the lenght.
field.style.backgroundColor = "yellow";
return false;
} else field.style.backgroundColor = "white";
return true;
}
/* testPattern()
Tests a field for its pattern. */
function testPattern(field, regx) {
if (regx.test(field.value)) {
field.style.backgroundColor = "white";
field.style.color = "black";
return true;
} else field.style.backgroundColor = "yellow";
field.style.color = "red";
return false;
}
/* validateForm()
Validates a Web form */
function validateForm() {
var isValid = true;
//testLength function with lname field also for fname, address, and summary to make sure an entry has been made.
if (testLength(document.forms[0].lname) == false) {
isValid = false;
}
if (testLength(document.forms[0].fname) == false) {
isValid = false;
}
if (testLength(document.forms[0].address) == false) {
isValid = false;
}
if (testLength(document.forms[0].summary) == false) {
isValid = false;
}
//must match ACT followed by six digits
if (testPattern(document.forms[0].account, /^ACT\d{6}$/) == false)
{
isValid = false;
}
//dept field. regx should match DEPT followed by three digits
if (testPattern(document.forms[0].department, /^DEPT\d{3}$/) == false)
{
isValid = false;
}
//Project field with regx should match PROJ followed by five digits
if (testPattern(document.forms[0].project, /^PROJ\d{5}$/) == false)
{
isValid = false;
}
//call testPattern function to test SSN. match 9 digits or text string
if (testPattern(document.forms[0].ssn, /^\d{3}-\d{2}-\d{4}$/) == false) {
isValid = false;
}
if (isValid == false)
{
alert("Please fill out all required fields in the proper format.");
}
return isValid;
}
/* calcRow
Calculates the costs within one row of the travel report */
function calcRow(row) {
var travel = parseFloat(document.forms[0].elements["travel" + row].value);
var lodge = parseFloat(document.forms[0].elements["lodge" + row].value);
var meal = parseFloat(document.forms[0].elements["meal" + row].value);
return travel + lodge + meal;
}
/* calcTotal()
Calculates the total cost of the travel */
function calcTotal() {
//create a variable totalEXP
var totalExp = 0;
//create a for loop that runs 1 t0 4
for (var i = 1; i <= 4; i++)
// increase the value of totalExp by value returned for calcRow
{
totalExp += calcRow(i);
}
return totalExp;
}
/* upDate()
Updates the total travel cost */
function update() {
//create a variable numRegExp
var numRegExp = /^\d*(\.\d{0,2})?$/;
// Test weather the currently selected object matches the numRegExp pattern
if (numRegExp.test(this.value)) {
// Display the value of the current object to 2 decimal places.
parseInt(this.value).toFixed(2);
//insert a for loop that runs 1 to 4 for all the expense rows in the form
for (var i = 1; i < 4; i++) {
//Set the value of sub[i] field to the value returned by calcRow()
document.forms[0].elements["sub" + i].value = calcRow(i).toFixed(2);
//set the value of the total field equal to the value returned by the calTotal() function
document.forms[0].total.value = calcTotal().toFixed(2);
}
}
//if the condition is not met display alert and change value.
else if (numRegExp.test(this.value) == false) {
alert("Invalid currency value");
(this.value = "0.00");
this.focus();
}
}
body {
background: white url(back.jpg) repeat-y scroll 0px 0px
}
#links {
position: absolute;
top: 10px;
left: 0px
}
#main {
border: 1px solid black;
width: 640px;
padding: 5px;
background-color: white;
margin-left: 100px;
margin-top: 0px
}
span {
color: red;
font-family: Arial, Helvetica, sans-serif;
font-size: 9pt
}
table {
font-size: 8pt;
width: 630px;
margin-top: 5px;
margin-bottom: 0px
}
th {
background-color: rgb(153, 204, 255);
text-align: left;
font-weight: normal;
font-family: Arial, Helvetica, sans-serif
}
#reporttitle {
background-color: white;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
font-size: 18pt;
color: rgb(153, 204, 255);
font-weight: bold
}
input {
width: 100%;
font-size: 8pt
}
select {
width: 100%;
font-size: 8pt
}
#lname,
#fname {
width: 150px
}
#account,
#department,
#project {
width: 150px
}
#traveltable th {
text-align: center
}
#subhead {
width: 100px
}
#travelexphead,
#lodgeexphead,
#mealexphead {
width: 80px
}
#date1,
#date2,
#date3,
#date4 {
text-align: center
}
#travel1,
#travel2,
#travel3,
#travel4 {
text-align: right
}
#lodge1,
#lodge2,
#lodge3,
#lodge4 {
text-align: right
}
#meal1,
#meal2,
#meal3,
#meal4 {
text-align: right
}
#sub1,
#sub2,
#sub3,
#sub4,
#total {
text-align: right
}
#traveltable #totalhead {
text-align: right
}
textarea {
height: 100px;
width: 100%
}
#main #psub {
text-align: center
}
#main p input {
width: 190px;
background-color: rgb(153, 204, 255);
color: black;
letter-spacing: 5
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--
New Perspectives on JavaScript, 2nd Edition
Tutorial 5
Case Problem 2
Expense Report Form
Author: Gavin Macken
Date: 8 March `15
Filename: exp.htm
Supporting files: back.jpg, exp.css, links.jpg, logo.jpg, report.js
-->
<title>Expense Report</title>
<link href="exp.css" rel="stylesheet" type="text/css" />
<script src="report.js" type="text/javascript"></script>
</head>
<body>
<form id="expform" method="post" action="done.htm">
<div id="links">
<img src="links.jpg" alt="" />
</div>
<div id="main">
<p>
<img src="logo.jpg" alt="DeLong Enterprises" />
</p>
<table cellspacing="2">
<tr>
<th colspan="5" id="reporttitle">Travel Expense Report</th>
</tr>
<tr>
<th>Name (Last)<span>*</span>
</th>
<th>(First)<span>*</span>
</th>
<th>(Initial)</th>
<th>Account<span>*</span>
</th>
<td>
<input name="account" id="account" />
</td>
</tr>
<tr>
<td>
<input name="lname" id="lname" />
</td>
<td>
<input name="fname" id="fname" />
</td>
<td>
<input name="init" id="init" />
</td>
<th>Department<span>*</span>
</th>
<td>
<input name="department" id="department" />
</td>
</tr>
<tr>
<th>Social Security Number<span>*</span>
</th>
<td colspan="2">
<input name="ssn" id="ssn" />
</td>
<th>Project<span>*</span>
</th>
<td>
<input name="project" id="project" />
</td>
</tr>
</table>
<table cellspacing="2">
<tr>
<th>Send Check to:<span>*</span>
</th>
<th>Trip Summary<span>*</span>
</th>
</tr>
<tr>
<td>
<textarea id="address" name="address" rows="" cols=""></textarea>
</td>
<td>
<textarea id="summary" name="summary" rows="" cols=""></textarea>
</td>
</tr>
</table>
<table id="traveltable" cellspacing="2">
<tr>
<th id="datehead">Travel Date</th>
<th id="travelexphead">Travel Cost</th>
<th id="traveltypehead">Type</th>
<th id="lodgeexphead">Lodging</th>
<th id="mealexphead">Meals</th>
<th id="subhead">Total</th>
</tr>
<tr>
<td>
<input name="date1" id="date1" />
</td>
<td>
<input name="travel1" id="travel1" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype1" id="traveltype1">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge1" id="lodge1" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal1" id="meal1" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub1" id="sub1" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date2" id="date2" />
</td>
<td>
<input name="travel2" id="travel2" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype2" id="traveltype2">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge2" id="lodge2" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal2" id="meal2" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub2" id="sub2" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date3" id="date3" />
</td>
<td>
<input name="travel3" id="travel3" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype3" id="traveltype3">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge3" id="lodge3" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal3" id="meal3" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub3" id="sub3" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<td>
<input name="date4" id="date4" />
</td>
<td>
<input name="travel4" id="travel4" value="0.00" class="expenseEntry" />
</td>
<td>
<select name="traveltype4" id="traveltype4">
<option>air</option>
<option>auto</option>
<option>taxi</option>
<option>train</option>
</select>
</td>
<td>
<input name="lodge4" id="lodge4" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="meal4" id="meal4" value="0.00" class="expenseEntry" />
</td>
<td>
<input name="sub4" id="sub4" value="0.00" readonly="readonly" />
</td>
</tr>
<tr>
<th colspan="5" id="totalhead">TOTAL</th>
<td>
<input id="total" name="total" readonly="readonly" value="0.00" />
</td>
</tr>
<tr>
<td colspan="6"><span>* - Indicates a required field</span>
</td>
</tr>
</table>
<p id="psub">
<input type="submit" value="Submit Report" />
</p>
</div>
</form>
</body>
</html>
Related
Here's another problem encountered with js/html code. I typed some numbers at the top of the page, then after I pressed the button First Line, it will display the numbers I inputted in the first table row accordingly. If I press the button Last Line, I'd like it to display some numbers after getting done with some arithmetics, which is in the btn2 part in the js file, in the last table row of the page. I'd like to find out if it is the problem of innerHTML or valueAsNumber in the if statements, or the variables declared in the for loop not applicable in the later if statements, that caused the numbers in the last row cannot be displayed eventually.
The for loop and the if statement is intended for the page to scan the numbers inputted in the first row, do some arithmetics with them, and display them in the last row, in each respective cell. Is there any other way out to do so?
Thank you very much!
const tab = document.getElementById("tab");
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
var R1 = [R1C1, R1C2, R1C3, R1C4, R1C5, R1C6, R1C7, R1C8,
R1C9, R1C10, R1C11, R1C12, R1C13, R1C14, R1C15, R1C16];
var R2 = [R2C1, R2C2, R2C3, R2C4, R2C5, R2C6, R2C7, R2C8,
R2C9, R2C10, R2C11, R2C12, R2C13, R2C14, R2C15, R2C16];
btn1.addEventListener('click', () => {
for (var i = 0; i <= 15; i++) {
let row = tab.rows[1];
let c = row.cells[i];
let inpId = 'inp' + (i + 1);
let inpEl = document.getElementById(inpId);
c.innerHTML = inpEl.value;
}
});
btn2.addEventListener('click', () => {
for (var i = 0; i <= 15; i++) {
var r1c = R1[i].id;
var r2c = R2[i].id;
var r1El = document.getElementById(r1c);
var r2El = document.getElementById(r2c);
}
if (r1El.innerHTML > 0) {
var choices = [0, (r1El.valueAsNumber) % 7, (r1El.valueAsNumber + 2) % 7, (r1El.valueAsNumber - 2) % 7];
var x = Math.floor(Math.random() * choices.length);
if (choices[x] == choices.at(0)) {
r2El.innerHTML = choices[x];
} else if (choices[x] <= 0) {
r2El.innerHTML = choices[x] + 7;
}
}
});
th,
tr,
td {
border: 1px solid black;
padding: 5px;
width: 40px;
text-align: center;
}
<div class="container">
<div id="data">
<table id="inpdata">
<tr>
<td id="inpb1">Group 1</td>
<td id="inpb2">Group 2</td>
<td id="inpb3">Group 3</td>
<td id="inpb4">Group 4</td>
</tr>
<tr>
<td>
<input type="number" id="inp1" title="inp1">
<input type="number" id="inp2" title="inp2">
<input type="number" id="inp3" title="inp3">
<input type="number" id="inp4" title="inp4">
</td>
<td>
<input type="number" id="inp5" title="inp5">
<input type="number" id="inp6" title="inp6">
<input type="number" id="inp7" title="inp7">
<input type="number" id="inp8" title="inp8">
</td>
<td>
<input type="number" id="inp9" title="inp9">
<input type="number" id="inp10" title="inp10">
<input type="number" id="inp11" title="inp11">
<input type="number" id="inp12" title="inp12">
</td>
<td>
<input type="number" id="inp13" title="inp13">
<input type="number" id="inp14" title="inp14">
<input type="number" id="inp15" title="inp15">
<input type="number" id="inp16" title="inp16">
</td>
</tr>
</table>
<br>
<button id="btn1">First line</button>
<button id="btn2">Last line</button>
</div>
<div id="tables">
<table id="tab">
<tr>
<th colspan="4">Group 1</th>
<th colspan="4">Group 2</th>
<th colspan="4">Group 3</th>
<th colspan="4">Group 4</th>
</tr>
<tr>
<td id="R1C1"></td>
<td id="R1C2"></td>
<td id="R1C3"></td>
<td id="R1C4"></td>
<td id="R1C5"></td>
<td id="R1C6"></td>
<td id="R1C7"></td>
<td id="R1C8"></td>
<td id="R1C9"></td>
<td id="R1C10"></td>
<td id="R1C11"></td>
<td id="R1C12"></td>
<td id="R1C13"></td>
<td id="R1C14"></td>
<td id="R1C15"></td>
<td id="R1C16"></td>
</tr>
<tr>
<td id="R2C1"></td>
<td id="R2C2"></td>
<td id="R2C3"></td>
<td id="R2C4"></td>
<td id="R2C5"></td>
<td id="R2C6"></td>
<td id="R2C7"></td>
<td id="R2C8"></td>
<td id="R2C9"></td>
<td id="R2C10"></td>
<td id="R2C11"></td>
<td id="R2C12"></td>
<td id="R2C13"></td>
<td id="R2C14"></td>
<td id="R2C15"></td>
<td id="R2C16"></td>
</tr>
</table>
</div>
So you can Iterate the td by iterating the elements HTMLCollection property of the tr. Iterate two Iterables by using the index from one.
const tab = document.getElementById("tab");
const btn1 = document.getElementById('btn1');
const btn2 = document.getElementById('btn2');
const firstRow = tab.firstElementChild.children[1].children;
const secondRow = tab.firstElementChild.children[2].children;
btn1.addEventListener('click', () => {
for (var i = 0; i <= 7 /* <- This is a magic value - avoid these */; i++) {
let row = tab.rows[1];
let c = row.cells[i];
let inpId = 'inp' + (i + 1);
let inpEl = document.getElementById(inpId);
c.innerHTML = inpEl.value;
}
});
btn2.addEventListener('click', () => {
[...secondRow].forEach((el,index)=>{
//let group = Math.floor(index / 4);
let inp = parseInt(firstRow[index].innerText, 10);
if (!inp) return;
let choices = [0, inp, (inp + 2), (inp - 2)];
let x = (Math.floor(Math.random() * choices.length) + 7) % 7;
el.innerText = x;
})
});
th,
tr,
td {
border: 1px solid black;
padding: 5px;
width: 40px;
height: 1.5em;
text-align: center;
}
<div class="container">
<div id="data">
<table id="inpdata">
<tr>
<td id="inpb1">Group 1</td>
<td id="inpb2">Group 2</td>
</tr>
<tr>
<td>
<input type="number" id="inp1" title="inp1">
<input type="number" id="inp2" title="inp2">
<input type="number" id="inp3" title="inp3">
<input type="number" id="inp4" title="inp4">
</td>
<td>
<input type="number" id="inp5" title="inp5">
<input type="number" id="inp6" title="inp6">
<input type="number" id="inp7" title="inp7">
<input type="number" id="inp8" title="inp8">
</td>
</tr>
</table>
<br>
<button id="btn1">First line</button>
<button id="btn2">Last line</button>
</div>
<div id="tables">
<table id="tab">
<tr>
<th colspan="4">Group 1</th>
<th colspan="4">Group 2</th>
</tr>
<tr>
<td></td><td></td><td></td><td></td>
<td></td><td></td><td></td><td></td>
</tr>
<tr>
<td></td><td></td><td></td><td></td>
<td></td><td></td><td></td><td></td>
</tr>
</table>
</div>
Some additional advice:
I couldn't be bothered to clean up all of your code, next time please provide a Minimal Example, tree fields would have been plenty to ask the question.
Further please avoid magic numbers, like you use in your loops. Get the size of what you are iterating when you use it. This makes your code more flexible and reusable.
In the same vein: Please do not throw ids everywhere. They just beg to break your code if you ever try to reuse it somehow.
I tried a project which has a form to submit the employee expenses. I got everything working but unable to clear the form (entered details in the text fields) after clicking on submit.
Getting Error: (After entering the details and clicking the submit button)
Uncaught ReferenceError: d is not defined at HTMLInputElement.onclick (index.html:63:42)
Here is my code:
document.getElementById("submit").addEventListener("click", (e) => {
e.preventDefault();
// Form validation
function validate() {
if (document.myForm.empId.value == "") {
alert("Please provide your Employee ID!");
document.myForm.empId.focus();
return false;
}
if (document.myForm.empName.value == "") {
alert("Please provide your Name!");
document.myForm.empName.focus();
return false;
}
if (document.myForm.PaymentMode.value == "") {
alert("Select your Payment Mode!");
document.myForm.PaymentMode.focus();
return false;
}
if (document.myForm.Date.value == "") {
alert("Please provide the Date!");
document.myForm.Date.focus();
return false;
}
if (document.myForm.Bill.value == "") {
alert("Please provide your Bill Amount!");
document.myForm.Bill.focus();
return false;
}
return true;
}
let id = document.getElementById("id").innerText;
let empId = document.getElementById("empID").value;
let name = document.getElementById("name").innerText;
let empName = document.getElementById("empname").value;
let using = document.getElementById("using").innerText;
let mode = document.getElementById("payment-mode").value;
let day = document.getElementById("day").innerText;
let date = document.getElementById("date").value;
let amount = document.getElementById("amount").innerText;
let bill = document.getElementById("bill").value;
let form = document.getElementById("forReset");
let array = [
[id, empId],
[name, empName],
[using, mode],
[day, date],
[amount, bill],
];
let expenseList = Object.fromEntries(array);
const expenseTable = document.getElementById("expenseTable");
function output() {
if (validate()) {
for (let i = 0; i < Object.keys(expenseList).length; i++) {
expenseTable.innerHTML += `
<tr>
<td>${expenseList[id]}</td>
<td>${expenseList[name]}</td>
<td>${expenseList[using]}</td>
<td>${expenseList[day]}</td>
<td>$${expenseList[amount]}</td>
<td><a class="deleteButton">Delete</td>
</tr>
`;
for (let i = 0; i < expenseTable.children.length; i++) {
expenseTable.children[i]
.querySelector(".deleteButton")
.addEventListener("click", function () {
this.parentNode.parentNode.remove();
});
}
break;
}
} else {
return false;
}
}
output();
function d() {
form.reset();
}
d();
});
.table {
border: 1px solid black;
width: 100%;
}
th {
border-right: 1px solid black;
}
.table td {
border: 1px solid black;
text-align: center;
}
.deleteButton {
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expense Tracker Project</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="employee-info">
<form
id="forReset"
class="expenesesForm"
name="myForm"
onsubmit="return(validate());"
method="POST"
action=""
>
<table>
<tr>
<td id="id">Employee ID:</td>
<td>
<input id="empID" name="empId" type="text" placeholder="Employee ID" />
</td>
</tr>
<tr>
<td id="name">Name:</td>
<td>
<input id="empname" type="text" placeholder="Name" name="empName" />
</td>
</tr>
<tr>
<td id="using">Payment Mode:</td>
<td>
<select id="payment-mode" name="PaymentMode">
<option class="" value="" selected disabled>
Select from the list
</option>
<option class="mode" value="card">Card</option>
<option class="mode" value="cheque">Cheque</option>
<option class="mode" value="cash">Cash</option>
<option class="mode" value="other">Other</option>
</select>
</td>
</tr>
<tr>
<td id="day">Date of Transaction:</td>
<td><input id="date" type="date" name="Date" /></td>
</tr>
<tr>
<td id="amount">Amount:</td>
<td><input id="bill" type="number" name="Bill" /></td>
</tr>
<tr>
<td>
<br />
<input
id="submit"
type="submit"
value="Submit"
onclick="javascript:d();"
/>
<input id="reset" type="reset" value="Cancel" />
</td>
</tr>
</table>
</form>
<br />
<table class="table">
<thead>
<tr>
<th>Employee Id</th>
<th>Name</th>
<th>Mode of Transaction</th>
<th>Date of Transaction</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="expenseTable"></tbody>
</table>
</div>
<script src="./script.js"></script>
</body>
</html>
Expected output:
After clicking the submit button, entered form details should get cleared.
Here is a simple method,
click reset button automatically after submit
You could reuse the <input type="reset">
cancel icon to clear form values
https://www.w3schools.com/tags/att_input_type_reset.asp
Also, you can hide reset input using display:none, if it is not necessary in your screen
An alternative method is clear each input value by setting an empty value in it
function formReset () {
document.getElementById("empID").value = '';
document.getElementById("name").innerText = '';
document.getElementById("empname").value = '';
}
Here is a working example
document.getElementById("submit").addEventListener("click", (e) => {
e.preventDefault();
// Form validation
function validate() {
if (document.myForm.empId.value == "") {
alert("Please provide your Employee ID!");
document.myForm.empId.focus();
return false;
}
if (document.myForm.empName.value == "") {
alert("Please provide your Name!");
document.myForm.empName.focus();
return false;
}
if (document.myForm.PaymentMode.value == "") {
alert("Select your Payment Mode!");
document.myForm.PaymentMode.focus();
return false;
}
if (document.myForm.Date.value == "") {
alert("Please provide the Date!");
document.myForm.Date.focus();
return false;
}
if (document.myForm.Bill.value == "") {
alert("Please provide your Bill Amount!");
document.myForm.Bill.focus();
return false;
}
return true;
}
let id = document.getElementById("id").innerText;
let empId = document.getElementById("empID").value;
let name = document.getElementById("name").innerText;
let empName = document.getElementById("empname").value;
let using = document.getElementById("using").innerText;
let mode = document.getElementById("payment-mode").value;
let day = document.getElementById("day").innerText;
let date = document.getElementById("date").value;
let amount = document.getElementById("amount").innerText;
let bill = document.getElementById("bill").value;
let array = [
[id, empId],
[name, empName],
[using, mode],
[day, date],
[amount, bill],
];
let expenseList = Object.fromEntries(array);
const expenseTable = document.getElementById("expenseTable");
function output() {
if (validate()) {
for (let i = 0; i < Object.keys(expenseList).length; i++) {
expenseTable.innerHTML += `
<tr>
<td>${expenseList[id]}</td>
<td>${expenseList[name]}</td>
<td>${expenseList[using]}</td>
<td>${expenseList[day]}</td>
<td>$${expenseList[amount]}</td>
<td><a class="deleteButton">Delete</td>
</tr>
`;
for (let i = 0; i < expenseTable.children.length; i++) {
expenseTable.children[i]
.querySelector(".deleteButton")
.addEventListener("click", function () {
this.parentNode.parentNode.remove();
});
}
break;
}
} else {
return false;
}
}
output();
function clearData() {
document.getElementById("reset").click();
}
clearData();
});
.table {
border: 1px solid black;
width: 100%;
}
th {
border-right: 1px solid black;
}
.table td {
border: 1px solid black;
text-align: center;
}
.deleteButton {
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Expense Tracker Project</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div class="employee-info">
<form
id="forReset"
class="expenesesForm"
name="myForm"
onsubmit="return(validate());"
method="POST"
action=""
>
<table>
<tr>
<td id="id">Employee ID:</td>
<td>
<input id="empID" name="empId" type="text" placeholder="Employee ID" />
</td>
</tr>
<tr>
<td id="name">Name:</td>
<td>
<input id="empname" type="text" placeholder="Name" name="empName" />
</td>
</tr>
<tr>
<td id="using">Payment Mode:</td>
<td>
<select id="payment-mode" name="PaymentMode">
<option class="" value="" selected disabled>
Select from the list
</option>
<option class="mode" value="card">Card</option>
<option class="mode" value="cheque">Cheque</option>
<option class="mode" value="cash">Cash</option>
<option class="mode" value="other">Other</option>
</select>
</td>
</tr>
<tr>
<td id="day">Date of Transaction:</td>
<td><input id="date" type="date" name="Date" /></td>
</tr>
<tr>
<td id="amount">Amount:</td>
<td><input id="bill" type="number" name="Bill" /></td>
</tr>
<tr>
<td>
<br />
<input
id="submit"
type="submit"
value="Submit"
/>
<input id="reset" type="reset" value="Cancel" />
</td>
</tr>
</table>
</form>
<br />
<table class="table">
<thead>
<tr>
<th>Employee Id</th>
<th>Name</th>
<th>Mode of Transaction</th>
<th>Date of Transaction</th>
<th>Amount</th>
</tr>
</thead>
<tbody id="expenseTable"></tbody>
</table>
</div>
<script src="./script.js"></script>
</body>
</html>
This question already has answers here:
Are Variable Operators Possible?
(8 answers)
Closed 4 years ago.
I want to make a form where the two first input fields accept numbers and the third one the symbol and then the result is calculated and shown as in the image. my goal
my code so far is:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test</title>
<style>
form {
background-color:cyan;
border:solid 1px blue;
padding:2px;
width:500px;
}
#lf{
background-color:#ccc;
border:solid 3px black;
padding:4px;
}
form td { background-color:cyan;
font-family:"Courier New", Courier, monospace;
}
#resultSt{
color:#C00;
font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
font-weight:bolder;
animation:ease-in;
}
</style>
<script>
var $original = null;
$(document).ready(function(){
$("p").keyup(function(){
var a=$("#1").val();
var b=$("#2").val();
var c=$("#3").val();
var d=addnumbers(a,b);
$("span").append(d);
if(d>5){
$("span").css({"color":"green"});
$("span").css({"font-weight":"bold"});
}
else{
$("span").css({"color":"red"});
$("span").css({"font-weight":"bold"});
}
});
$("p").mouseout(function(){
$("span").html($original);
});
function addnumbers(a,b){
var c=Number(a)+Number(b);
return c;
}
});
</script>
</head>
<body>
<section>
<article>
<form>
<table >
<tr>
<td>First Number:</td>
<td><input type="number" id="1" name="first" size="30" required="required" ></td>
</tr>
<tr>
<td>Second Number:</td>
<td><input type="number" id="2" name="second" size="30" required="required" ></td>
</tr>
<tr>
<td>Symbol:</td>
<td> <label for="symbol"></i>
</label>
<input name="symbol" id="3" pattern="[+ - * / ]">
</td>
</tr>
<tr>
<td>Result is:</td>
<td><input type="text" name="city" size="30" ></td>
</tr>
</table> <br />
<input type="submit" value="submit" id="sb">
</form>
</article>
</section>
</body>
</html>
i just cant find a way to make the function accept symbols from Symbol input field. Do you guys have any suggestions, solutions.
thank you!
PS: I am newbie in coding.
As a starting point, you could use a switch statement, eg:
var a=$("#1").val() * 1; // *1 gets the value and ensures it's a number
var b=$("#2").val() * 1;
var op=$("#3").val(); // get the operation
var d;
// equivalent of: if (op == "+") .. else if (op == "-")
switch (op) {
case "+": d=a+b; break;
case "-": d=a-b; break;
case "*": d=a*b; break;
default: alert("unrecognised operation"); break;
}
Working sample:
var $original = null;
$(document).ready(function() {
$("input").keyup(function() {
var a = $("#1").val() * 1;
var b = $("#2").val() * 1;
var c = $("#3").val();
var op = $("#3").val();
var d;
switch (op) {
case "+":
d = a + b;
break;
case "-":
d = a - b;
break;
case "*":
d = a * b;
break;
default:
d = "unrecognised operation";
break;
}
$("span").text(d);
});
});
form {
background-color: cyan;
border: solid 1px blue;
padding: 2px;
width: 500px;
}
#lf {
background-color: #ccc;
border: solid 3px black;
padding: 4px;
}
form td {
background-color: cyan;
font-family: "Courier New", Courier, monospace;
}
#resultSt {
color: #C00;
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
font-weight: bolder;
animation: ease-in;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</style>
<table>
<tr>
<td>First Number:</td>
<td><input type="number" id="1" name="first" size="30" required="required"></td>
</tr>
<tr>
<td>Second Number:</td>
<td><input type="number" id="2" name="second" size="30" required="required"></td>
</tr>
<tr>
<td>Symbol:</td>
<td>
<input name="symbol" id="3" pattern="[+ - * / ]">
</td>
</tr>
<tr>
<td>Result is:</td>
<td><span><span></td>
</tr>
</table>
So I've been searching this site for weeks trying to find a solution to this and have looked at EVERY question asked about getting the sum of input fields or finding the value of start and stop times but none of them solve my issue.
The included snippet shows a time sheet that I currently am able to input the reg (regular) and ot (overtime) hours and the sum of each row is populated in the total box but at the bottom I have to manually total the column values.
What I would like to do is eliminate the amount of data that has to be input into the form by having javascript calculate the start time and stop time and add the values to the reg, ot and total fields then sum up those columns at the bottom for the grandtotals.
The reason I want to do it like this is that this form is converted into a phone app and the less that is needed to input the fewer mistakes made.
I'm pretty new to this so I'm sure what I have is either incorrect (although it works), or there is a better way to accomplish it with less coding.
Any direction, input or help is greatly appreciated.
function sum() {
var txtFirstNumberValue = document.getElementById('reghours').value;
var txtSecondNumberValue = document.getElementById('othours').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours').value = result;
}
}
function sum2() {
var txtFirstNumberValue = document.getElementById('reghours2').value;
var txtSecondNumberValue = document.getElementById('othours2').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours2').value = result;
}
}
function sum3() {
var txtFirstNumberValue = document.getElementById('reghours3').value;
var txtSecondNumberValue = document.getElementById('othours3').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours3').value = result;
}
}
function sum4() {
var txtFirstNumberValue = document.getElementById('reghours4').value;
var txtSecondNumberValue = document.getElementById('othours4').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours4').value = result;
}
}
function sum5() {
var txtFirstNumberValue = document.getElementById('reghours5').value;
var txtSecondNumberValue = document.getElementById('othours5').value;
var result = parseInt(txtFirstNumberValue) + parseInt(txtSecondNumberValue);
if (!isNaN(result)) {
document.getElementById('totalhours5').value = result;
}
}
</script>
<script>
$(function() {
$('#BasicExample').timepicker();
});
$(function() {
$('#BasicExample2').timepicker();
});
$(function() {
$('#BasicExample3').timepicker();
});
$(function() {
$('#BasicExample4').timepicker();
});
$(function() {
$('#BasicExample5').timepicker();
});
$(function() {
$('#BasicExample6').timepicker();
});
$(function() {
$('#BasicExample7').timepicker();
});
$(function() {
$('#BasicExample8').timepicker();
});
$(function() {
$('#BasicExample9').timepicker();
});
$(function() {
$('#BasicExample10').timepicker();
});
.ui-timepicker-wrapper {
overflow-y: auto;
height: 150px;
width: 6.5em;
background: #fff;
border: 1px solid #ddd;
-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);
-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);
box-shadow:0 5px 10px rgba(0,0,0,0.2);
outline: none;
z-index: 10001;
margin: 0;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration {
width: 13em;
}
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-30,
.ui-timepicker-wrapper.ui-timepicker-with-duration.ui-timepicker-step-60 {
width: 11em;
}
.ui-timepicker-list {
margin: 0;
padding: 0;
list-style: none;
}
.ui-timepicker-duration {
margin-left: 5px; color: #888;
}
.ui-timepicker-list:hover .ui-timepicker-duration {
color: #888;
}
.ui-timepicker-list li {
padding: 3px 0 3px 5px;
cursor: pointer;
white-space: nowrap;
color: #000;
list-style: none;
margin: 0;
}
.ui-timepicker-list:hover .ui-timepicker-selected {
background: #fff; color: #000;
}
li.ui-timepicker-selected,
.ui-timepicker-list li:hover,
.ui-timepicker-list .ui-timepicker-selected:hover {
background: #1980EC; color: #fff;
}
li.ui-timepicker-selected .ui-timepicker-duration,
.ui-timepicker-list li:hover .ui-timepicker-duration {
color: #ccc;
}
.ui-timepicker-list li.ui-timepicker-disabled,
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
color: #888;
cursor: default;
}
.ui-timepicker-list li.ui-timepicker-disabled:hover,
.ui-timepicker-list li.ui-timepicker-selected.ui-timepicker-disabled {
background: #f2f2f2;
}
.auto-style1 {
text-align: right;
}
body {
font-family: sans-serif;
}
#summation {
font-size: 16px;
font-weight: bold;
color:#174C68;
}
.txt {
background-color: #FEFFB0;
font-weight: bold;
text-align: center;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://jemtech.us/scripts/jquery.timepicker.min.js"></script>
<script src="http://jemtech.us/scripts/jquery.timepicker.js"></script>
<body>
<form action="process_form.php" method="post">
<table align="center" style="width: 498px">
<td class="auto-style1"> </td>
<td class="auto-style1"> </td>
<td class="auto-style1" style="width: 127px"> </td>
</table>
<table align="center" class="auto-style6" style="width: 857px">
<th class="auto-style5" style="width: 47px">Start</th>
<th class="auto-style5" style="width: 47px">Stop</th>
<th class="auto-style5" style="width: 43px">Reg</th>
<th class="auto-style5" style="width: 45px">OT</th>
<th class="auto-style5" style="width: 51px">Total</th>
<th class="auto-style5"></th>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample2" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 43px;">
<input type="text" class="txt" name="RegularHours" id="reghours" onkeyup="sum()" style="width: 45px" />
</td>
<td style="height: 26px; width: 45px;">
<input type="text" class="txt" name="OTHours" id="othours" value="0" onkeyup="sum()" style="width: 45px" />
</td>
<td style="height: 26px; width: 51px;">
<input type="text" class="txt" name="TotalHours" id="totalhours" style="width: 50px" readonly/>
</td>
<td style="height: 26px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample3" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample4" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 43px;">
<input type="text" class="txt" name="RegularHours2" id="reghours2" onkeyup="sum2()" style="width: 45px" />
</td>
<td style="height: 26px; width: 45px;">
<input type="text" class="txt" name="OTTotal2" id="othours2" value="0" onkeyup="sum2()" style="width: 45px" />
</td>
<td style="height: 26px; width: 51px;">
<input type="text" class="txt" name="TotalHours2" id="totalhours2" style="width: 50px" readonly/>
</td>
<td style="height: 26px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample5" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample6" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 17px; width: 43px;">
<input type="text" class="txt" class="txt" name="RegularHours3" id="reghours3" onkeyup="sum3()" style="width: 45px" />
</td>
<td style="height: 17px; width: 45px;">
<input type="text" class="txt" class="txt" name="OTHours3" id="othours3" value="0" onkeyup="sum3()" style="width: 45px" />
</td>
<td style="height: 17px; width: 51px;">
<input type="text" class="txt" class="txt" name="TotalHours3" id="totalhours3" style="width: 50px" readonly/>
</td>
<td style="height: 17px">
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample7" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample8" type="text" class="time" style="width: 85px" />
</td>
<td style="width: 43px">
<input type="text" class="txt" name="RegularHours4" id="reghours4" onkeyup="sum4()" style="width: 45px" />
</td>
<td style="width: 45px">
<input type="text" class="txt" name="OTHours4" id="othours4" value="0" onkeyup="sum4()" style="width: 45px" />
</td>
<td style="width: 51px">
<input type="text" class="txt" name="TotalHours4" id="totalhours4" style="width: 50px" readonly/>
</td>
<td>
</td>
</tr>
<tr>
<td style="height: 26px; width: 47px;">
<input id="BasicExample9" type="text" class="time" style="width: 85px" />
</td>
<td style="height: 26px; width: 47px;">
<input id="BasicExample10" type="text" class="time" style="width: 85px" />
</td>
<td style="width: 43px">
<input type="text" class="txt" name="RegularHours5" id="reghours5" onkeyup="sum5()" style="width: 45px" />
</td>
<td style="width: 45px">
<input type="text" class="txt" name="OTHours5" id="othours5" value="0" onkeyup="sum5()" style="width: 45px" />
</td>
<td style="width: 51px">
<input type="text" class="txt" name="TotalHours5" id="totalhours5" style="width: 50px" readonly/>
</td>
<td>
</td>
</tr>
</table>
<div class="auto-style1" style="width: 640px; height: 26px">
<td><strong>Total Hours</strong>
</td>
<td>
<input type="text" class="txt" name="RegTotal" id="total" style="width: 45px" readonly />
</td>
<td>
<input type="text" class="txt" name="OTTotal" id="total" style="width: 45px" readonly/>
</td>
<td style="width: 45px">
<tr id="summation">
<td style="width: 50px">
<input type="text" class="txt" name="GrandTotal" id="grandtotal" style="width: 50px" readonly/>
</td>
<td style="height: 23px"></td>
</tr>
</td>
</div>
<div style="height: 35px"></div>
<hr />
<br/>
<input type="submit" name="submit" value="Submit" />
</form>
</body>
Please consider using a jQuery TimePicker Plugin as mentioned in https://www.sitepoint.com/10-jquery-time-picker-plugins/ together with https://momentjs.com/ for calculations.
As others have mentioned a date picker will make this easier for both you and your users. Either way, you will need to parse your inputs to get date objects
// With date picker
var startDate = new Date(startPicker.value);
or
// With current select inputs
// Get AM/PM hours - hourSelect should be the select element for hours
var startHrs = periodSelect.value === 'PM'
? parseInt(hourSelect.options[hourSelect.selectedIndex].value, 10)
: parseInt(hourSelect.options[hourSelect.selectedIndex].value, 10) + 12;
// No date provided so use dummy date (1970-1-1)
var startDate = new Date(
1970,
1,
1,
startHrs,
minuteSelect.options[minuteSelect.selectedIndex].value; // minuteSelect should be the select element for minutes
);
Then calculate the difference between your start and end dates. As mentioned you can use moment.js for this but the regular date object should be sufficient.
function getDifference(startDate, endDate) {
return new Date(endDate.getTime() - startDate.getTime());
}
Now you can use difference.getUTCHours() and difference.getUTCMinutes to get the total time worked. It should be trivial to get regular and overtime from the total. Remember to check that the start time is before the end.
... or there is a better way to accomplish it with less coding.
The essence of the question seems to be about how to keep the code DRY, not about whether or not to use a date-picker (though that is also an important decision).
The golden rules in spreadsheet-like apps like this with repeated rows are :
use classes for elements in the repeated rows
use ids only for non-repeating element
Here's a general framework :
jQuery(function($) {
var overtimeAfter = 8.0; // hours per day
// *** utility Constructor ***
function Hours(std, ot) {
return {'std':std, 'ot':ot};
}
Hours.prototype.add = function(otherHours) {
return new Hours(this.std+otherHours.std, this.ot+otherHours.ot);
}
// *** utility functions ***
function getTime(input) {
// Here, do whatever is necessary to convert input values to some standard abstraction:
// for example, 24H string or js Date() object.
return Number(input.val()); // simplest case
}
function timeDiffernce(t1, t2) {
// Here do whatever is necessary to calculate the time difference
// between t2 and t1, in whatever abstraction was returned by getTime().
// For example:
var t = t2 - t1; // simplest case
return (t < 0) ? 24 + t : t; // allow for t1...t2 to span midnight
}
// *** core functions ***
function calcDayHours(tr) {
// here is where you benefit from classes within the table row
var time1 = getTime($('.time1', tr));
var time2 = getTime($('.time2', tr));
var hours = timeDiffernce(time1, time2);
var std = Math.min(hours, overtimeAfter);
var ot = Math.max(0, hours - overtimeAfter);
var total = std + ot;
$('.reghours', tr).val(std);
$('.othours', tr).val(ot);
$(".totalhours", tr).val(total);
return new Hours(std, ot);
}
function calcWeekHours(hours) {
var weekHours = hours.reduce(function(week, day) {
return week.add(day);
}, new Hours(0, 0));
// these elements are unique, therefore identified by id.
$("#regTotal").val(weekHours.std);
$("#otTotal").val(weekHours.ot);
$("#grandTotal").val(weekHours.std + weekHours.ot);
return weekHours;
}
// *** master function ***
function sum() {
// Assume a table or tbody with id="timesheet"
var dayHours = $("#timesheet tr").get().map(calcDayHours);
var weekHours = calcWeekHours(dayHours);
// if you want wage calculations, then pass `weekHours` to a `calcWages()` function.
// var wages = calcWages(weekHours);
}
// Then attach `sum` as the handler for all kinds of keyup/tap/click/focus/blur events.
});
As I say, that's just a framework. There are still decisions to make, eg :
what you write in getTime() will depend on the expected date/time input format (text vs date-picker ...)
what you write in timeDiffernce() will depend on what you decide to return from getTime() (Number vs Date ...).
which ui event(s) should trigger sum().
how to specify the overtime threshold overtimeAfter - hardcoding as above will get you started.
how to accommodate overtime thresholds on a "per day", "per week" or "per month" basis - wage systems vary.
Good evening! I'm teaching myself to code. Right now, I'm making a JavaScript loan calculator, but I hit a snag. If I put 0% interest, it displays nothing in my output textboxes. Everything else is working perfectly though. Any help would be appreciated. Thanks!
<!DOCTYPE html>
<html>
<head>
<title>JavaScript Loan Calculator</title>
<style type="text/css">
.auto-style1 {
text-align: left;
}
.auto-style2 {
font-size: larger;
color: #FFF;
font: Georgia;
}
.auto-style3 {
width: 82px;
text-align: center;
style="float: right;
}
table {
background-color: #F5F5F5;
width: 400px;
height: 300px;
padding-left: 20px;
padding-bottom: 20px;
padding-top: 20px;
}
body {
background-color: #d2691e;
}
</style>
</head>
<body>
<form name="loaninfo">
<div class="auto-style1">
<p><strong>
<span class="auto-style2"> </span></strong><strong><span class="auto-style2"><br />
</span></strong></p>
</div>
<table width="327">
<tr><td colspan="3"></td></tr>
<tr>
<td>Loan Amount:</td>
<td>
$
<input type="text" name="principal" size="12" title="textfield" pattern="([0-9]+\.)?[0-9]+" >
</td>
</tr>
<tr>
<td>Interest Rate:</td>
<td>
<input type="text" name="interest" size="12" title="textfield" pattern="([0-9]+\.)?[0-9]+" >
%
</td>
</tr>
<tr>
<td>Number of Years for Loan:</td>
<td>
<input type="text" name="years" size="12" title="textfield" pattern="([0-9]+\.)?[0-9]+" >
</td>
</tr>
<tr>
<td colspan="3"><input type="button" class="auto-style3" onClick="calculate();" value="Calculate">
<br />
<br />
</td>
</tr>
<tr>
<td colspan="3">
<b>Your Payment Information</b>
</td>
</tr>
<tr>
<td>Monthly Payment Amount:</td>
<td>$ <input type="text" name="payment" size="12" readonly /></td>
</tr>
<tr>
<td>Total Payment Amount:</td>
<td>$ <input type="text" name="total" size="12" readonly ></td>
</tr>
<tr>
<td>Total Interest Payments:</td>
<td>$ <input type="text" name="totalinterest" size="12" readonly /> </td>
</tr>
<tr>
<td colspan="3">
<input type="reset" class="auto-style3" />
</td>
</tr>
</table>
</form>
<script language="JavaScript">
function calculate() {
var principal = document.loaninfo.principal.value;
var months_in_year = 12
var interest = document.loaninfo.interest.value / 100 / months_in_year;
var payments = document.loaninfo.years.value * months_in_year;
var x = Math.pow(1 + interest, payments);
var monthval = (principal*x*interest)/(x-1);
if (!isNaN(monthval) &&
(monthval != Number.POSITIVE_INFINITY) &&
(monthval != Number.NEGATIVE_INFINITY)) {
document.loaninfo.payment.value = round(monthval);
document.loaninfo.total.value = round(monthval * payments);
document.loaninfo.totalinterest.value = round((monthval * payments) - principal);
}
else {
document.loaninfo.payment.value = "";
document.loaninfo.total.value = "";
document.loaninfo.totalinterest.value = "";
}
function round(x) {
return Math.round(x*100)/100;
}
function jsDecimals(e) {
var evt = (e) ? e : window.event;
var key = (evt.keyCode) ? evt.keyCode : evt.which;
if (key != null) {
key = parseInt(key, 10);
if ((key < 48 || key > 57) && (key < 96 || key > 105)) {
if (!jsIsUserFriendlyChar(key, "Decimals")) {
return false;
}
}
else {
if (evt.shiftKey) {
return false;
}
}
}
return true;
}
form.onsubmit = function () {
return textarea.value.match(/^\d+(\.\d+)?$/);
}
</script>
When you put 0 you are getting
var x = Math.pow(1 + interest, payments); // 1
var monthval = principal * x * interest / (x - 1); //NaN because 1-1 in fraction is 0 so it returns 0/0 and it's NaN
you can change you code to be like this:
if (interest===0){
var monthval = (principal)/(months_in_year);
} else {
var monthval = (principal*x*interest)/(x-1);
}
Working Version: http://codepen.io/mhadaily/pen/ZpypdA
feel free to change it to be like what you want.
It's because of this section of code.
else if (interest == 0) {
document.loaninfo.payment.value = "";
document.loaninfo.total.value = "";
document.loaninfo.totalinterest.value = "";
}
When the interest is 0, you are setting the values of all your output boxes to an empty string.
You should replace the RHS of the assignment.