What I want is, after the user enters the number of subjects, the system will show the number of input box according to the number of subjects entered, then when the user clicks on the button, it should show the sum. I tried many ways, but I failed to show the sum, anyone knows what is the mistake I made?
Below is my code:
function select() {
var x = parseInt(document.getElementById('1').value);
if (document.getElementById('1').value == "") {
alert("Please fill up number of subject");
} else if (isNaN(x) == true) {
alert("Please fill up number of subject with number");
} else {
var subject = parseInt(document.getElementById('1').value);
var sum = 0;
for (var num = 1; num <= subject; num++) {
document.write("Enter the mark for subject " + num + " : ");
var value = parseFloat(document.write("<input/><br>"));
sum += value;
}
var calc = document.write("<button>Next</button><br>");
calc.onclick = function() {
next()
};
function next() {
document.write("Total marks: " + sum + "%");
}
}
}
<html>
<body>
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</body>
</html>
That's how I have rewritten a big part of your code. I have place inline comments to explain what I do.
function select() {
var x = parseInt(document.getElementById('1').value, 10);
// Getting the div that wraps the initial form.
var formWrapper = document.querySelector('.formWrapper');
// Getting the div, that is going to display the new fields and the results.
var results = document.querySelector('.results');
// I have switch your statement from x == '' to '' === x as it
// consists a good practice
if ( '' === x ) {
alert("Please fill up number of subject");
// I have remove the isNaN(x) == true, because the isNan will
// be either true or false.
} else if ( isNaN(x) ) {
alert("Please fill up number of subject with number");
} else {
// Using parseInt(x, 10) to set the base.
var subject = parseInt(x, 10);
// In this array, I store the auto-generated fields.
var fieldsList = [];
// Removing the first div from the DOM
formWrapper.parentElement.removeChild(formWrapper);
for ( var num = 1; num <= subject; num++ ) {
// I am creating a new field
var newField = document.createElement('input');
// I push the field into the array I made for the fields.
fieldsList.push(newField);
// I append the field in the HTML
results.appendChild(newField);
// I create a <br> tag
var br = document.createElement('br');
// And I append the tag in the DOM
results.appendChild(br);
}
// I create the button that is going to handle the Next functionality
var nextButton = document.createElement('button');
// I set the button text
nextButton.innerText = 'Next';
// I add an Event Listener for the click event.
nextButton.addEventListener(
'click',
function() {
// I reset the sum to 0
var sum = 0;
// I itterate the fields auto-generated and saved in the array
fieldsList.forEach(
function(field) {
// I get the value
sum += parseInt(field.value, 10);
}
);
// I create the field that is going to display the output
let resultText = document.createElement('div');
// I set the text based on the sum
resultText.innerText = "Total marks: " + sum + "%";
// I append the text message to the DOM
results.appendChild(resultText);
}
);
// I append the button to the DOM
results.appendChild(nextButton);
}
}
<html>
<body>
<div class="formWrapper">
Enter the number of subject: <input type="text" onkeypress="return/[0-9]/i.test(event.key)" id="1" value=""><br>
<button onclick="select()">Check</button><br>
</div>
<div class="results"></div>
</body>
</html>
Related
I am trying to evaluate when the user inputs nothing (an empty string) or anything besides a number (Not a number). After I console log the an input of empty string a NaN is returned. I am not sure why the else-if statement is never recognized if I test for both an empty string or NaN value. This also ultimately affects my average total score.
const equationTag = document.querySelector('div#equation');
const inputBtn = document.querySelector('input.submit-btn');
const incorrectTag = document.querySelector('p#incorrect');
const correctTag = document.querySelector('p#correct');
const counterTag = document.querySelector('div#counter');
const exitButton = document.querySelector('button.exit-btn');
const displayButton = document.querySelector('button.display-btn');
const resultModal = document.querySelector('section.stats-section');
const averageP = document.querySelector('p.avg');
const guessP = document.querySelector('p.total-guesses');
let points = 0;
let correctGuesses = 0;
let incorrectGuess = 0;
let totalGuesses = 0;
/*
Takes a min and max value as parameters, and
returns a randomized integer
*/
function getRandomValue(min, max) {
let r = Math.floor(Math.random() * (max - min + 1)) + min;
return r;
}
// Displays multiplcation equation on the user interface
function displayEquation() {
equationTag.textContent = `${integerOne} x ${integerTwo}=`;
}
// Returns the product of the two integers
function getProduct() {
return integerOne * integerTwo;
}
/*
Event listener grabs user input on click
and clears user input afterwards
*/
inputBtn.addEventListener('click', () => {
const inputTag = document.querySelector('#num');
const answer = parseFloat(inputTag.value);
evaluateAnswer(answer);
inputTag.value = "";
inputTag.focus();
})
/*
Event listener grabs user input on enter key
and clears user input afterwards
*/
document.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
const inputTag = document.querySelector('#num');
const answer = parseFloat(inputTag.value);
evaluateAnswer(answer);
inputTag.value = "";
inputTag.focus();
}
})
exitButton.addEventListener('click', () => {
setDisplayNone(resultModal);
})
displayButton.addEventListener('click', () => {
setDisplayBlock(resultModal);
})
/*
Takes a integer user input as an argument
and compares whether the answer is correct or not.
*/
function evaluateAnswer(input) {
console.log('Input value on eval ', input); // double checking value
if (input !== getProduct()) {
subtractPoint();
incorrectGuess++;
} else if (input === ' ' || isNaN()) { // I am not sure why it's never evaluated
console.log('Input value is empty or not a number ', input);
} else {
addPoint();
correctGuesses++;
}
totalGuesses++;
restartGame();
guessP.textContent = "Incorrect Guesses= " + incorrectGuess;
let average = (correctGuesses / totalGuesses);
let precisionAvg = roundToPrecision(average, 2);
averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
// console.log('Total guesses: ', totalGuesses);
// console.log('Incorrect ', incorrectGuess);
// console.log("Average: ", average)
}
/*
Evaluates if the points are less
than zero then restart points to 0
else minus a point.
*/
function subtractPoint() {
if (points <= 0) {
points = 0;
} else {
points -= 1;
}
setDisplayBlock(incorrectTag);
setDisplayNone(correctTag);
incorrectTag.textContent = ('Incorrect: ' + integerOne + ' x ' + integerTwo + ' = ' + getProduct());
setPoint();
}
// Sets new updated point
function setPoint() {
counterTag.textContent = points;
}
// Adds a point and updates earned points
function addPoint() {
points += 1;
correctTag.textContent = ('Correct!');
setDisplayBlock(correctTag);
setDisplayNone(incorrectTag);
setPoint();
}
/*
Resets game and gets two new random integers
and calls the displayEquation function.
*/
function restartGame() {
integerOne = getRandomValue(0, 12);
integerTwo = getRandomValue(0, 12);
displayEquation();
}
// sets css display block and opacity 1 on element
function setDisplayBlock(displayResult) {
displayResult.style.display = 'block';
displayResult.style.opacity = 1;
}
// sets css display none and opacity 0 on element
function setDisplayNone(displayResult) {
displayResult.style.display = 'none';
displayResult.style.opacity = 0;
}
/*
Takes a value as a parameter, and integer as a parameter
returns a rounded value with two decimal places at most
https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary/11832950#11832950
*/
function roundToPrecision(value, decimals = 2) {
const pow = Math.pow(10, decimals);
return Math.round((value + Number.EPSILON) * pow) / pow;
}
// run game on load
let integerOne = getRandomValue(0, 12);
let integerTwo = getRandomValue(0, 12);
displayEquation();
<body>
<header>
<h1 id="title">Multiply Me</h1>
</header>
<main>
<div id="equation"></div>
<div id="counter">0</div>
<input type="number" id="num" value="" title="input">
<input type="submit" class="submit-btn">
<button type="submit" class="display-btn" value="Show Results">+</button>
<div id="response">
<p id="correct"></p>
<p id="incorrect"></p>
</div>
<section class="stats-section">
<h3 class="h3-title">Overall Results:</h3>
<button class="exit-btn">x</button>
<article class="article-stats">
<p class="total-guesses"></p>
<p class="avg"></p>
</article>
</section>
</main>
</body>
Several issues apart from not using isNaN correctly
You cannot see if a value is a single space after parseFloating it.
I would suggest
const answer = inputTag.value;
evaluateAnswer(answer);
where you have this. Note the order and that I test the positive outcome before the negative
function evaluateAnswer(input) {
input = input.trim();
if (input === "" || isNaN(input)) {
console.log('Input value is empty or not a number ', input);
return; /* Any need to continue? */
} else if (input === getProduct()) {
addPoint();
correctGuesses++;
} else {
subtractPoint();
incorrectGuess++;
}
You must first check that the input value is not empty, so you must modify the order of the condition. And it is better to add a return to exit the function when no value is entered so that a new question is not generated.
function evaluateAnswer(input) {
console.log('Input value on eval ', input); // double checking value
if (input === '' || isNaN(input)) { // I am not sure why it's never evaluated
console.log('Input value is empty or not a number ', input);
return;
} else if (input !== getProduct()) {
subtractPoint();
incorrectGuess++;
} else{
addPoint();
correctGuesses++;
}
totalGuesses++;
restartGame();
guessP.textContent = "Incorrect Guesses= " + incorrectGuess;
let average = (correctGuesses / totalGuesses);
let precisionAvg = roundToPrecision(average, 2);
averageP.textContent = `${(precisionAvg * 100).toFixed(2)}%`;
}
I am practicing creating a function that loops whatever number I put into the input into a times table. I used a for loop to achieve this but I ran into an issue. My for loop only runs one time and it only get my input * 10 for some reason. Can someone please help. Thank you.
function myFunction() {
var inputNumber = document.querySelector(".input-field").value;
inputNumber = parseInt(inputNumber);
if (isNaN(inputNumber) || inputNumber == "" || inputNumber == null) {
document.querySelector(".output h1").innerHTML = "Please enter a number!";
} else {
for (i = 1; i <= 10; i++) {
let product = inputNumber * i;
document.querySelector(".output").innerHTML = "<br>" + inputNumber + " * " + i + " = " + product + "<br>";
}
}
}
Looks like you update the HTML on every iteration. However, I think you want to expand the innerHTML to include all elements?
I would look into creating html elements in javascripts and adding them in html like this (draft, untested):
const element = document.createElement("div")
for (let i = 1; i < 10; i++) {
let product = inputNumer * i;
element.appendChild(document.createTextNode(`${inputNumer} ${product}`);
}
Please study this. It is using recommended event listener and a map
const arr = [...Array(11).keys()].slice(1); // numbers from 1 to 10
const h1 = document.querySelector("#output h1"),
result = document.getElementById("result"),
inputField = document.getElementById("inputField");
inputField.addEventListener("input", function() {
const inputNumber = +this.value;
console.log(inputNumber)
h1.classList.toggle("hide", inputNumber); // keep hide if ok number
result.innerHTML = inputNumber ? arr.map(i => `${inputNumber} * ${i} = ${inputNumber*i}`).join(`<br/>`) : "";
});
.hide {
display: none;
}
<input type="number" id="inputField" class=".input-field" />
<hr/>
<div id="output">
<h1 class="error hide">Please enter a number!</h1>
<div id="result">
</div>
</div>
I am trying to build a javascript calculator as per freecodecamp requirement on front end track.
Codepen link: https://codepen.io/ekilja01/pen/MoXROe
By pressing any number on calculator the display must be changed to that number. Also the var number has to remember its value, because by clicking the number again it becomes a new number, so after that I can use operators and parseInt to evaluate and display the final value. I've got an idea how can this be implemented by using jQuery, so something like this:
$("#numbers a").not("#clear,#clearall").click(function(){
number += $(this).text();
totaldiv.text(number);
});
$("#operators a").not("#equals").click(function(){
operator = $(this).text();
newnumber = number;
number = "";
totaldiv.text("0");
});
$("#clear,#clearall").click(function(){
number = "";
totaldiv.text("0");
if ($(this).attr("id") === "clearall") {
newnumber = "";
}
});
//Add your last .click() here!
$("#equals").click(function(){
if (operator === "+"){
number = (parseInt(number, 10) + parseInt(newnumber,10)).toString(10);
} else if (operator === "-"){
number = (parseInt(newnumber, 10) - parseInt(number,10)).toString(10);
} else if (operator === "÷"){
number = (parseInt(newnumber, 10) / parseInt(number,10)).toString(10);
} else if (operator === "×"){
number = (parseInt(newnumber, 10) * parseInt(number,10)).toString(10);
}
totaldiv.text(number);
number = "";
newnumber = "";
});
But what can be equivalent to this in vanilla js? I've tried .textContent or .innerHTML, but neither of them work. On calculator's dispay either undefined or <a>1</a> ... <a>AC</a>. Also what is the equivalent to .not(). Any help will be much appreciated.
html:
<div id="calculator">
<p id="cal">CALCULATOR</p>
<div id="total">
</div>
<div id="operators">
<a>÷</a>
<a>×</a>
<a>+</a>
<a>-</a>
<a>=</a>
</div>
<div id="numbers">
<a>1</a>
<a>2</a>
<a>3</a>
<a>4</a>
<a>5</a>
<a>6</a>
<a>7</a>
<a>8</a>
<a>9</a>
<a id="clear">C</a>
<a>0</a>
<a id="clearall">AC</a>
</div>
</div>
js:
document.addEventListener('DOMContentLoaded', function (event) {
console.log('DOM OK');
// Declare variables for number, new number and operators
var number, newNumber, operator = "";
// Declare variable total number to display total on the calculator's display
var totalNumber = document.getElementById("total");
totalNumber.textContent = "0";
document.getElementById("numbers").addEventListener('click', function(){
number += this.textContent;
totalNumber.textContent = number;
})
})
You may want to use the event argument in the callback function. For example:
number = "";
document.getElementById("numbers").addEventListener('click', function(e){
number += e.target.textContent;
totalNumber.textContent = number;
})
More information on the event target properties specifically:
https://developer.mozilla.org/en-US/docs/Web/API/Event/target
Entire JS code:
document.addEventListener('DOMContentLoaded', function (event) {
console.log('DOM OK');
// Declare variables for number, new number and operators
var number, newNumber, operator = "";
// Declare variable total number to display total on the calculator's display
var totalNumber = document.getElementById("total");
totalNumber.textContent = "0";
number = "";
document.getElementById("numbers").addEventListener('click', function(e){
number += e.target.textContent;
totalNumber.textContent = number;
})
})
just to display which number is clicked on-
var totalNumber = document.getElementById("total");
totalNumber.textContent = "";
document.getElementById("numbers").addEventListener('click', function(e){
totalNumber.textContent += e.target.innerText;
})
This is the code I have so far. When the user enters a word into the input box, I want that word to be stored in an array via the Add Word button. Once a number of words have been entered, the user clicks the Process Word button and I want all the words in the array to appear. How would I do this? Also could someone also explain why when nothing is entered into the input box "field is empty" does not appear?
function begin() {
var word = "List of words";
var i = returnword.length
if (userinput.length === 0) {
word = "Field is empty"
}
document.getElementById('message2').innerHTML = word
while (i--) {
document.getElementById('message').innerHTML = returnword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
var arrword = [];
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
Addword()
Your function contains an array arrword. If you keep it inside your function it will be reset every time you call the function. You need to keep your array of words outside the function
Empty input
The empty input message should be shown when you click on the Add word button. Check the input and display a message if needed
Display word
You can simply use join() to display you array
var arrayOfWord = [];
var inputElement = document.getElementById('userinput');
var errorElement = document.getElementById('error');
var wordsElement = document.getElementById('words');
function addWord() {
errorElement.innerHTML = "";
var word = inputElement.value;
if (word.trim() === "")
errorElement.innerHTML = "Empty input";
else
arrayOfWord.push(word);
inputElement.value = "";
}
function process(){
words.innerHTML = arrayOfWord.join(' - ');
}
#error {
color: tomato;
}
#words {
color: purple;
}
Enter a word <input id="userinput" /><button onclick="addWord()">Add word</button>
<div id="error"></div>
<button onclick="process()">Process</button>
<div id="words"></div>
you can do something a bit clearer with jQuery! :)
if you handle the input with jquery you can write something like:
var arrWord = [] // your array
/* Attaching a click handler on your "Add Word" button that will
execute the function on user click */
$("#addWordButtonID").on("click", function () {
var wordTyped = $('#textInputID').val() // your var that collect userInput
if (wordTyped.length != 0) { // your if statement with length === 0 condition
arrWord.push(wordTyped) // adding word typed to the array
}
})
to add jquery to your html page, just add
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
in your html header
Hopefully you already have the right html. Then you can modify your script like below:
<script>
var arrword = [];
var returnword;
function begin() {
var word = "List of words";
var i = arrword.length;
if (arrword.length === 0) {
word = "Field is empty";
}
document.getElementById('message2').innerHTML = word;
while (i--) {
document.getElementById('message').innerHTML = arrword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
</script>
var arrword = [];
var returnword;
function begin() {
var word = "List of words";
var i = arrword.length;
if (arrword.length === 0) {
word = "Field is empty";
}
document.getElementById('message2').innerHTML = word;
while (i--) {
document.getElementById('message').innerHTML = arrword[i] + "<br/>" + document.getElementById('message').innerHTML;
}
}
function addword() {
returnword = document.getElementById('userinput').value;
arrword.push(returnword);
}
<button id="addWord" onclick="addword()">Add Word</button>
<button id="processWords" onclick="begin()">ProcessWords</button>
<input type="text" id="userinput" value=" " />
<div id="message2">
</div>
<div id="message">
</div>
I am trying to check the user input for greater than 2 and less than 4 checkbox selected.
I have to do this check before the form gets submitted.
Although I am using AlloyUI for client side validation. You can help me with vanilla javascript.
Please help me with my code...
<% for(loop here which generates more than one checkbox) { %>
<form name=".." method=".." action=".." onSubmit="return checkBox();">
<input type="checkbox" id=".." name=".."/>
</form>
%>
My javascript
function checkBox(){
alert("start");
var total = 0;
var max = form.checkcompare.length;
alert(max);
for(var idx = 0; idx < max; idx++)
{
if(eval("document.compareform.checkcompare[" + idx + "].checked") == true)
{
alert("checking");
total += 1;
}
}
if (total==2 || total==4)
{
/* document.compareform.submit(); */
alert("success");
}
else
{
alert('Select minimum of 2 or maximum of 4 Estimates');
}
//alert("You selected " + total + " boxes.");
}
Its not working..can someone help..Thanks
Something tells me you have little idea what you're doing.
First off, you're creating one form for EVERY checkbox. Open the form tag, then put in your loop to add the checkboxes, then close the form.
Now for your script...
form is undefined, so you can get its elements. form.checkcompare is undefined, so you can't get its length. You probably want to pass this in the onSubmit event (onSubmit="return checkBox(this);"), and function checkBox(form). Then use form.querySelectorAll('input[type=checkbox]');.
Next, why in the world are you using evil eval just to get an array index?
As if that weren't enough you say you want "between 2 and 4" but your code considers "3" invalid.
Finally, you're not returning anything.
Fixed (and improved) code:
function checkBox(form){
var total = 0;
var boxes = form.querySelectorAll('input[type=checkbox]:checked').length;
if (boxes < 2 || boxes > 4)
return true;
else {
alert('Select minimum of 2 or maximum of 4 Estimates');
return false;
}
}
function getNumberOfCheckedCheckboxes ( form ) {
var returnValue = 0;
var inputElements = form.getElementsByTagName("input");
for (var i = 0; i < inputElements.length; i ++) {
if (inputElements.type == "checkbox") {
if (inputElments.checked) {
returnValue ++;
}
}
}
return returnValue;
}