Consecutive keyup events not working properly - javascript

I am creating a program that needs to handle three consecutive key presses of the enter button. My first eventListener works as planned. However, when the user input is incorrect, and the program moves onto the second eventListener, the program always runs the else statement regardless of whether the user input was correct or not. I tried including a variable, again, to capture user input at the second eventListener (thinking it was still reading the first user input) but the result was no different.
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Enter Missing Text</title>
</head>
<body>
<p id="quote"></p>
<p id="correctResponse"></p>
<p id="incorrectResponse"></p>
<script>
let quote = ['For score and', '7', 'years ago.'];
let helper = ' ';
for (i = 0; i < quote.length; i++) {
if (i === 1) {
quote[1] = "<input type='text' id='txtBox'><br>";
}
helper += quote[i];
}
document.getElementById('quote').innerHTML = helper;
document.getElementById('txtBox').focus();
document.addEventListener('keyup', function(e) {
if (e.keyCode === 13) {
var userInput = document.createElement('foo');
userInput.textContent = txtBox.value;
if (userInput.textContent == '7' || userInput.textContent == 'seven') {
document.getElementById('correctResponse').innerHTML = 'awesome.';
} else {
document.getElementById('incorrectResponse').innerHTML = "sorry. try again";
document.getElementById('txtBox').value = " ";
document.getElementById('txtBox').focus();
}
document.addEventListener('keyup', function(e) {
if (e.keyCode === 13) {
var userInput = document.createElement('foo');
userInput.textContent = txtBox.value;
if (userInput.textContent == '7' || userInput.textContent == 'seven') {
document.getElementById('correctResponse').innerHTML = 'awesome.';
} else {
document.getElementById('incorrectResponse').innerHTML = "give it one more try";
document.getElementById('txtBox').value = " ";
document.getElementById('txtBox').focus();
}
}
});
}
});
</script>
</body>
</html>

You can remove previous listener and add the next one in case the answer is wrong:
(any input value other than 7 will circle through handlers)
const result = document.getElementById('result');
function isEnter(event) {
return event.keyCode === 13
}
function f1(event) {
if (isEnter(event)) {
if (event.target.value !== '7') {
result.innerText = 'wrong 1';
event.target.addEventListener('keyup', f2);
event.target.removeEventListener('keyup', f1);
} else {
result.innerText = 'right 1';
}
}
}
function f2(event) {
if (isEnter(event)) {
if (event.target.value !== '7') {
result.innerText = 'wrong 2';
event.target.addEventListener('keyup', f3);
event.target.removeEventListener('keyup', f2);
} else {
result.innerText = 'right 2';
}
}
}
function f3(event) {
if (isEnter(event)) {
if (event.target.value !== '7') {
result.innerText = 'wrong 3';
event.target.addEventListener('keyup', f1);
event.target.removeEventListener('keyup', f3);
} else {
result.innerText = 'right 3';
}
}
}
document.getElementById('arrr').addEventListener('keyup', f1);
<input type="text" id='arrr'>
<p id='result'></p>

Related

Why isn't it removeing event listener?

