Using <label> <input> <br> in for loop - javascript

I'd like to ask on how to add label, input, and br in for loop please. I'm trying to create an application to calculate score/GPA with for loop. Basically, if I enter 4 then 4 boxes of test scores will show up for me to enter (the default value is 150) - and the maximum I can go is 5.
I'm having problem putting label, input, and br in the for loop - the code is fine and it ran, but you obviously see that I'm not using label, input, and br tags.
How may I add these in please?
For example, if I enter 3 in the number of exams, then setupInputBox() will generate three label, three input and three br elements.
I attached my codes below.
Thank you so much!
// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
return document.getElementById(id);
};
var numInputs = 1; //default setting, showing one test score input box
//define setupInputBox function to add more test score inputs boxes
var setupInputBox = function() {
$('testInputs').innerHTML = "";
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
numInputs = $('numscores').value;
numInputs = parseInt(numInputs);
// convert inputs into integer numerical value
//step-1.1: Add a condition in if() statement
//if user input for number of test scores is valid and in the range 1 to 5
if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
var mainDiv = document.getElementById("testInputs");
for (var i = 0; i < numInputs; i++) {
//Step-1.2.1: create new <label>, <input>, and <br> elements (use createElement() method)
var lbl = document.createElement('label');
var inp = document.createElement("input");
var br = document.createElement("br");
//Step-1.2.2: create text content node for each new <label> element ( use createTextNode() method )
lbl.append(document.createTextNode("Test-" + (i + 1)));
//Step-1.3.1: add for attribute to each new <label> element ( use setAttribute() method)
lbl.setAttribute("for", "score" + (i + 1));
//Step-1.3.2: add id, type, and value attributes to new <input> elements ( use setAttribute() method)
inp.setAttribute("id", "score" + (i + 1));
inp.setAttribute("value", "150");
inp.setAttribute("type", "number");
//Step-1.4: append each new <label>, <input>, and <br> elements to the <div> element with id=”testInputs”.
mainDiv.append(lbl, inp, br);
}
}
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;
//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and
//determine the final letter grade. Display all results on web page.
var processEntries = function() {
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
var score = []; //define an array to hold test scores
var message = ""; //define a variable for containing and displaying error message
var totalscore = 0,
avgScore, finalScore;
var isValid = true;
for (var i = 0; i < numInputs; i++) //
{
$("score" + (i + 1)).className = "";
//step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
var test = document.getElementById("score" + (i + 1));
var testScore = parseFloat(test.value);
//step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
//between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
//if a test score is valid, add that test score to the score array.
score.push(testScore);
} else {
isValid = false;
//if a test score is invalid, generate error message, and add that error messge to message string.
message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
test.setAttribute("class", "error");
}
}
console.log(score); //print out score array in console
console.log(message); //print out message string in console
if (isValid) {
//step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
//final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
for (var j = 0; j < numInputs; j++) {
totalscore += score[j];
}
totalscore = totalscore.toFixed(1);
avgScore = totalscore / numInputs;
avgScore = avgScore.toFixed(1);
var scoreTotal = document.getElementById('scoreTotal');
scoreTotal.value = totalscore.toString();
var scoreAvg = document.getElementById('scoreAvg');
scoreAvg.value = avgScore.toString();
avgScore = parseFloat(avgScore);
if (avgScore <= 150 && avgScore >= 120)
finalScore = "A";
else if (avgScore < 120 && avgScore >= 100)
finalScore = "B";
else if (avgScore < 100 && avgScore >= 80)
finalScore = "C";
else if (avgScore < 80 && avgScore >= 60)
finalScore = "D";
else if (avgScore < 60)
finalScore = "F";
var scoreFinal = document.getElementById("scoreFinal")
scoreFinal.value = finalScore
} else {
//If not all inputted test scores are valid, then create an alert box to display an error message
alert(message);
}
}; //end of processEntries function
//each time when calculate button is clicked, inputted test scores will be evaluated and
$("calculate").onclick = function() {
if (numInputs > 0 && numInputs < 6)
processEntries();
};
$("numscores").focus();
#import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 60%;
min-width: 600px;
border: 3px solid blue;
padding: 0 1em .5em;
}
h1 {
color: blue;
margin: .5em 0;
}
#teacher {
float: right;
margin: 0px 30px 0px 0px;
}
label {
float: left;
width: 10em;
text-align: right;
margin-bottom: .5em;
}
input {
width: 5em;
margin-left: 1em;
margin-bottom: .5em;
}
input.error {
background-color: yellow;
}
#s1 {
display: inline-block;
}
#s1 input {
vertical-align: center;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Score App</title>
<link rel="stylesheet" href="score.css">
</head>
<body>
<main>
<h2>The Test Scores App</h2>
<img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">
<div id="s1">
<label for="numscores">How many tests you want to consider?</label>
<input type='number' id='numscores' min='1' max='10' value='1'>
</div>
<div id="testInputs">
<label for="score1">Test-1:</label>
<input type='number' id='score1' value='150' /><br>
</div>
<div id='result'>
<label for="scoreTotal">Total Points:</label>
<input type="number" id="scoreTotal" disabled><br>
<label for="scoreAvg">Avg Grade:</label>
<input type="number" id="scoreAvg" disabled><br>
<label for="scoreFinal">Final Letter Grade:</label>
<input type="text" id="scoreFinal" disabled><br>
<label> </label>
<input type="button" id="calculate" value="Calculate">
</div>
</main>
<script src="testScoreV2.js">
</script>
</body>
</html>

