Assign a letter to a number value within a specific range - javascript

a learning noobie here.
I am needing a script that can take a number value and assign a letter to it, depending on the range the value falls within. Please run the simple example below:
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<table>
<tr>
<th>Achieved mark</th>
<th>Grade</th>
</tr>
<tr>
<td>Above 80 (max 100)</td>
<td>A</td>
</tr>
<tr>
<td>60-79</td>
<td>B</td>
</tr>
<tr>
<td>40-59</td>
<td>C</td>
</tr>
<tr>
<td>Below 39 (min 0)</td>
<td>D</td>
</tr>
</table>
<br>
<p>Enter achieved mark:</p>
<input type="input" id="mark" value="73">
<button onclick="myFunction()">GO!</button>
<p>Grade result:</p>
<input type="output" id="grade">
For this above example, when the "GO!" button is clicked, a grade letter would be output depending on the range of the input value.
Thank you in advance.

You can do it like this
First thing is you need to get the value of element that you can get by.
document.getElementById('mark').value this expression.
Now based on this value you can calculate grade by simply using if conditions.
Than you need to assign it to your grade (input) that you can achieve by this document.getElementById('grade').value = grade
function myFunction(e){
var ele = document.getElementById('mark').value;
var grade ='';
if(ele > 80){
grade = 'A';
} else if(ele <=79 && ele >=60){
grade = 'B';
} else if(ele <=59 && ele >=40){
grade = 'C'
} else {
grade = 'D';
}
document.getElementById('grade').value = grade;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<table>
<tr>
<th>Achieved mark</th>
<th>Grade</th>
</tr>
<tr>
<td>Above 80 (max 100)</td>
<td>A</td>
</tr>
<tr>
<td>60-79</td>
<td>B</td>
</tr>
<tr>
<td>40-59</td>
<td>C</td>
</tr>
<tr>
<td>Below 39 (min 0)</td>
<td>D</td>
</tr>
</table>
<br>
<p>Enter achieved mark:</p>
<input type="input" id="mark" value="73">
<button onclick="myFunction()">GO!</button>
<p>Grade result:</p>
<input type="output" id="grade">

Simple else if condition:
function myFunction() {
var num = document.getElementById('mark').value;
var result = 'A';
num = Math.min(100, Math.max(0, num));
if (num < 40) {
result = 'D';
} else if (num < 60) {
result = 'C';
} else if (num < 80) {
result = 'B';
}
document.getElementById('grade').value = result;
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
td, th {
border: 1px solid #dddddd;
text-align: left;
padding: 8px;
}
<table>
<tr>
<th>Achieved mark</th>
<th>Grade</th>
</tr>
<tr>
<td>Above 80 (max 100)</td>
<td>A</td>
</tr>
<tr>
<td>60-79</td>
<td>B</td>
</tr>
<tr>
<td>40-59</td>
<td>C</td>
</tr>
<tr>
<td>Below 39 (min 0)</td>
<td>D</td>
</tr>
</table>
<br>
<p>Enter achieved mark:</p>
<input type="input" id="mark" value="73">
<button onclick="myFunction()">GO!</button>
<p>Grade result:</p>
<input type="output" id="grade">

Return a string based on the current grade.
const myFunction = (grade) => {
let mark = null;
if (grade >= 80 && grade <= 100) {
mark = 'A';
} else if (grade >= 60 && grade <= 79) {
mark = 'B';
} else if (grade >= 40 && grade <= 59) {
mark = 'C'
} else if (grade <= 39) {
mark = 'Dude?';
} else {
return false;
}
return mark;
}
const grade = myFunction(60);
console.log(grade);
You can also use this utility if you want to make it shorter.
// Check a range of numbers in an if condition

You can also try below one.
const grades = {
100: 'A',
80: 'B',
60: 'C',
40: 'D'
};
function myFunction() {
const ele = document.getElementById('mark').value;
let grade = 'Invalid input';
for (const g in grades) {
if (parseInt(ele) < parseInt(g)) {
grade = grades[g];
break;
}
}
document.getElementById('grade').value = grade;
}
It has the flexibility to configure the grades and also handling the invalid cases.

Related

Add columns to a new table row in JQuery

I have the following html:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
<td id=col4">7</td>
</tr>
</tbody>
</table>
I would like to use JQuery to append everything after column 3 (col3) to a new row. Ideally I would end up with something like this:
<table id='myTable'>
<tbody>
<tr>
<td id=col1">12</td>
<td id=col2">55</td>
<td id=col3">142</td>
</tr>
<tr>
<td id=col4">7</td>
</tr>
</tbody>
</table>
Any ideas how this could be achieved? I have tried a few things but haven't been able to get it working.
You could define a generic redistribution function, that takes as argument the desired number of columns, and which just fills up the rows with content from top to bottom, using that number of columns.
It could even be a jQuery plugin:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; border: 2px solid }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
Here is a version with one extra statement that sets the colspan on the very last td element so it occupies the remaining columns in the last row:
$.fn.redistribute = function(maxNumCols) {
if (maxNumCols < 1) return;
$(this).each(function () {
let cells = Array.from($("td", this));
let $tr = $("tr", this);
let rowCount = Math.ceil(cells.length / maxNumCols);
for (let i = 0; i < rowCount; i++) {
let $row = i >= $tr.length ? $("<tr>").appendTo(this) : $tr.eq(i);
$row.append(cells.splice(0, maxNumCols));
}
$("td", this).last().attr("colspan", rowCount * maxNumCols - cells.length + 1);
});
}
// I/O management
function alignTable() {
let cols = +$("input").val(); // Get desired number of columns
$("#myTable").redistribute(cols); // Apply to table
}
// Refresh whenever input changes
$("input").on("input", alignTable);
// Refresh on page load
alignTable();
table { border-collapse: collapse; }
td { border: 1px solid; padding: 4px }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Desired number of columns: <input type="number" size="3" value="4" min="1">
<table id='myTable'>
<tbody>
<tr>
<td>12</td>
<td>55</td>
<td>142</td>
<td>7</td>
<td>20</td>
<td>410</td>
<td>99</td>
</tr>
</tbody>
</table>
It sounds like you're still new to jQuery. To give you an idea how to solve your described problem, I have written a solution here. I hope it helps you.
// parameters for splitting
var splitIndex = 3,
splitClass = '.split-columns';
// start the splitting
splitColumnsIntoRows();
function splitColumnsIntoRows() {
var $tables = $(splitClass),
numberTables = $tables.length;
if (numberTables == 0) {
return;
}
for (var i = 0; i < numberTables; i++) {
iterateSplittingRows($($tables[i]).find('tr'));
}
}
function iterateSplittingRows($currentRows) {
var $currentRow,
numberRows = $currentRows.length;
if (numberRows == 0) {
return;
}
for (var i = 0; i < numberRows; i++) {
$currentRow = $($currentRows[i]);
iterateSplittingFields($currentRow, $currentRow.find('th, td'));
}
}
function iterateSplittingFields($currentRow, $currentFields) {
var $newRow,
newRows = [],
childrenLength,
numberFields = $currentFields.length;
if (numberFields == 0) {
return;
}
for (var i = 0; i < numberFields; i++) {
if (i < splitIndex) {
continue;
}
if (i % splitIndex == 0) {
$newRow = $('<tr></tr>');
}
$newRow.append($currentFields[i]);
if (i == numberFields - 1) {
childrenLength = $newRow.children().length;
// fill the row with empty fields if the length does not fit the splitIndex
for (var j = splitIndex; j > childrenLength; j--) {
$newRow.append($('<td></td>'));
}
}
if (
(i >= splitIndex && i % splitIndex == splitIndex - 1)
||
i == numberFields - 1
){
newRows.push($newRow);
}
}
$currentRow.after(newRows);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="myTable" class="split-columns">
<tbody>
<tr>
<td class="col_01">01</td>
<td class="col_02">02</td>
<td class="col_03">03</td>
<td class="col_04">04</td>
<td class="col_05">05</td>
<td class="col_06">06</td>
<td class="col_07">07</td>
<td class="col_08">08</td>
<td class="col_09">09</td>
</tr>
<tr>
<td class="col_10">10</td>
<td class="col_11">11</td>
<td class="col_12">12</td>
<td class="col_13">13</td>
<td class="col_14">14</td>
<td class="col_15">15</td>
<td class="col_16">16</td>
<td class="col_17">17</td>
</tr>
<tr>
<td class="col_19">19</td>
<td class="col_20">20</td>
<td class="col_21">21</td>
<td class="col_22">22</td>
<td class="col_23">23</td>
<td class="col_24">24</td>
<td class="col_25">25</td>
</tr>
</tbody>
</table>

Cannot read property 'childNodes' checkbox to get value from same row

Below code should get me the value of the column next to the checked box in the table, but, once the button is clicked, I am getting:
Cannot read property childNodes of null
Note: database from firebase which where the values from the table come from
Table image :
rootRefReAgents.on("child_added", snap => {
var AgentName = snap.child("Name").val();
$("#table_body_Test").append("<tr><td>" + AgentName + "</td><td><INPUT TYPE=\"Checkbox\"> </Input></td></tr>");
});
}
function ActionData(){
let agents = [];
let table = document.getElementById("table_body_Test");
let childNodes = Array.from(table.childNodes);
// let childNodes = table.childNodes;
for (let child of childNodes.values()) {
console.log(`child: ${child}`);
if (child.constructor.name !== "HTMLTableRowElement") {
continue;
}
let agent = child.childNodes.item(1).innerHTML;
console.log(`agent: ${agent}`);
let checkbox = child.childNodes.item(3).childNodes.item(1);
console.log(`checkbox: ${checkbox}`);
console.log(checkbox.checked);
if (checkbox.checked) {
agents.push(agent);
}
}
console.log(`agents: ${agents}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="testTable" align="center">
<thead>
<tr style="color: #D2002E; background: #FFCC01; height:32px;">
<td>Agents</td>
<td>Select</td>
</tr>
</thead>
<tbody id="table_body_Test">
</tbody>
</table>
<button id="submitBtn" onclick="ActionData()">Next</button>
ES6 brought new methods that simplify the code and its reading
const tableBody = document.querySelector('#testTable tbody' );
document.querySelector('#submitBtn').onclick=()=>
{
let agents = [];
console.clear();
for (let rowX of tableBody.rows )
{
let
agent = rowX.cells[0].textContent,
checkbox = rowX.cells[1].querySelector('input[type=checkbox]')
;
console.log( 'agent:', agent, 'checked:', checkbox.checked);
if (checkbox.checked) { agents.push(agent); }
}
console.log( 'agents (array):', agents.join(' / '));
}
/// bonus info :
/*
rootRefReAgents.on("child_added", snap=>{
let
newRow = tableBody.insertRow(-1);
newRow.insertCell(0).textContent = snap.child("Name").val();
newRow.insertCell(1).innerHTML = '<input type="Checkbox">';
});
*/
#testTable { margin: auto; border-collapse: collapse }
#testTable thead tr {
color: #D2002E;
background: #FFCC01;
height:32px;
font-weight: bold;
}
#testTable tr:nth-child(even) {background-color: lightgrey }
#testTable td { border:1px solid grey; padding: 0 20px; }
#testTable td:nth-child(2) { text-align: center }
<table id="testTable">
<thead>
<tr> <td>Agents</td> <td>Select</td> </tr>
</thead>
<tbody>
<tr> <td>AMC</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>Mygulfex</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>topStar</td> <td> <input type="checkbox" > </td> </tr>
<tr> <td>WMC</td> <td> <input type="checkbox" > </td> </tr>
</tbody>
</table>
<button id="submitBtn" >see Selects in console</button>

Calculating GPA and Credit Hours

<script type="text/javascript">
<!--Hide from old browsers
function gpacalc() {
var grade = new Array(9);
var credit = new Array(9);
var getGrade = new Array(5);
var getCredit = new Array(5);
var gradeCount = 12;
grade[0] = "A+";
credit[0] = 4;
grade[1] = "A";
credit[1] = 4;
grade[2] = "A-";
credit[2] = 3.7;
grade[3] = "B+";
credit[3] = 3.3;
grade[4] = "B";
credit[4] = 3;
grade[5] = "B-";
credit[5] = 2.7;
grade[6] = "C+";
credit[6] = 2;
grade[7] = "C-";
credit[7] = 1.7;
grade[8] = "D+";
credit[8] = 1.3;
grade[9] = "D";
credit[9] = 1;
grade[10] = "D-";
credit[10] = 0.7;
grade[11] = "F";
credit[11] = 0.0;
getGrade[0] = document.calcGpaForm.grade1.value;
getGrade[0] = getGrade[0].toUpperCase();
getGrade[1] = document.calcGpaForm.grade2.value;
getGrade[1] = getGrade[1].toUpperCase();
getGrade[2] = document.calcGpaForm.grade3.value;
getGrade[2] = getGrade[2].toUpperCase();
getGrade[3] = document.calcGpaForm.grade4.value;
getGrade[3] = getGrade[3].toUpperCase();
getGrade[4] = document.calcGpaForm.grade5.value;
getGrade[4] = getGrade[4].toUpperCase();
getGrade[5] = document.calcGpaForm.grade6.value;
getGrade[5] = getGrade[5].toUpperCase();
getCredit[0] = document.calcGpaForm.credit1.value;
getCredit[1] = document.calcGpaForm.credit2.value;
getCredit[2] = document.calcGpaForm.credit3.value;
getCredit[3] = document.calcGpaForm.credit4.value;
getCredit[4] = document.calcGpaForm.credit5.value;
getCredit[5] = document.calcGpaForm.credit6.value;
var totalGrades =0;
var totalCredits = 0;
var GPA = 0;
var i = 0;
for (i; i < 6; i++) {
if (getGrade[i] == "") {
break;
}
else if (getGrade[i] == "c" || getGrade[i] == "C") {
alert("'C' is not a vaild letter grade. Course " +eval(i + 1)+ ".")
return;
}
else if (isNaN(getCredit[i])) {
alert("Enter a vaild number of credits for Course " +eval(i + 1)+ ".")
return;
}
else if (getCredit[i] == "") {
alert ("You left the number of credits blank for Course " +eval(i + 1)+ ".")
return;
}
var validgradecheck = 0;
var x = 0;
for (x; x < gradeCount; x++) {
if (getGrade[i] == grade[x]) {
totalGrades = totalGrades + (parseInt(getCredit[i],10) * credit[x]);
totalCredits = totalCredits + parseInt(getCredit[i],10);
validgradecheck = 1;
break;
}
}
if (validgradecheck == 0) {
alert("Could not recognize the grade entered for Course " +eval(i + 1)+ ".");
return;
}
}
if (totalCredits == 0) {
alert("Total credits cannot equal zero.");
return;
}
GPA = Math.round(( totalGrades / totalCredits ) * 100) / 100;
alert("GPA = " + eval(GPA));
return;
}
function copyRight() {
var lastModDate = document.lastModified;
var lastModDate = lastModDate.substring(0,10);
displayDateLast.innerHTML = "<h6>Copyright © Haiwook Choi. "+" <br /> This document was last modified "+lastModDate+".</h6>";
}
//-->
</script>
<style type="text/css">
<!--
.align-center {
text-align:center;
}
table {
margin-left: auto;
margin-right: auto;
width: 70%;
}
.block {
width: 50%;
margin-right: auto;
margin-left: auto;
}
.center-div {
width: 70%;
margin-right: auto;
margin-left: auto;
}
.header-text {
font-family: Arial, Helvetica, sans-serif;
font-size: 12pt;
font-weight: bold;
text-align: center;
}
.center-items {
text-align: center;
}
.right-align {
text-align: right;
width: 50%;
}
.left-align {
text-align: left;
width: 50%;
}
#displayDateLast {
text-align: left;
width: 50%;
margin-right: auto;
margin-left: auto;
}
-->
</style>
I'm trying to make a webpage that allows the user to enter from 4 to 6 grades for any course. Next to the letter grade, I'm wanting to put a text-field that accepts the credit hours for the courses. Also when the Calculate GPA button is clicked I want it to verify that a letter grade has been entered and then accumulate the grade points as well as the credit hours and display the GPA. I'm having trouble getting the GPA to calculate though. As well as having an alert display when a user enters anything other than a letter grade? Can someone look over my code and tell me what I should fix or add? Thanks if you read this and attempt to help!
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Chapter 10 Cases and Places: 2</title>
<script type="text/javascript">
<!--Hide from old browsers
function gpacalc() {
var grade = new Array(9);
var credit = new Array(9);
var getGrade = new Array(5);
var getCredit = new Array(5);
var gradeCount = 12;
grade[0] = "A+";
credit[0] = 4;
grade[1] = "A";
credit[1] = 4;
grade[2] = "A-";
credit[2] = 3.7;
grade[3] = "B+";
credit[3] = 3.3;
grade[4] = "B";
credit[4] = 3;
grade[5] = "B-";
credit[5] = 2.7;
grade[6] = "C+";
credit[6] = 2;
grade[7] = "C-";
credit[7] = 1.7;
grade[8] = "D+";
credit[8] = 1.3;
grade[9] = "D";
credit[9] = 1;
grade[10] = "D-";
credit[10] = 0.7;
grade[11] = "F";
credit[11] = 0.0;
getGrade[0] = document.calcGpaForm.grade1.value;
getGrade[0] = getGrade[0].toUpperCase();
getGrade[1] = document.calcGpaForm.grade2.value;
getGrade[1] = getGrade[1].toUpperCase();
getGrade[2] = document.calcGpaForm.grade3.value;
getGrade[2] = getGrade[2].toUpperCase();
getGrade[3] = document.calcGpaForm.grade4.value;
getGrade[3] = getGrade[3].toUpperCase();
getGrade[4] = document.calcGpaForm.grade5.value;
getGrade[4] = getGrade[4].toUpperCase();
getGrade[5] = document.calcGpaForm.grade6.value;
getGrade[5] = getGrade[5].toUpperCase();
getCredit[0] = document.calcGpaForm.credit1.value;
getCredit[1] = document.calcGpaForm.credit2.value;
getCredit[2] = document.calcGpaForm.credit3.value;
getCredit[3] = document.calcGpaForm.credit4.value;
getCredit[4] = document.calcGpaForm.credit5.value;
getCredit[5] = document.calcGpaForm.credit6.value;
var totalGrades =0;
var totalCredits = 0;
var GPA = 0;
var i = 0;
for (i; i < 6; i++) {
if (getGrade[i] == "") {
break;
}
else if (getGrade[i] == "c" || getGrade[i] == "C") {
alert("'C' is not a vaild letter grade. Course " +eval(i + 1)+ ".")
return;
}
else if (isNaN(getCredit[i])) {
alert("Enter a vaild number of credits for Course " +eval(i + 1)+ ".")
return;
}
else if (getCredit[i] == "") {
alert ("You left the number of credits blank for Course " +eval(i + 1)+ ".")
return;
}
var validgradecheck = 0;
var x = 0;
for (x; x < gradeCount; x++) {
if (getGrade[i] == grade[x]) {
totalGrades = totalGrades + (parseInt(getCredit[i],10) * credit[x]);
totalCredits = totalCredits + parseInt(getCredit[i],10);
validgradecheck = 1;
break;
}
}
if (validgradecheck == 0) {
alert("Could not recognize the grade entered for Course " +eval(i + 1)+ ".");
return;
}
}
if (totalCredits == 0) {
alert("Total credits cannot equal zero.");
return;
}
GPA = Math.round(( totalGrades / totalCredits ) * 100) / 100;
alert("GPA = " + eval(GPA));
return;
}
function copyRight() {
var lastModDate = document.lastModified;
var lastModDate = lastModDate.substring(0,10);
displayDateLast.innerHTML = "<h6>Copyright © Hannah. "+" <br /> This document was last modified "+lastModDate+".</h6>";
}
//-->
</script>
<style type="text/css">
<!--
.align-center {
text-align:center;
}
table {
margin-left: auto;
margin-right: auto;
width: 70%;
}
.block {
width: 50%;
margin-right: auto;
margin-left: auto;
}
.center-div {
width: 70%;
margin-right: auto;
margin-left: auto;
}
.header-text {
font-family: Arial, Helvetica, sans-serif;
font-size: 12pt;
font-weight: bold;
text-align: center;
}
.center-items {
text-align: center;
}
.right-align {
text-align: right;
width: 50%;
}
.left-align {
text-align: left;
width: 50%;
}
#displayDateLast {
text-align: left;
width: 50%;
margin-right: auto;
margin-left: auto;
}
-->
</style>
</head>
<body onLoad="gpacalc(); copyRight()">
<div class="center-div">
<p style="font-family:Arial, Helvetica, sans-serif; font-size:xx-large; font-weight:bold; text-align: center; color:blue">Calculating Your GPA</p>
<p class="block"><strong>Directions: </strong>Enter your letter grade for your courses. In the boxes to the right enter the credit hours per course. Then Click the Calculate GPA button to have your GPA calculated as well as your total credit hours.</p>
<form name="calcGpaForm" method="post">
<table>
<tr>
<h4 style="text-align: center">Letter Grade:</h4>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 1:
</th>
<td class="align-left"><input type="text" name="grade1" type="text" id="grade1" size="10" onBlur="validgradecheck" /></td>
<td class="margin-left: auto"><input type="text" name="credit1" id="credit1" size="10" /></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 2:
</th>
<td class="align-left"><input name="grade2" type="text" id="grade2" size="10" onBlur="validgradecheck" /></td>
<td class="align-left"><input type="text" name="credit2" id="credit2" size="10" /></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 3:
</th>
<td class="align-left"><input name="grade3" type="text" id="grade3" size="10" onBlur="validgradecheck" /></td>
<td class="align-left"><input type="text" name="credit3" id="credit3" size="10" /></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 4:
</th>
<td class="align-left"><input name="grade4" type="text" id="grade4" size="10" onBlur="validgradecheck" /> </td>
<td class="align-left"><input type="text" name="credit4" id="credit4" size="10" /></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 5:
</th>
<td class="align-left"><input type="text" name="grade5" id="grade5" size="10" onBlur="validgradecheck" /></td>
<td class="align-left"><input type="text" name="credit5" id="credit5" size="10" /></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 6:
</th>
<td class="align-left"><input type="text" name="grade6" id="grade6" size="10" onBlur="validgradecheck"/></td>
<td class="align-left"><input type="text" name="credit6" id="credit6" size="10" /></td>
</tr>
<tr>
<td class="right-align">
<input name="button" type="button" value="Calculate GPA" onClick="gpacalc()"/>
</td>
<td class="align-left">
<input name="Reset" type="reset" />
</td>
</tr>
<tr>
<td class="right-align">
<span style="font-weight:bolder;">GPA:</span>
</td>
<td><input type="text" name="gpacalc" id="gpacalc" value=" " size="10" /></td>
</tr>
</table>
</form>
</div>
<div id="displayDateLast">
</div>
</body>
</html>
Few remarks:
I don't think you need to worry about old browsers as no one should be using them nowadays. Therefore, <!--Hide from old browsers --> not needed.
What's the point of calculating the GPA when the page loads i.e. onload? There are no grades when the page loads up, so you'll always get an error. It is probably better to only calculate when the user clicks the button.
Do not repeat yourself.
Do not write for yourself to only read but for others, so comment your code.
Check this answer on the difference between dot notation and square brack notation when it comes to accessing an object property.
eval() is evil and not needed in your code.
Here's how I would do it (hopefully it answers all your questions):
// an object is a better data structure for storing grading scale
var gradingScale = {
'A+': 4,
'A': 4,
'A-': 3.7,
'B+': 3.3,
'B': 3,
'B-': 2.7,
'C+': 2.3,
'C-': 1.7,
'D+': 1.3,
'D': 1,
'D-': 0.7,
'F': 0.0
};
// note in JS, you can reference an element by their ID
// attaching onclick event handler to your button with ID "gpacalc"
gpacalc.onclick = function() {
var totalGradePoints = 0;
var totalCredits = 0;
// easier to just start at 1
for (var i = 1; i <= 6; i++) {
// you can access an object's property using [] notation; useful in this situation
// good idea to normalize your values e.g. trim, uppercase, etc
var grade = document.calcGpaForm['grade' + i].value.trim().toUpperCase();
var credit = document.calcGpaForm['credit' + i].value.trim();
// skip if no grade is entered
if (grade == "") {
break;
}
// check if grade is invalid i.e. not in the grading scale
if (!gradingScale.hasOwnProperty(grade)) {
alert("'" + grade + "' is not a valid letter grade. Course " + i + ".");
return;
// check if credit is empty
} else if (credit == "") {
alert("You left the number of credits blank for Course " + i + ".");
return;
// check if credit is not a number
} else if (isNaN(credit)) {
alert("Enter a valid number of credits for Course " + i + ".");
return;
}
// at this point, the grade and credit should both be valid...
credit = parseInt(credit, 10);
// so let's add them to the tally
totalGradePoints += gradingScale[grade] * credit;
totalCredits += credit;
}
// check if total credits is greater than zero
if (totalCredits == 0) {
alert("Total credits cannot equal zero.");
return;
}
// show total
gpa.value = Math.round((totalGradePoints / totalCredits) * 10) / 10;
}
<form name="calcGpaForm" method="post">
<table>
<tr>
<h4 style="text-align: center">Letter Grade:</h4>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 1:
</th>
<td class="align-left"><input type="text" name="grade1" type="text" id="grade1" size="10"></td>
<td class="margin-left: auto"><input type="text" name="credit1" id="credit1" size="10"></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 2:
</th>
<td class="align-left"><input name="grade2" type="text" id="grade2" size="10"></td>
<td class="align-left"><input type="text" name="credit2" id="credit2" size="10"></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 3:
</th>
<td class="align-left"><input name="grade3" type="text" id="grade3" size="10"></td>
<td class="align-left"><input type="text" name="credit3" id="credit3" size="10"></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 4:
</th>
<td class="align-left"><input name="grade4" type="text" id="grade4" size="10"></td>
<td class="align-left"><input type="text" name="credit4" id="credit4" size="10"></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 5:
</th>
<td class="align-left"><input type="text" name="grade5" id="grade5" size="10"></td>
<td class="align-left"><input type="text" name="credit5" id="credit5" size="10"></td>
</tr>
<tr>
<th class="right-align">
<span style="color:#cc0000;"></span>Course 6:
</th>
<td class="align-left"><input type="text" name="grade6" id="grade6" size="10"></td>
<td class="align-left"><input type="text" name="credit6" id="credit6" size="10"></td>
</tr>
<tr>
<td class="right-align">
<input type="button" value="Calculate GPA" id="gpacalc">
</td>
<td class="align-left">
<input name="Reset" type="reset">
</td>
</tr>
<tr>
<td class="right-align">
<span style="font-weight:bolder;">GPA:</span>
</td>
<td><input type="text" id="gpa" value="" size="10"></td>
</tr>
</table>
</form>
(Note: the sample attaches an onclick event handler to your button in the JS and not by using an onclick attribute. Though, the latter way should work.)

Calculating 0% Interest?

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.

JavaScript - Traversing the HTML DOM using childNodes causes errors in Non IE browsers

I have the following table being rendered in my browser. It's generated from the server side.
<table id="tblQuestions" class="tblQuestionsContainer" border="0">
<tr>
<td id="1" class="tdQuestion">Are u an indian citizen ?</td>
</tr><tr>
<td><table id="answer-1" border="0">
<tr>
<td><input id="answer-1_0" type="radio" name="answer-1" value="1" /><label for="answer-1_0">Yes</label></td><td><input id="answer-1_1" type="radio" name="answer-1" value="0" /><label for="answer-1_1">No</label></td>
</tr>
</table></td>
</tr><tr>
<td id="2" class="tdQuestion">Do you have a passport ?</td>
</tr><tr>
<td><table id="answer-2" border="0">
<tr>
<td><input id="answer-2_0" type="radio" name="answer-2" value="1" /><label for="answer-2_0">Yes</label></td><td><input id="answer-2_1" type="radio" name="answer-2" value="0" /><label for="answer-2_1">No</label></td>
</tr>
</table></td>
</tr>
</table>
Now I am using the following code in my JavaScript to validate the radio button's checked state.
var tblQuestionBoard=document.getElementById("tblQuestions");
tblAnswer = tblQuestionBoard.rows[1].childNodes[0].childNodes[0]
Now tblAnswer should be an object having the Table with id "answer-1"
In IE, I am getting it. But in Mozilla and rest of the browsers I am getting it as undefined.
How to solve this?
It's because you're using childNodes and whitespaces in the DOM are considered to be text nodes by Firefox et. al but not IE
See this answer for an explanation
My suggestions
1.Set up some wrapper functions that ignore any nodeType other than 1 (ELEMENT_NODE) to do DOM traversing. Something like
function child(elem, index) {
// if index is not supplied, default is 1
// you might be more comfortable making this 0-based
// in which case change i initial assignment value to 0 too
index = index || 1;
// get first child element node of elem
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
// use the index to move to nth-child element node
for(var i=1; i < index;i++) {
(function() {
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
and use like so - Working Demo - (Code at the bottom of the answer for reference)
<table id="myTable">
<thead>
...
</thead>
<tbody>
...
</tbody>
</table>
<script type="text/javascript">
child(document.getElementById('myTable'), 2); // will get the tbody
</script>
2.Use getElementbyId(), getElementsByTagName() or getElementsByName() instead of relying on position in the DOM
3.Use a JavaScript library that abstracts away browser differences (jQuery comes highly recommended)
The Demo Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
window.onload = function() {
document.getElementById('getCellContents').onclick = getCellContents;
}
function child(elem, index) {
index = index || 1;
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
for(var i=1; i < index;i++) {
(function() {
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function getCellContents() {
var row = parseInt(document.getElementById('row').value, 10);
var column = parseInt(document.getElementById('column').value, 10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for (var i= 0; i < cells.length; i++) {
(function() {
cells[i].bgColor = '#ffffff';
})();
}
if (row && column) {
var tbody = child(table , 2);
var selectedRow = (row <= tbody.getElementsByTagName("tr").length)? child(tbody, row): null;
var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)? child(selectedRow, column): null;
if (selectedRow && selectedCell) {
selectedCell.bgColor = '#00ff00';
result = selectedCell.innerHTML;
color = '#b7b7b7';
}
else {
result = 'Cell does not exist';
color = '#ff0000';
}
}
else {
result = 'You must provide numeric arguments for Row and Column Number';
color = '#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}
</script>
<title>DOM Traversal</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
font-family: Verdana, Helvetica, Arial;
font-size: 0.8em;
}
h2 {
text-align:center;
}
table {
border: 1px solid #000;
border-collapse: collapse;
}
th, td {
border: 1px solid #000;
padding: 2px;
}
fieldset {
border: 0;
}
label {
display: block;
width: 120px;
text-align: right;
float: left;
padding-right: 10px;
margin: 5px 0;
}
input {
margin: 5px 0;
}
input.text {
padding: 0 0 0 3px;
width: 172px;
}
input.button {
margin: 15px 0 0 130px;
}
span {
font-weight: bold;
color: #b7b7b7;
}
</style>
</head>
<body>
<h2>Example to demonstrate use of JavaScript DOM traversing wrapper functions</h2>
<div style="margin: 0 auto; width: 600px;">
<fieldset>
<label for="row">Row Number:</label><input id="row" class="text" type="text" /><br/>
<label for="column">Column Number:</label><input id="column" class="text" type="text" /><br/>
<input id="getCellContents" type="button" class="button" value="Get Cell Contents" />
</fieldset>
<p>Results: <span id="results"></span></p>
<table id="table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
<th>Column 5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Banana</td>
<td>Apple</td>
<td>Orange</td>
<td>Pineapple</td>
<td>Cranberry</td>
</tr>
<tr>
<td>Monkey</td>
<td>Giraffe</td>
<td>Elephant</td>
<td>Tiger</td>
<td>Snake</td>
</tr>
<tr>
<td>C#</td>
<td>Java</td>
<td>Python</td>
<td>Ruby</td>
<td>Haskell</td>
</tr>
<tr>
<td>France</td>
<td>Spain</td>
<td>Italy</td>
<td>Germany</td>
<td>Netherlands</td>
</tr>
</tbody>
</table>
<p style="font-weight:bold;">The Code:
<pre><code>
<script type="text/javascript">
window.onload = function() {
document.getElementById('getCellContents').onclick = getCellContents;
}
function child(elem, index) {
index = index || 1;
elem = (elem.firstChild && elem.firstChild.nodeType != 1) ?
next(elem.firstChild) :
elem.firstChild;
for(var i=1; i < index;i++) {
(function() {
if(elem)
return elem = next(elem);
})();
}
return elem;
}
function next(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
function getCellContents() {
var row = parseInt(document.getElementById('row').value, 10);
var column = parseInt(document.getElementById('column').value, 10);
var result;
var color;
var table = document.getElementById('table');
var cells = table.getElementsByTagName('td');
for (var i= 0; i < cells.length; i++) {
(function() {
cells[i].bgColor = '#ffffff';
})();
}
if (row && column) {
var tbody = child(table , 2);
var selectedRow = (row <= tbody.getElementsByTagName("tr").length)?
child(tbody, row): null;
var selectedCell = (selectedRow && column <= selectedRow.getElementsByTagName("td").length)?
child(selectedRow, column): null;
if (selectedRow && selectedCell) {
selectedCell.bgColor = '#00ff00';
result = selectedCell.innerHTML;
color = '#b7b7b7';
}
else {
result = 'Cell does not exist';
color = '#ff0000';
}
}
else {
result = 'You must provide numeric arguments for Row and Column Number';
color = '#ff0000';
}
var results = document.getElementById('results');
results.innerHTML = result;
results.style.color = color;
}
</script>
</code>
</pre>
</p>
</div>
</body>
</html>

Categories