My code is:
var input = document.getElementById('showInput0');
var inputStr = 'showInput0';
numberOfInputs = 0;
function anotherInput() {
var div = document.createElement('div');
div.innerText = '- ';
id = 'showInput' + numberOfInputs;
document.body.appendChild(div).setAttribute('id', id);
/*lastNumOfId = str.slice(-1);
lastNumOfIdMULT = lastNumOfId + 1;
console.log('lastNumOfId:', lastNumOfId);
var inputStr = 'showInput' + lastNumOfIdMULT;
var input = document.getElementById(inputStr);*/
numberOfInputs += 1;
listen(id);
}
var help = ['help: Returns this.', 'clear: Clears the text'];
var numberOfOutputContainers = 0;
var numberOfOutputs = 0;
function execCommand(command) {
inputtedCommandStr = command.toString();
command = inputtedCommandStr.replace(/,/g, '');
console.log('COMMAND GOT:', command);
if (command == 'help') {
console.log('Command', command, 'registered');
var container = document.createElement('div');
//.setAttribute('id', 'outputParaX');
container.innerText = 'container:';
idOfOutput = 'showOutput' + numberOfOutputContainers;
document.body.appendChild(container).setAttribute('id', idOfOutput);
numberOfOutputContainers += 1;
for (const item of help) {
var div = document.createElement('div');
div.innerText = item;
id = 'Output' + help.indexOf(item);
numberOfOutputs += 1;
document
.getElementById(idOfOutput)
.appendChild(div)
.setAttribute('id', id);
}
anotherInput();
} else if (command == 'clear') {
} else {
console.log('Command', command, 'is unknown');
}
}
function listen(inputStr) {
input = document.getElementById(inputStr);
var inputtedCommandStr = '';
var inputtedCommand = [];
document.addEventListener('keydown', function(e) {
//console.log(e.which);
//console.log(e.key);
if (e.key == 'Space') {
inputtedCommand.push(' ');
} else if (e.key == 'Backspace') {
inputtedCommand.pop();
} else if (e.key == 'Enter') {
//EXECUTE COMMAND
if (document.removeEventListener('keydown', e)) {
document.removeEventListener('keydown', e);
} else {
console.log('NO EVENT LISTENER FOUND');
document.removeEventListener('keydown', e);
}
document.removeEventListener('keydown', e);
execCommand(
inputtedCommand,
numberOfOutputContainers,
numberOfOutputs
);
//inputtedCommand = [];
} else if (e.key == 'Alt') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else if (e.key == 'AltGraph') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else if (e.key == 'Shift') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else if (e.key == 'CapsLock') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else if (e.key == 'Control') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else if (e.key[0] == 'F') {
console.log(
'Button represents an action in the character --> not in the command string'
);
} else {
inputtedCommand.push(e.key);
}
//console.log(inputtedCommand);
/*
for (const item of inputtedCommand) {
console.log(item)
}
for (let index = 0; index < inputtedCommand.length; index++) {
inputtedCommandStr[index] = inputtedCommand[index]
console.log(inputtedCommand, inputtedCommandStr)
}*/
inputtedCommandStr = inputtedCommand.toString();
input.innerHTML = '- ' + inputtedCommandStr.replace(/,/g, '');
console.log(input);
});
}
anotherInput();
And, after I type in help hit enter then repeating this several times, I've got this as output:
- help
container:
help: Returns this.
clear: Clears the text
- helphelp
container:
help: Returns this.
clear: Clears the text
- helphelp
container:
help: Returns this.
clear: Clears the text
- helphelp
container:
help: Returns this.
clear: Clears the text
- helphelp
container:
help: Returns this.
clear: Clears the text
- helphelp
container:
help: Returns this.
clear: Clears the text
To remove an event listener, it's best to name the function. JS will try to match the function/listener according to this page.
The line you have:
document.removeEventListener('keydown', e);
Isn't going to remove anything because 'e' is not a function.
To start, you would need something like this:
let handler = function(e){/*stuff*/};
document.addEventListener('keydown', handler);
Then you can remove it with
document.removeEventListener('keydown', handler);

unsure how to display results using getelementbyId // javascript

Ok so my code is below. Once the calculate price button is clicked, I want it to display the results beneath the button. ie. number of cars = CarNumber, type of car = CarType and the price of the car = CarPrice. I know this is probably super easy to do but I just cant get it to work.
HTML:
<!DOCTYPE html>
<html>
<body>
<form name="Cars">
<h1>Car Sales</h1>
<p>Which type of car would you like (A, B or C)</p>
<input type="text" name="CarType"><br>
<p>how many cars would you like (1-100)</p>
<input type="text" name="CarNumber"><br>
<br>
<button onclick="return beginfunction()">Calculate Price</button>
<p id="message"></p>
<script src="car.js"> </script>
</form>
</body>
</font>
JavaScript:
function beginfunction() {
var CarType = document.forms["Cars"]["CarType"].value;
var CarNumber = document.forms["Cars"]["CarNumber"].value;
var CarPrice;
if ( !( CarType == 'A' || CarType == 'B' || CarType == 'C' ) ) {
CarTypeError = "Invalid Car Type";
document.getElementById("message").innerHTML = CarTypeError;
return false;
}
{
if (isNaN(CarNumber)) {
CarNumberError = "Invalid Quantity Entered";
document.getElementById('message').innerHTML = CarNumberError;
return false;
}
}
{
if (CarNumber >0 && CarNumber <10)
{
}
else
CarError = "Invalid";
document.getElementById('message').innerHTML = CarError;
return false;
}
{
if (CarType == 'A') {
CarPrice = 30;
} else if (CarType == 'B') {
CarPrice = 20;
} else if (CarType == 'C'){
CarPrice = 10;
}
}
}
The way that you use innerHTML is right, but there is some logic problems in your function, here is the refactored code:
function beginfunction() {
var CarType = document.forms["Cars"]["CarType"].value;
var CarNumber = document.forms["Cars"]["CarNumber"].value;
var CarPrice;
var message = "";
if ( !( CarType == 'A' || CarType == 'B' || CarType == 'C' ) ) {
message = "Invalid Car Type";
}else{
if (CarType == 'A') {
CarPrice = 30;
} else if (CarType == 'B') {
CarPrice = 20;
} else if (CarType == 'C'){
CarPrice = 10;
}
message = CarPrice;
}
if (isNaN(CarNumber)) {
message = "Invalid Quantity Entered";
}
if (CarNumber >0 && CarNumber <10)
{
}
else{
message = "Invalid";
}
document.getElementById('message').innerHTML = message;
return false;
}