Use a template literal and you can make this a lot simpler
// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
return document.getElementById(id);
};
var numInputs = 1; //default setting, showing one test score input box
//define setupInputBox function to add more test score inputs boxes
var setupInputBox = function() {
$('testInputs').innerHTML = "";
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
//string to hold our new html
let newHTML = "";
numInputs = $('numscores').value;
numInputs = parseInt(numInputs);
// convert inputs into integer numerical value
//step-1.1: Add a condition in if() statement
//if user input for number of test scores is valid and in the range 1 to 5
if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
var mainDiv = document.getElementById("testInputs");
for (var i = 0; i < numInputs; i++) {
//Create new html using template literal
newHTML += `<label for='score${i+1}'>Test - ${i+1}</label><input type='number' value='150' id='score${i+1}'><br>`;
}
//Update the div
mainDiv.innerHTML += newHTML;
}
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;
//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and
//determine the final letter grade. Display all results on web page.
var processEntries = function() {
$('scoreTotal').value = "";
$('scoreAvg').value = "";
$('scoreFinal').value = "";
var score = []; //define an array to hold test scores
var message = ""; //define a variable for containing and displaying error message
var totalscore = 0,
avgScore, finalScore;
var isValid = true;
for (var i = 0; i < numInputs; i++) //
{
$("score" + (i + 1)).className = "";
//step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
var test = document.getElementById("score" + (i + 1));
var testScore = parseFloat(test.value);
//step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
//between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
//if a test score is valid, add that test score to the score array.
score.push(testScore);
} else {
isValid = false;
//if a test score is invalid, generate error message, and add that error messge to message string.
message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
test.setAttribute("class", "error");
}
}
console.log(score); //print out score array in console
console.log(message); //print out message string in console
if (isValid) {
//step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
//final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
for (var j = 0; j < numInputs; j++) {
totalscore += score[j];
}
totalscore = totalscore.toFixed(1);
avgScore = totalscore / numInputs;
avgScore = avgScore.toFixed(1);
var scoreTotal = document.getElementById('scoreTotal');
scoreTotal.value = totalscore.toString();
var scoreAvg = document.getElementById('scoreAvg');
scoreAvg.value = avgScore.toString();
avgScore = parseFloat(avgScore);
if (avgScore <= 150 && avgScore >= 120)
finalScore = "A";
else if (avgScore < 120 && avgScore >= 100)
finalScore = "B";
else if (avgScore < 100 && avgScore >= 80)
finalScore = "C";
else if (avgScore < 80 && avgScore >= 60)
finalScore = "D";
else if (avgScore < 60)
finalScore = "F";
var scoreFinal = document.getElementById("scoreFinal")
scoreFinal.value = finalScore
} else {
//If not all inputted test scores are valid, then create an alert box to display an error message
alert(message);
}
}; //end of processEntries function
//each time when calculate button is clicked, inputted test scores will be evaluated and
$("calculate").onclick = function() {
if (numInputs > 0 && numInputs < 6)
processEntries();
};
$("numscores").focus();
#import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
background-color: white;
margin: 0 auto;
width: 60%;
min-width: 600px;
border: 3px solid blue;
padding: 0 1em .5em;
}
h1 {
color: blue;
margin: .5em 0;
}
#teacher {
float: right;
margin: 0px 30px 0px 0px;
}
label {
float: left;
width: 10em;
text-align: right;
margin-bottom: .5em;
}
input {
width: 5em;
margin-left: 1em;
margin-bottom: .5em;
}
input.error {
background-color: yellow;
}
#s1 {
display: inline-block;
}
#s1 input {
vertical-align: center;
float: left;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Test Score App</title>
<link rel="stylesheet" href="score.css">
</head>
<body>
<main>
<h2>The Test Scores App</h2>
<img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">
<div id="s1">
<label for="numscores">How many tests you want to consider?</label>
<input type='number' id='numscores' min='1' max='10' value='1'>
</div>
<div id="testInputs">
<label for="score1">Test-1:</label>
<input type='number' id='score1' value='150' /><br>
</div>
<div id='result'>
<label for="scoreTotal">Total Points:</label>
<input type="number" id="scoreTotal" disabled><br>
<label for="scoreAvg">Avg Grade:</label>
<input type="number" id="scoreAvg" disabled><br>
<label for="scoreFinal">Final Letter Grade:</label>
<input type="text" id="scoreFinal" disabled><br>
<label> </label>
<input type="button" id="calculate" value="Calculate">
</div>
</main>
<script src="testScoreV2.js">
</script>
</body>
</html>

