How to fix access DOM in a loop using prompt - javascript

In a prompt message I request a number, I want to update the DOM element (input) but only work when do - while ends, I want to update the DOM after every prompt message.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Odds and Evens Game</title>
</head>
<body>
<form>
Number: <input type="text" id="number">
<input type="button" onclick="showIt()" value="ShowIt">
</form>
<script>
function showIt(){
var inputval ;
do {
inputval = prompt('Enter a number between 1 and 5 , 999 to exit');
number = parseInt(inputval);
document.getElementById('number').value= number;
}while(number !== 999);
}
</script>
</body>
</html>
sample that is running:
https://jsfiddle.net/neossoftware/73ag8whd/4/

prompt window prevents the user from accessing the rest of the program's interface until the dialog box is closed. Your while loop is calling prompt again and again blocking the access to user interface.
Use await, to paint the window before calling second prompt.
let num = 0;
let ele = document.querySelector('#num');
(async () => {
do {
await getInput()
ele.value = num;
await sleep(0);
} while(num !== 999);
})();
function sleep(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
function getInput() {
return new Promise(resolve => {
num = Number(prompt("Enter num"));
resolve(num);
});
}
Number: <input type="text" id="num">

Maybe I'm not understanding the question completely as your code does work without error except the last 999 to exit bit (on Firefox, Linux) - as that code then updates your input to 999. Why do you have this 999 to exit anyway?
Some minor changes and options below:
function showIt(){
var inputval, num;
do {
inputval = prompt('Enter a number between 1 and 5 (inclusive), 999 to exit');
num = parseInt(inputval);
if ((num != NaN) && (num >= 1) && (num <= 5) && (num != 999)) {
document.getElementById('number').value = num;
}
} while (num !== 999);
}
function updateAndExit(e) {
var inputval = prompt('Enter a number between 1 and 5 (inclusive)');
var num = parseInt(inputval);
if ((num != NaN) && (num >= 1) && (num <= 5)) {
this.textContent = num;
}
}
window.onload = function() {
var d = document.getElementById("click-to-udpate");
if (d) {
d.addEventListener("click",updateAndExit,false);
}
}
.fakeInput {
border:1px solid #886;
padding:6px;
background:#ddd;
}
.fakeInput:hover {
border:1px solid #688;
background:#fff;
cursor:pointer
}
Number: <input type="text" disabled="disabled" id="number">
<input type="button" onclick="showIt()" value="ShowIt">
<p>
Different option below:
</p>
<div id="click-to-udpate" class="fakeInput">Click to update</div>

Related

Unable to make thss script to run on click. Need it to re run after input has been changed

I've tried many times but can not figure out how to get this full script to run on click it will not work. Need answer to change after the value of the input has been changed.
<input id="a" value="500" type="number">
<p id="b"></p>
<script>
var bills = [100, 250, 450, 950, 1150];
var money = mod(document.getElementById("a").value);
function mod(num){
if (num % 5 === 0){
return num;
} else {
return num + 5 - num % 5
}
}
function foo(num){
var index = bills.length - 1;
var splits = [];
while (money >= bills[0]){
if (money >= bills[index]){
money -= bills[index];
splits.push(bills[index]);
} else {
index--;
}
}
return splits;
}
document.getElementById("b").innerHTML = foo(money) </script>

Adding JavaScript calculation function to HTML form

I am trying to link a basic calculation in an external JavaScript
The form is pretty simple and the function just checks to make sure the step number is even. I have reviewed the code many times, but when I enter the numbers and hit submit nothing happens. Any suggestions? Its seems like I just don't have the function and input elements linked correctly.
here is the code:
function evenNumbers() {
var evenNumberBtn = document.querySelector("button");
evenNumberBtn.addEventListener("click", evenNumbers);
var startNumber = parseInt(document.getElementById("startNumber").value);
var endNumber = parseInt(document.getElementById("endNumber").value);
var stepNumber = parseInt(document.getElementById("stepNumber").value);
while (startNumber + stepNumber <= endNumber) {
if (startNumber <= endNumber){
if (startNumber % 2 === 0 && stepNumber % 2 === 0) {
startNumber += stepNumber;
alert(startNumber);
} else if (startNumber % 2 !== 0 && stepNumber % 2 === 0) {
startNumber += 1 + (stepNumber);
alert(startNumber);
} else {
alert("Please enter a positive number for the step value.");
}
} else {
alert("Please enter an ending number greater than the start number.");
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>HTML5, CSS3 and JavaScript demo</title>
</head>
<body>
<form>
<label>Start: </label>
<input type="number" id="startNumber"/><br/>
<label>End: </label>
<input type="number" id="endNumber"/><br/>
<label>Step by:</label>
<input type="number" id="stepNumber"/><br/>
<button onclick="evenNumbers();">Submit</button>
<p></p>
</form>
<!-- End your code here -->
</body>
</html>
Try this:
In .js file
var evenNumberBtn = document.querySelector("button");
evenNumberBtn.addEventListener("click", evenNumbers);
I have removed your actual code for now, because it has some issues whereby you can end up in an infinite loop (I definitely did and it crashed Chrome 😊).
Your issue was in your HTML
Before
<button onclick("evenNumbers();")>Submit</button>
After
<button onclick="evenNumbers();">Submit</button>
function evenNumbers() {
var startNumber = parseInt(document.getElementById("startNumber").value);
var endNumber = parseInt(document.getElementById("endNumber").value);
var stepNumber = parseInt(document.getElementById("stepNumber").value);
alert(startNumber + ',' + endNumber + ',' + stepNumber);
}
<!DOCTYPE html>
<html>
<head>
<title>HTML5, CSS3 and JavaScript demo</title>
</head>
<body>
<form>
<label>Start: </label>
<input type="text" id="startNumber"/><br/>
<label>End: </label>
<input type="text" id="endNumber"/><br/>
<label>Step by:</label>
<input type="text" id="stepNumber"/><br/>
<button onclick="evenNumbers();">Submit</button>
<p></p>
</form>
<!-- End your code here -->
</body>
</html>
function evenNumbers() {
//var evenNumberBtn = document.querySelector("button");
//evenNumberBtn.addEventListener("click", evenNumbers);
var startNumber = parseInt(document.getElementById("startNumber").value);
var endNumber = parseInt(document.getElementById("endNumber").value);
var stepNumber = parseInt(document.getElementById("stepNumber").value);
while (startNumber + stepNumber <= endNumber) {
if (startNumber <= endNumber){
if (startNumber % 2 === 0 && stepNumber % 2 === 0) {
startNumber += stepNumber;
alert(startNumber);
} else if (startNumber % 2 !== 0 && stepNumber % 2 === 0) {
startNumber += 1 + (stepNumber);
alert(startNumber);
} else {
alert("Please enter a positive number for the step value.");
}
} else {
alert("Please enter an ending number greater than the start number.");
}
}
}
<!DOCTYPE html>
<html>
<head>
<title>HTML5, CSS3 and JavaScript demo</title>
</head>
<body>
<form>
<label>Start: </label>
<input type="text" id="startNumber"/><br/>
<label>End: </label>
<input type="text" id="endNumber"/><br/>
<label>Step by:</label>
<input type="text" id="stepNumber"/><br/>
<button onclick="evenNumbers()">Submit</button>
<p></p>
</form>
<!-- End your code here -->
</body>
</html>
The first two lines inside evenNumber function need to be outside the function, Otherwise your code never reaches inside that block.
$( document ).ready(function() {
var evenNumberBtn = document.querySelector("button");
evenNumberBtn.addEventListener("click", evenNumbers);
function evenNumbers() {
/*
your code here
*/
}
});
Also the logic inside the evenNumbers seems wrong. You might need to change that too.

Why is `pieceOfText` undefined?

I am creating a little guessing game involving decrypting text, but there is a variable inside my JavaScript code that is not working correctly. This variable, called pieceOfText, is supposed to be equal to a random piece of text generated from an array of 3 pieces of encoded text. However, when I retrieve the value of said variable, it outputs undefined.
Here is the code I have now:
function randomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random * (max - min + 1)) + min;
} // defines the function that gets a random number
var text = ['smell', 'cat', 'jump']; // pieces of text to decrypt
var encryptedText = []; // the decrypted pieces of text.
for (var i = 0; i < text.length; i++) {
encryptedText.push(window.btoa(text[i]));
}
var pieceOfText = encryptedText[randomInt(0, 2)];
console.log(pieceOfText);
/* document.getElementById('para').innerHTML += " " + pieceOfText; */
function validateForm() {
var form = document.forms['game']['text'];
var input = form.value;
if (input == "") {
alert("Enter your answer within the input.");
return false;
} else if (!(/^[a-zA-Z0-9-]*$/.test(input))) {
alert("Your input contains illegal characters.");
return false;
} else if (input != window.atob(pieceOfText)) {
alert("Incorrect; try again.");
location.reload();
} else {
alert("Correct!");
location.reload();
}
}
<!DOCTYPE html>
<html>
<HEAD>
<META CHARSET="UTF-8" />
<TITLE>Decryption Guessing Game</TITLE>
</HEAD>
<BODY>
<p id="para">Text:</p>
<form name="game" action="get" onsubmit="return validateForm()">
Decrypt: <input type="text" name="text">
<input type="submit" value="Check!">
</form>
<SCRIPT LANGUAGE="Javascript">
</SCRIPT>
</BODY>
</html>
The line commented out is possibly preventing my guessing game from running properly because pieceOfText is set to undefined. I was currently doing some debugging at the time when I found this out. One question I found with a similar dilemma was more oriented towards ECMAScript 6 (I'm not sure if I'm using that), and others I found weren't even related to JavaScript. So, what caused this and how can I fix it?
You wrote Math.random instead of Math.random() (you forgot to actually call the function):
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Decryption Guessing Game</title>
</head>
<body>
<p id="para">Text:</p>
<form name="game" action="get" onsubmit="return validateForm()">
Decrypt: <input type="text" name="text">
<input type="submit" value="Check!">
</form>
<script>
function randomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
} // defines the function that gets a random number
var text = ['smell', 'cat', 'jump']; // pieces of text to decrypt
var encryptedText = []; // the decrypted pieces of text.
for (var i = 0; i < text.length; i++) {
encryptedText.push(window.btoa(text[i]));
}
var pieceOfText = encryptedText[randomInt(0, 2)];
console.log(pieceOfText);
/* document.getElementById('para').innerHTML += " " + pieceOfText; */
function validateForm() {
var form = document.forms['game']['text'];
var input = form.value;
if (input == "") {
alert("Enter your answer within the input.");
return false;
} else if (!(/^[a-zA-Z0-9-]*$/.test(input))) {
alert("Your input contains illegal characters.");
return false;
} else if (input != window.atob(pieceOfText)) {
alert("Incorrect; try again.");
location.reload();
} else {
alert("Correct!");
location.reload();
}
}
</script>
</body>
</html>

Guessing Game in Javascript

What I'm trying to do is make a simple guessing game where the user can any the number without limit but will be graded at the end when the guessed the number correctly based on the number of their guesses. However, with my code when I enter a number and press the button to multiple times the hint changes from "Higher" to "Lower" even if the number is not changed also the message that should be displayed when the number is guessed correctly is not showing. Here's my code, I'm a beginner so there's bound to be errors in the code and any help is appreciated.
<fieldset>
<input type="number" id="guess" />
<button onClick="checknum();">Check Number</button>
</fieldset>
<fieldset>
<p>Your current status:</p>
<output id="status_output">You have yet to guess anything.</output>
</fieldset>
<script type="text/javascript">
function checknum(){
var randomNumber = Math.floor((Math.random() * 100) + 1);
var guessNumber = document.getElementById("guess").value;
//var guessNumber = parseInt(guess.value);
var statusOutput = document.getElementById('status_output');
var counter = 0;
var isguessed = false;
do {
counter = (counter + 1)
if (guessNumber < randomNumber) {
statusOutput.value = ("Higher");
}
else if (guessNumber > randomNumber) {
statusOutput.value = ("Lower");
}
else if (guessNumber = randomNumber) {
set (isguessed = true());
statusOutput.value = ("Correct" + mark());
}
}
while (isguessed = false);
}
function mark(){
if (counter < 10){
statusOutput.value("Excellent");
}
else if (counter > 10 && counter <20){
statusOutput.value("Okay");
}
else
statusOutput.value("Needs Practice");
}
</script>
In your while you are assigning false to the variable named isguessed.
You want to do while (isguessed === false) instead. This will check if isguessed is set to false
isguessed = false : assigns the varibles isguessed to false
isguessed === false : a boolean expression return true or false

Functions giving unexpected behavior in JavaScript

I am writing a program to generate primes in JavaScript. The problem is that the behavior of the program is very strange, it seems that the functions do not execute in order which prevents it from executing properly. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Generate Some Primes!</title>
</head>
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="messageBox"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = "Generating ...";
var DONE = "Done!";
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
writeMessage(NOT_STARTED);
if (checkInput()) {
checkNumbers();
writeMessage(DONE);
}
}
}
function checkInput() {
initializeBounds();
if (lower >= upper) {
writeMessage("Lower bound must be less than upper bound.");
return false;
}
return true;
}
function initializeBounds() {
lower = Math.round(document.getElementById("lower").value);
upper = Math.round(document.getElementById("upper").value);
primesList.innerHTML = "";
}
function checkNumbers() {
for (var i = lower; i < upper; i++) {
if (isPrime(i))
writePrime(i);
}
}
function writePrime(p) {
primesList.innerHTML += "<li>" + p + "</li>";
}
function writeMessage(message) {
var messageBox = document.getElementById("messageBox");
messageBox.innerHTML = message;
}
function isPrime(p) {
if (p < 2)
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
</html>
These are my problems:
When the lower bound is close to the upper bound, and they are both relatively large numbers, no output is produced (for example try inputting 900 as the lower bound and 1000 as the upper bound), even though I know for sure prime numbers exist there, and that my method for generating them works.
The primes should be displayed on the screen as they are generated, and not at the end when they have all been created. If you input 0 as the lower bound and 10000 as the upper bound you will clearly see this issue (I suggest running the snippet full screen and watching the scrollbar size).
This is related to number 2. The Generating ... message is never shown, only Done.
EDIT: I made some changes to the code that solved the first issue.
I would suggest using Promises to break the blocking behaviour of the for loop and give the browser/UI enough time to render the results.
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="messageBox"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = "Generating ...";
var DONE = "Done!";
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
writeMessage(NOT_STARTED);
if (checkInput()) {
checkNumbers()
.then(function() {
writeMessage(DONE);
})
}
}
}
function checkInput() {
initializeBounds();
if (lower >= upper) {
writeMessage("Lower bound must be less than upper bound.");
return false;
}
return true;
}
function initializeBounds() {
lower = Math.round(document.getElementById("lower").value);
upper = Math.round(document.getElementById("upper").value);
primesList.innerHTML = "";
}
function checkNumbers() {
var promise = Promise.resolve();
for (var i = lower; i < upper; i++) {
(function(i) {
promise = promise.then(function() {
if (isPrime(i))
return writePrime(i);
});
})(i);
}
return promise;
}
function writePrime(p) {
return new Promise(function(resolve, reject) {
primesList.innerHTML += "<li>" + p + "</li>";
writeMessage("Generating ..." + Math.round(100 * p / (upper - lower)) + "%");
setTimeout(function() {
resolve();
}, 0);
});
}
function writeMessage(message) {
var messageBox = document.getElementById("messageBox");
messageBox.innerHTML = message;
}
function isPrime(p) {
if (p < 2)
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
External link to jsFiddle.
1: Use parseInt() to correctly convert the input (string) to a number.
2, 3: The for loop blocks the window thread, so this is why you aren't seeing the step-by-step results; the DOM will be refreshed only when the code finishes. The message is actually being set, but you can't see it because the process is blocked.
I have edited on your snippet, using the setTimeout() function, which will wait some time before calls.
<!DOCTYPE html>
<html>
<head>
<title>Generate Some Primes!</title>
</head>
<body>
<h1>Let's Generate Some Primes!!!</h1>
<form id="userInput">
<ul>
<li>
<label>Lower Bound (inclusive):</label>
<input type="number" id="lower">
</li>
<li>
<label>Upper Bound (exclusive):</label>
<input type="number" id="upper">
</li>
<li>
<input type="submit" value="Generate!">
</li>
</ul>
</form>
<p id="progress"></p>
<ul id="primes"></ul>
<script>
var primesList = document.getElementById("primes");
var lower;
var upper;
var NOT_STARTED = false;
var DONE = true;
window.onload = function() {
userInput.onsubmit = function(e) {
e.preventDefault();
/* 3: let's give some time for message */
writeProgressMessage(NOT_STARTED);
initializeBounds();
window.setTimeout(function () {
checkNumbers(lower, upper);
}, 1000); // waiting for 1s to start
}
}
function initializeBounds() {
/* correctly convert the input's for numbers, using parseInt */
lower = parseInt(document.getElementById("lower").value, 10);
upper = parseInt(document.getElementById("upper").value, 10);
primesList.innerHTML = "";
}
function checkNumbers(current, upper) {
if (isPrime(current))
writePrime(current);
/* not yet finished */
if (current != upper) {
setTimeout(function () {
checkNumbers(current+1, upper);
}, 100); // wait 100ms for the next check
}
}
function writePrime(p) {
primesList.innerHTML += "<li>" + p + "</li>";
}
function writeProgressMessage(done) {
var progress = document.getElementById("progress");
if (!done)
progress.innerHTML = "Generating ...";
else
progress.innerHTML = "Done!";
}
function isPrime(p) {
if (p < 2 || !Number.isInteger(p))
return false;
for (var b = p - 1; b > 1; b--)
if (GCD(p, b) > 1)
return false;
return true;
}
function GCD(a, b) {
if (b == 0)
return a;
else
return GCD(b, a % b);
}
</script>
</body>
</html>

Categories

Resources