Replace text in an <li> tag in an ul

I'm new to web programming, and I'm trying to complete a simple guessing game project.
Right now I'm stuck because I'm trying to update an unordered list with the player's past guesses, but the page does not update.
Here is my jQuery code:
$(document).ready(function() {
game = new Game;
var guessNum
onSubmit = function(event){
event.preventDefault();
var input = $('#player-input');
var guess = +input.val();
input.val('');
var result = game.playersGuessSubmission(guess);
if (result == 'You have already guessed that number.') {
$('#title').text(result);
} else if (result === 'You Win!' || result === 'You lose.') {
$('#title').text(result);
$('#subtitle').text('Press the reset button to play again.')
$('#hint').prop('disabled', true)
$('#submit').prop('disabled', true)
} else { //this is the relevant portion
guessNum = (game.pastGuesses.length - 1).toString();
$('#' + guessNum).text(guessNum);
}
};
$('#submit').on('click', function(e){
onSubmit(e);
});
$('#player-input').on('keypress', function(e) {
if(e.which == 13) {
e.preventDefault();
onSubmit(e);
};
});
});
Here is the unordered list's html:
<div id='guesses'>
<!-- unordered list of guesses -->
<ul id='past-guesses' class="list-inline center">
<li id='0' class="guess list-group-item ">-</li>
<li id='1'class="guess list-group-item">-</li>
<li id='2' class="guess list-group-item">-</li>
<li id='3' class="guess list-group-item">-</li>
<li id='4' class="guess list-group-item">-</li>
</ul>
</div>
I have also tried not using the identifiers in the html, and instead selecting the li elements this way:
var idStr = "#past-guesses:eq(" + guessNum + ")"
$(idStr).text(game.playersGuess.toString());
In either case, the page does not update with the new values in the unordered list displayed. What am I doing wrong?
EDIT
In response to the request in comments, here's my entire JS file (now slightly edited because I was experimenting with changing the list id's to not begin with a number):
function generateWinningNumber() {
num = Math.random()
if (num === 0) {
return 1;
} else {
roundNum = Math.floor(num*100);
return roundNum + 1;
}
}
function shuffle(array) {
var m = array.length, t, i;
// While there remain elements to shuffle…
while (m) {
// Pick a remaining element…
i = Math.floor(Math.random() * m--);
// And swap it with the current element.
t = array[m];
array[m] = array[i];
array[i] = t;
}
return array;
}
function Game(){
this.winningNumber = generateWinningNumber();
this.playersGuess = null;
this.pastGuesses = [];
}
Game.prototype.difference = function() {
return Math.abs(this.playersGuess - this.winningNumber);
}
Game.prototype.isLower = function() {
if (this.playersGuess < this.winningNumber) {
return true;
} else {
return false;
}
}
Game.prototype.checkGuess = function() {
if (this.playersGuess === this.winningNumber) {
return "You Win!";
}
if (this.pastGuesses.indexOf(this.playersGuess) > -1) {
return "You have already guessed that number.";
}
this.pastGuesses.push(this.playersGuess);
if (this.pastGuesses.length >= 5) {
return "You Lose.";
} else if (this.difference() < 10) {
return "You're burning up!";
} else if (this.difference() < 25) {
return "You're lukewarm.";
} else if (this.difference() < 50) {
return "You're a bit chilly.";
} else {
return "You're ice cold!";
}
}
Game.prototype.playersGuessSubmission = function(num) {
if (num < 1 || num > 100 || typeof num != 'number') {
throw "That is an invalid guess."
} else {
this.playersGuess = num;
return this.checkGuess();
}
}
Game.prototype.provideHint = function() {
return shuffle([generateWinningNumber(), generateWinningNumber(), this.winningNumber]);
}
newGame = function() {
game = new Game;
return game;
}
$(document).ready(function() {
var game = new Game;
var guessNum
onSubmit = function(event){
event.preventDefault();
var input = $('#player-input');
var guess = +input.val();
input.val('');
var result = game.playersGuessSubmission(guess);
if (result == 'You have already guessed that number.') {
$('#title').text(result);
} else if (result === 'You Win!' || result === 'You lose.') {
$('#title').text(result);
$('#subtitle').text('Press the reset button to play again.')
$('#hint').prop('disabled', true)
$('#submit').prop('disabled', true)
} else {
guessNum = (game.pastGuesses.length - 1).toString();
$('#l' + guessNum).text(guessNum);
}
};
$('#submit').on('click', function(e){
onSubmit(e);
});
$('#player-input').on('keypress', function(e) {
if(e.which == 13) {
e.preventDefault();
onSubmit(e);
};
});
});
});
You need to escape the CSS selector.
try to replace this line:
$('#' + guessNum).text(guessNum);
with this:
var selector = "#\\" + guessNum.toString().charCodeAt(0).toString(16) + " " + guessNum.toString().substr(1);
$(selector).text(guessNum);
you can read more at:
https://www.w3.org/International/questions/qa-escapes