Related

Create triangle and square pattern with input js

I started creating a program in where an input from a user is needed, then, depending on the input, will display either a right triangle or square (triangle for even, square for odd) The pattern will be in descending order starting from the input number. However, my code does not yield any output.
Output:
triangle (3 is the input number)
3 3 3
2 2
1
square (3 is the input number)
3 3 3
2 2 2
1 1 1
Is there something missing in my code? Thanks
<!DOCTYPE html>
<html lang="en">
<head>
<style>
</style>
<script>
function myFunction() {
var number;
console.info("Number:" + number);
if (number %2 == 0) {
var line = document.getElementById("list")
for (let n = 1; n <= number; --i) {
let line = "";
for (let r = 1; r <= n; ++j) {
line += (j + " ");
}
document.getElementById("line");
}
} else {
var line = document.getElementById("list")
for (let n = 1; n <= number; i++) {
let line = "";
for (let r = 1; r <= number; j++) {
line += (j + " ");
}
document.getElementById("line");
}
}
}
</script>
</head>
<body>
</br>
Enter the number : <input id="number" type="number"/>
<br />
<button onclick="myFunction()">Print</button>
<div id="line">
</body>
</html>
you have some errors over your code , first you don't see any content because you never create a dom element and append to html ,then you don't read the value of the input, your loops have a some errors of undefined variables,and put always your js script at the end of the body, because you need to all html elements be rendered before your js be executed for dont have undefined value when you do you document.getElementById, i made a full example with a new code that achieve the goals , just read it and you will notice the difference and the errors that you have , peace dog!
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.clear {
clear: both;
}
.float-left {
float: left;
height: 20px;
width: 20px;
vertical-align: middle;
line-height: 20px;
text-align: center;
border: 1px solid green;
}
.triangle {
-moz-transform: skew(45deg);
-webkit-transform: skew(45deg);
transform: skew(45deg);
}
</style>
</head>
<body>
</br>
Enter the number : <input id="number" type="number" />
<br />
<button onclick="init()">Print</button>
<div id="figure">
</div>
<script>
let figureContainer = document.getElementById('figure');
function drawLine(number, lengthOfLine, typeOfFigure) {
for (let i = 0; i < lengthOfLine; i++) {
let numberIOfLine = document.createElement("div");
numberIOfLine.innerHTML = number;
if (typeOfFigure === "triangle") {
numberIOfLine.className = "float-left ";
} else {
numberIOfLine.className = "float-left";
}
figureContainer.appendChild(numberIOfLine);
}
let clearLine = document.createElement("div");
clearLine.className = "clear";
figureContainer.appendChild(clearLine);
}
function drawSquare(number) {
for (let i = 0; i < number; i++) {
drawLine(number - i, number, "square");
}
}
function drawTriangle(number) {
for (let i = 0; i < number; i++) {
drawLine(number - i, number - i, "triangle");
}
}
function init() {
figureContainer.innerHTML = "";
let number = document.getElementById("number").value;
if (number % 2 === 0) {
drawSquare(number);
} else {
drawTriangle(number);
}
}
</script>
</body>
</html>

Why does a variable with .substring() not reflect css styling?

Using pure javascript, I am trying to create a price-validating function that when used, validates prices entered into a form. There are 4 requirements to my validation:
Input must be a number and cannot be empty
If a decimal is entered, there must at least be 1 pre- and post-decimal character
Price entered must be a number that is between $1 and $99.99 (both inclusive)
Price entered must not have whitespaces in between
and here is my code:
function formCheck() {
var success = true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById('divMessage'); //feedback div
//Price Variables
var movPrice = document.getElementById('txtPrice');
var priceFdBk1 = '<ul><li> Please enter <b>numbers</b> only. </li></ul>';
var priceFdBk2 =
'<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>';
var priceFdBk3 = '<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>';
var priceFdBk4 = '<ul><li> Please do not leave a space when entering the movie price. </li></ul>';
//Price Validation
function priceCheck(price, fdBk1, fdBk2, fdBk3, fdBk4) {
//arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
var price_len = price_clean.length; //number of characters in price entered
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor == '$') {
price_clean = price_clean.substring(1);
}
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.') > -1) {
var deciSensor = 1; //remember that input has a decimal
var intValue = price_clean.split('.')[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split('.')[1]; //obtain post-decimal characters
var postCounter = 0;
for (var j = 0; j < decimalValue.length; j++) {
//count number of decimal places
postCounter += 1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean) || price_clean == '') {
msgBox.innerHTML = fdBk1;
price.className = 'yellow';
success = false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if ((deciSensor == 1 && intValue == '') || (deciSensor == 1 && decimalValue == '')) {
//if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className = 'yellow';
success = false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean < 1 || price_clean > 99.99 || postCounter > 2) {
msgBox.innerHTML = fdBk3; //message in feedback div
price.className = 'yellow';
success = false; //prevent loading of "process.html" since selected movie is invalid
} else {
price.className = 'transparent';
}
//Filter 4: Price entered must not have whitespaces in between
for (var i = 0; i < price_len; i++) {
oneDigit = price_clean.charAt(i);
if (oneDigit == ' ') {
//if the price float character has a whitespace
msgBox.innerHTML = fdBk4; //message in feedback div
price.className = 'yellow'; //highlight error in client's input
success = false; //prevent loading of "process.html" since selected movie is invalid
} else if (oneDigit == '') {
//if the price float character has no whitespace
price.className = 'transparent'; //remove highlight from client's input
}
}
}
priceCheck(movPrice, priceFdBk1, priceFdBk2, priceFdBk3, priceFdBk4);
return success;
}
.yellow {
background-color: yellow;
}
.transparent {
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
The code works fine but has 1 issue, which I suspect comes from this line:
price_clean = price_clean.substring(1)
Specifically, whenever I enter a "$" sign into the form, my code will remove the "$" sign and validate the input as usual. However, when the input is invalid, it no longer highlights the input box in yellow.
May I know what is going on and how can this be fixed using vanilla javascript? Thank you
Your issue is that you're adding the yellow highlight, but then removing it in your final for loop, this is due to your final for loop using price_len, which is calculated before you remove the $. As a result, your for loop is doing one additional iteration, and so .charAt(i) tries to access an index not in your string giving you an empty string. To fix this, you can calculate the length after you've removed the additional $:
function formCheck() {
var success = true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById('divMessage'); //feedback div
//Price Variables
var movPrice = document.getElementById('txtPrice');
var priceFdBk1 = '<ul><li> Please enter <b>numbers</b> only. </li></ul>';
var priceFdBk2 =
'<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>';
var priceFdBk3 = '<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>';
var priceFdBk4 = '<ul><li> Please do not leave a space when entering the movie price. </li></ul>';
//Price Validation
function priceCheck(price, fdBk1, fdBk2, fdBk3, fdBk4) {
//arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor == '$') {
price_clean = price_clean.substring(1);
}
var price_len = price_clean.length; //number of characters in price entered
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.') > -1) {
var deciSensor = 1; //remember that input has a decimal
var intValue = price_clean.split('.')[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split('.')[1]; //obtain post-decimal characters
var postCounter = 0;
for (var j = 0; j < decimalValue.length; j++) {
//count number of decimal places
postCounter += 1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean) || price_clean == '') {
msgBox.innerHTML = fdBk1;
price.className = 'yellow';
success = false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if ((deciSensor == 1 && intValue == '') || (deciSensor == 1 && decimalValue == '')) {
//if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className = 'yellow';
success = false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean < 1 || price_clean > 99.99 || postCounter > 2) {
msgBox.innerHTML = fdBk3; //message in feedback div
price.className = 'yellow';
success = false; //prevent loading of "process.html" since selected movie is invalid
} else {
price.className = 'transparent';
}
//Filter 4: Price entered must not have whitespaces in between
for (var i = 0; i < price_len; i++) {
oneDigit = price_clean.charAt(i);
if (oneDigit == ' ') {
//if the price float character has a whitespace
msgBox.innerHTML = fdBk4; //message in feedback div
price.className = 'yellow'; //highlight error in client's input
success = false; //prevent loading of "process.html" since selected movie is invalid
} else if (oneDigit == '') {
//if the price float character has no whitespace
price.className = 'transparent'; //remove highlight from client's input
}
}
}
priceCheck(movPrice, priceFdBk1, priceFdBk2, priceFdBk3, priceFdBk4);
return success;
}
.yellow {
background-color: yellow;
}
.transparent {
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
There are however a few improvements you can consider making to your code though:
Use const or let instead of var (to help with minimizing scoping issues)
Update your code to use classList.toggle() to remove/add your highlight class
Consider using regular expressions or HTML5 validation with custom validation messages using setCustomValidity()
Use DOM2 event hanlders by using .addEventListener() with e.preventDefault() instead of DOM0 (onxyz) HTML attributes
A small fix to your code, you've set price_len before removing leading $
const price_len = price_clean.length;
for(var i=0; i<price_len; i++){
...
}
<html>
<head>
<style>
.yellow{
background-color:yellow
}
.transparent{
background-color: transparent;
}
h1 {
color: #7157ff;
}
hr {
display: block;
border: 0;
border-top: 3px solid #f90;
padding: 0;
}
textarea {
width: 70%;
}
#div_main {
font-family: Sans-serif;
margin: auto;
margin-top: 30px;
width: 500px;
}
#div_left {
width: 150px;
display: inline-block;
float: left;
}
#div_left p {
margin-bottom: 19px;
}
#div_right {
width: 350px;
display: inline-block;
float: right;
}
.clear {
clear: both;
}
</style>
<script language="javascript">
function formCheck(){
var success=true; //default, assumes client enters all fields correctly so "process.html" will load
var msgBox = document.getElementById("divMessage"); //feedback div
//Price Variables
var movPrice = document.getElementById("txtPrice");
var priceFdBk1 = "<ul><li> Please enter <b>numbers</b> only. </li></ul>"
var priceFdBk2 = "<ul><li> You entered a decimal point. Please enter a <b>number</b> both before and after the decimal place. </li></ul>"
var priceFdBk3 = "<ul><li> Please enter a movie price between $1.00 to $99.99 (up to 2 decimal places). </li></ul>"
var priceFdBk4 = "<ul><li> Please do not leave a space when entering the movie price. </li></ul>"
//Price Validation
function priceCheck(price,fdBk1,fdBk2,fdBk3,fdBk4){ //arguments = price and feedbacks if errors are made
var price_clean = price.value.trim(); //price entered by client without whitespace
//var price_len = price_clean.length; //number of characters in price entered
//If there is a $ sign, remove it first
var dollarSensor = price_clean.charAt(0);
if (dollarSensor=="$"){
price_clean = price_clean.substring(1);
}
//If there is a decimal point, obtain pre- and post-decimal characters
if (price_clean.indexOf('.')>-1){
var deciSensor=1 //remember that input has a decimal
var intValue = price_clean.split(".")[0]; //obtain pre-decimal characters)
var decimalValue = price_clean.split(".")[1]; //obtain post-decimal characters
var postCounter=0
for (var j=0;j<decimalValue.length;j++){ //count number of decimal places
postCounter+=1;
}
}
//Filter 1: Input must be a number and cannot be empty
if (isNaN(price_clean)||price_clean==""){
msgBox.innerHTML = fdBk1;
price.className="yellow";
success=false;
}
//Filter 2: If a decimal is entered, there must at least be 1 pre- and post-decimal character
else if (deciSensor==1 && intValue==""||deciSensor==1 && decimalValue==""){ //if client did not enter a number before and after the decimal point
msgBox.innerHTML = fdBk2;
price.className="yellow";
success=false;
}
//Filter 3: Price entered must be a number that is between $1 and $99.99 (both inclusive)
else if (price_clean<1||price_clean>99.99||postCounter>2){
msgBox.innerHTML = fdBk3; //message in feedback div
price.className="yellow";
success=false; //prevent loading of "process.html" since selected movie is invalid
}
else{
price.className="transparent";
}
//Filter 4: Price entered must not have whitespaces in between
const price_len = price_clean.length;
for(var i=0; i<price_len; i++){
oneDigit = price_clean.charAt(i);
if (oneDigit==" "){ //if the price float character has a whitespace
msgBox.innerHTML= fdBk4; //message in feedback div
price.className="yellow"; //highlight error in client's input
success=false; //prevent loading of "process.html" since selected movie is invalid
}
else if (oneDigit==""){ //if the price float character has no whitespace
price.className="transparent"; //remove highlight from client's input
}
}
}
priceCheck(movPrice,priceFdBk1,priceFdBk2,priceFdBk3,priceFdBk4)
return success;
}
</script>
</head>
<body>
<div id="div_main">
<h1>
Add Movie
</h1>
<hr>
<form action="process.html" method="POST">
<div id="div_left">
<p>Price* ($):</p>
</div>
<div id="div_right">
<p><input type="text" id="txtPrice" name="txtPrice"></p>
</div>
<input type="submit" id="btnSubmit" onclick="return formCheck()">
</form>
<div id="divMessage">
*denotes compulsary fields.
</div>
</div>
</body>
</html>