How do I prevent both my if statements running the first time?

Quick question as I'm drawing a blank, if I have an event listener that contains 2 if statements that on first time round are both true but I don't want both of them to execute how do I prevent this? Can I break on the first conditional or something like that?
JS
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output');
input.addEventListener('keydown', function (event) {
if (this.value.length === 0) {
console.log('run this once');
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output');
var firstTimeCallbackRun= true;
input.addEventListener('keydown', function (event) {
if (this.value.length === 0) {
console.log('run this once');
if(firstTimeCallbackRun) {
firstTimeCallbackRun = false;
return;
}
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
var input = document.querySelector('.js-input'),
output = document.querySelector('.js-output'),
isFirst = true;
input.addEventListener('keydown', function (event) {
if (isFirst) {
isFirst = false;
return;
}
if (this.value.length === 0) {
console.log('run this once');
}
if (this.value === '') {
console.log('this is empty so show hint')
}
});
Maybe something like that? But probably you should ask yourself why this is happening and what are you doing wrong. Since it is a hacky and not optimal solution.
(function() {
var firstRun = true;
var input = document.querySelector('.js-input');
var output = document.querySelector('.js-output');
input.addEventListener('keydown', function (event) {
if (firstRun) {
firstRun = false;
if (this.value.length === 0) {
console.log('run this once');
}
} else {
if (this.value === '') {
console.log('this is empty so show hint')
}
}
});
})();
Here an example of how you could achieve this:
(function() {
var input = document.querySelector('.js-input');
var isDirty = function(element) {
if ( ! element.data) {
element.data = {isDirty: false};
}
if (element.value.length > 0 && ! element.data.isDirty) {
element.data.isDirty = true;
} else if (element.value.length === 0) {
element.data.isDirty = false;
}
return element.data.isDirty;
};
input.addEventListener('keyup', function (event) {
var dirtyClass = " is-dirty";
if (isDirty(this)) {
if (this.className.search(dirtyClass) === -1) {
this.className += dirtyClass;
}
} else {
this.className = this.className.replace(dirtyClass, "");
}
});
})();

How do I know, via key event code, if the character just entered in a <textarea> is lower or upper case?

I'm trying to capture the character just entered into a <textarea>, but I can only get which key is pressed via key event like keydown or keyup, not knowing if it's lower case or upper case.
For example, when I input A or a, the event key codes for keydown are all 65.
I thought of using val() to get the string in the <textare> and get the last character of it, but that is too slow and memory consuming, since I want to record every keyboard event while the user is typing.
So is there a way I can simply get the last entered character?
Try this:
var p = $('#log')[0];
$("#textarea").on("keypress", function(e) {
p.textContent = '';
var k = e.keyCode || e.which;
var character = String.fromCharCode(k);
if (!isNaN(character * 1)) {
p.textContent += 'character is numeric';
} else {
if (character == character.toUpperCase()) {
p.textContent += 'UPPER case true';
}
if (character == character.toLowerCase()) {
p.textContent += 'lower case true';
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="textarea"></textarea>
<p id="log"></p>
I see what you mean about the shiftKey
var myObj = $('#myTextarea');
function isLetter(char){
if ((char.toLowerCase() !== char) || (char.toUpperCase() !== char)) {
return true;
}
return;
}
myObj.keypress(function( event ){
var text = myObj.val();
var char = text.charAt(text.length-1);
if (!event.shiftKey && isLetter(char)) {
if (char == char.toUpperCase()) {
console.log('Upper');
}
if (char == char.toLowerCase()) {
console.log('Lower');
}
}
});
try:
<textarea id="area1"></textarea>
window.onload = function () {
document.getElementById("area1").onkeypress = function(event){
var code = event.which;
if ((code >= 65) && (code <= 90)) {
alert('Upper');
}
else if ((code >= 97) && (code <= 122)) {
alert('Lower');
}
}
}

Categories