How can I store and show data in array at the same time?

I want to make a simple guessing game by JavaScript. I want to make a guessing game where people can guess number against of random number. each time after guessing, it will store the result in a array, and show on right side of previous history.
//here is the JS file
var a=[10];
let x=0;
function check()
{
var num=Math.floor(Math.random()*5);
var a= document.getElementById("inpt").value;
if (num==a)
{
document.querySelector("#result").innerHTML="You are right in guess";
a[x]=true;
}
else {
document.querySelector("#result").innerHTML="You are Wrong in guess";
a[x]=false;
}}
if (a[x]==true)
{
document.getElementById("finalize").innerHTML=x+1+": number turn is right";
}
else{
document.getElementById("finalize").innerHTML=x+1+": number turn is wrong";
}
<!-- Here is the HTML file -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My gussing game</title>
<script src="index.js"></script>
</head>
<body>
<div style="width: 45%; float: left; background: gold; margin: 2px; text-align: center;">
<H1>Game Input</H1>
<hr>
<input type="number" id="inpt" placeholder="Guess the number">
<br>
<button onclick="check()">Submit</button>
<p id="result"></p>
</div>
<div style="width: 45%; float: left; background: rgb(42, 204, 177); margin: 2px; text-align: center;">
<h1>Game Result</h1>
<hr>
<p id="finalize"></p>
</div>
</body>
</html>
I can not understand why my code is not running!! can you please brief all the thing me?
you redeclare var a in check function, so assignment a[x] is for local var
If you format your code you will see that the field you want to update is outside of the check function:
var a = [10];
let x = 0;
function check() {
var num = Math.floor(Math.random() * 5);
var a = document.getElementById("inpt").value;
if (num == a) {
document.querySelector("#result").innerHTML = "You are right in guess";
a[x] = true;
}
else {
document.querySelector("#result").innerHTML = "You are Wrong in guess";
a[x] = false;
}
}
if (a[x] == true) {
document.getElementById("finalize").innerHTML = x + 1 + ": number turn is right";
}
else {
document.getElementById("finalize").innerHTML = x + 1 + ": number turn is wrong";
}
To perform that action everytime you submit a guess you need to move those fields inside of that function:
var a = [10];
let x = 0;
function check() {
var num = Math.floor(Math.random() * 5);
var a = document.getElementById("inpt").value;
if (num == a) {
document.querySelector("#result").innerHTML = "You are right in guess";
a[x] = true;
}
else {
document.querySelector("#result").innerHTML = "You are Wrong in guess";
a[x] = false;
}
if (a[x] == true) {
document.getElementById("finalize").innerHTML = x + 1 + ": number turn is right";
}
else {
document.getElementById("finalize").innerHTML = x + 1 + ": number turn is wrong";
}
}
Is this the sort of behaviour you want? (If it is then I will make comments in the code to explain)
Demo:
//here is the JS file
//array to hold each guess:
var guesses = [];
//number to hold current guess number (could also use guesses.length):
let x = 0;
//random number rounded to a whole number:
var num = Math.round(Math.floor(Math.random()*5),0);
function check(){
//for testing output the random num:
console.log(num)
if (x == 0){
//rest our message log div:
document.getElementById("finalize").innerHTML = ""
}
//get the current guess:
var a = document.getElementById("inpt").value;
//if guess equals random num:
if (num==a){
document.querySelector("#result").innerHTML="You are right in guess";
//push the current guess onto the guesses array:
guesses.push(a);
//update the div (<div id="guessArr"></div>) to hold a stringified representation
//of our array, such as ["1", "2", "3"] if the user guesses 1, then 2, then 3:
document.querySelector("#guessArr").innerHTML = JSON.stringify(guesses);
//create a p tag (<p></p>) to store our message
var p = document.createElement('p')
//add the message to that p tag:
p.innerHTML = x+1+": number turn is right"
//append it to the div:
document.getElementById("finalize").appendChild(p)
//reset our guess number/count:
x = 0;
//reset our guesses array:
guesses = [];
//reset our input field:
document.getElementById("inpt").value = "";
//generate a new random number to guess:
num = Math.round(Math.floor(Math.random()*5),0);
}
//if guess was incorrect:
else {
document.querySelector("#result").innerHTML="You are Wrong in guess";
//push the current guess onto the guesses array:
guesses.push(a);
//update the div (<div id="guessArr"></div>) to hold a stringified representation
//of our array, such as ["1", "2", "3"] if the user guesses 1, then 2, then 3:
document.querySelector("#guessArr").innerHTML = JSON.stringify(guesses);
//create a p tag (<p></p>) to store our message
var p = document.createElement('p')
//add the message to that p tag:
p.innerHTML = x+1+": number turn is wrong"
//append it to the div:
document.getElementById("finalize").appendChild(p)
//add one to our guess number/count:
x += 1;
}
}
<!-- Here is the HTML file -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My gussing game</title>
<script src="index.js"></script>
</head>
<body>
<div style="width: 45%; float: left; background: gold; margin: 2px; text-align: center;">
<H1>Game Input</H1>
<hr>
<input type="number" id="inpt" placeholder="Guess the number">
<br>
<button onclick="check()">Submit</button>
<p id="result"></p>
</div>
<div style="width: 45%; float: left; background: rgb(42, 204, 177); margin: 2px; text-align: center;">
<h1>Game Result</h1>
<hr>
<div id="guessArr"></div>
<div id="finalize">
</div>
</div>
</body>
</html>

How to fix a switch from going to default

My problem is that for some reason the average of the grade does not run through the switch and i believe goes straight to default. How can i fix this little problem. must be a switch statement!
My input for grades is 76,99,85,88,83.
My guess is because my average is a 86.2? so like the decimal? I have tried to add a .0 at the end like i did for my if/ifelse and that seem to work.
<head>
<style>
hr {
background-color: black;
margin: 2px auto;
width: 100%;
height: 2px;
}
.container{
width: 500px;
padding: 15px;
background-color: #D3D3D3;
box-shadow: 10px 10px 5px 0px #8c878c;
}
body {
background-color: #EEE8AA;
}
form { display: table; }
p { display: table-row; }
label { display: table-cell; }
input { display: table-cell; }
</style>
</head>
<body>
<form name="gradecal">
<div class="container">
<p>
<label for="a">First Name: </label>
<input type="text" name="fname"/>
</p>
<p>
<label for="a">Last Name: </label>
<input type="text" name="lname"/>
</p>
<p>
<label for="a">Grade #1: </label>
<input type="text" name="grd1"/>
</p>
<p>
<label for="a">Grade #2: </label>
<input type="text" name="grd2"/>
</p>
<p>
<label for="a">Grade #3: </label>
<input type="text" name="grd3"/>
</p>
<p>
<label for="a">Grade #4: </label>
<input type="text" name="grd4"/>
</p>
<p>
<label for="a">Grade #5: </label>
<input type="text" name="grd5"/>
</p>
<p>
<input type="button" value="Submit" onclick="getGrades();" />
</p>
</div>
</form>
<script>
function getGrades(){
// initialize variables
var fname = 0, lname = 0, grade1 = 0, grade2 = 0, grade3 = 0, grade4 = 0, grade5 = 0, average = 0;
// assigning varables to textbox value
firnam = String(document.gradecal.fname.value);
lasnam = String(document.gradecal.lname.value);
grade1 = Number(document.gradecal.grd1.value);
grade2 = Number(document.gradecal.grd2.value);
grade3 = Number(document.gradecal.grd3.value);
grade4 = Number(document.gradecal.grd4.value);
grade5 = Number(document.gradecal.grd5.value);
// Calculate average
average = (grade1+ grade2+ grade3+ grade4+ grade5) / 5;
// if else to determine what grade falls into percentage wise
var perc = 0;
if (average >= 90 && average <=100){
perc = "100-99.9 %";
document.write(perc);
}
else if (average >= 80 && average <=89.9){
perc = "80-89.9 %";
document.write(perc);
}
else if (average >= 70 && average <=79.9){
perc = "70-79.9 %";
document.write(perc);
}
else if (average >= 60 && average <=69.9){
perc = "60-69.9 %";
document.write(perc);
}
else {
perc = "59.9 % or less";
document.write(perc);
}
// switch to determine the letter grade
var letter = 0;
switch (true){
case (average >= 90 && average <= 100):
letter = "A";
document.write(letter);
break;
case (average >= 80 && average <= 89.9):
letter = "B";
document.write(letter);
break;
case (average >= 70 && average <= 79.9):
letter = "C";
document.write(letter);
break;
case (average >= 60 && average <= 69.9):
letter = "D";
document.write(letter);
break;
default:
letter = "F";
document.write(letter);
break;
}
// display when submit is clicked
document.write('<p>First Name: ' + firnam.toUpperCase());
document.write('<br>Last Name: ' + lasnam.toLowerCase());
document.write('<br>Grade #1: ' + grade1);
document.write('<br>Grade #2: ' + grade2);
document.write('<br>Grade #3: ' + grade3);
document.write('<br>Grade #4: ' + grade4);
document.write('<br>Grade #5: ' + grade5);
document.write('<br>Semester Average: ' + average);
document.write('<hr>Based on your semester average, your grade falls between: ' + perc );
document.write('<br>You have earned a(n): ' + letter + '</p>');
}
</script>
</body>
</html>
expected result is "You have earned a(n): B" the result i am getting is "You have earned a(n): F".(corrected)
Also the perc and letter display in the first line when outputted, how can i only display it once??
The problem is the grade variables are undefined and get typecasted to 0
so the average is always 0, hence the default(else) will be set even if you write an if...else
update the code like below;
if(average >= 90.0)
letter = "A";
else if(average >= 80.0)
letter = "B";
else if(average >= 70.0)
letter = "C";
else if(average >= 60.0)
letter = "D";
else
letter = "F";
document.write('<br>You have earned a(n): ' + letter);
Update
The problem now is that unless the average is "exactly" 90,80,70 or 60, it will always be the "default" and give you F!
Update
Find the solution: https://jsfiddle.net/ur2nvxg4/2/
Again, if you have to use switch ranges, you must have switch(true) and case average >= value in the code for perc I see a potential error when the value is 89.99% from the code. it has also been modified
Some things could help us:
Why don't you console.log the average, and the typeof average?
There may be 2 issues going on here:
1) The grade variables are not getting the value from each of your inputs.
If this is the case, why don't you assign an ID to each input, since they represent a distinct value for each grade.
(If the inputs are dynamically created, you can create an ID for each of them associated with their index).
Lets say that we have :
<label for="a">Grade #1: </label>
<input type="text" name="grd1" id="grade1/>
Now we can get the value by doing:
const grade1 = document.querySelector("#grade1").value;
console.log the value of grade1 to make sure you're getting something back.
Also, you have to convert it to a number, as I believe the value is stored as a string.
2) Type mismatch
If you are getting back correct values for grade, try and console log the typeof each grade, and the average.
What could end up happening is that the average is actually a string, because the grades are treated as a string.

what's wrong with this javascript script.?

I am trying to learn javascript by following this exercise from MDN website Learn JavaScript
here is my final code for the game.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Number guessing game</title>
<style>
html {
font-family: sans-serif;
}
body {
width: 50%;
max-width: 800px;
min-width: 480px;
margin: 0 auto;
}
.lastResult {
color: white;
padding: 3px;
}
</style>
</head>
<body>
<h1>Number guessing game</h1>
<p>We have selected a random number between 1 and 100. See if you can guess it in 10 turns or less. We'll tell you if your guess was too high or too low.</p>
<div class="form">
<label for="guessField">Enter a guess:</label>
<input type="text" id="guessField" class="guessField" autofocus>
<input type="submit" value="Submit guess" class="guessSubmit">
</div>
<div class="resultParas">
<p class="guesses"></p>
<p class="lastResult"></p>
<p class="lowOrHi"></p>
</div>
</body>
<script>
// Your JavaScript goes here
var randomNumber = Math.floor(Math.random() * 100) + 1;
var guesses = document.querySelector(".guesses");
var lastResult = document.querySelector(".lastResult");
var lowOrHi = document.querySelector(".lowOrHi");
var guessField = document.querySelector(".guessField");
var guessSubmit = document.querySelector(".guessSubmit");
var test; //used for creating new reset button
var count = 1; // counter for counting user input
function checkGuess() {
//alert('checkGuess is called');
var value = Number(guessField.value);
if (count === 1) {
guesses.textContent = "Previous guesses :"
}
guesses.textContent += value + ' ';
if (value === randomNumber) {
lastResult.textContent = "congratulation u successfully guessed the number";
lastResult.style.backgroundColor = "green";
lowOrHi.textContent = "";
left = 1;
setGameOver();
} else if (count === 10) {
lastResult.textContent = "game over"
lastResult.style.backgroundColor = "red";
left = 1;
setGameOver();
} else {
lastResult.textContent = "WRONG";
lastResult.style.backgroundColor = "red";
if (value < randomNumber) {
lowOrHi.textContent = "too low";
} else {
lowOrHi.textContent = "too high";
}
}
count++;
guessField.value = '';
}
guessSubmit.addEventListener("click", checkGuess);
function setGameOver() {
guessField.disabled = true;
guessSubmit.disabled = true;
test = document.createElement('button');
test.textContent = "restart game";
document.body.appendChild(test);
test.addEventListener('click', resetGame);
}
function resetGame() {
count = 1;
var resetParas = document.querySelectorAll('.resultParas');
for (var i = 0; i < resetParas.length; i++) {
resetParas[i].textContent = '';
}
guessField.disabled = false;
guessSubmit.disabled = false;
guessField.value = '';
lastResult.style.backgroundColor = 'white';
randomNumber = Math.floor(Math.random() * 100) + 1;
test.parentNode.removeChild(test);
}
</script>
</html>
But when i try to run the game and use the reset game button to restart the game then i am not able to manipulate guesses,lastResult and lowOrHi elements using textContent and backgroundColor properties.
Your blanking out everything inside .resultParas.. And this will include all you <p> tags. IOW: after doing that they have disappeared from the DOM, you can see this say in chrome inspector that .resultPara's after clicking reset game is now blank, and all your p tags have gone.
I think what you really want to do, is blank out the children (the p tags)..
You don't need querySelectorAll either, as in your case there is only the one.
var resetParas = document.querySelector('.resultParas');
for(var i = 0 ; i < resetParas.children.length ; i++) {
resetParas.children[i].textContent = '';
}

Categories

Resources