Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 days ago.
Improve this question
I am coding a simple Javascript chatbot and need help on how to make the choices cookBtn and englishBtn to work as well as how I finish from Bound Book, Pocket Book and Chaged My Mind to "Thank you for your order (name), we will ship out right away.
Please find my js code below.
// All the DOM selectors stored as short variables
const chat = document.getElementById("chat");
const formWrapper = document.getElementById('formWrapper');
const messageSound = new Audio ("assets/pop.mp3");
const timeGreetings = [`Good morning my friend! What's your name?`, `Hello my friend! What's your name?`, `Good evening my friend! What's your name?`, `I am sorry my friend, but we are closed!`];
// Variable for date & time.
const date = new Date();
console.log(date);
const time = date.getHours();
console.log(time);
const greetUser = (timeGreetings, time) => {
if (time >= 5 && time <= 10) {
showMessage(timeGreetings[0], "bot"); //Morning (5 to 10)
} else if (time > 10 && time <= 18) {
showMessage(timeGreetings[1], "bot"); //Hello (11 to 18)
} else if (time > 18 && time <= 22) {
showMessage(timeGreetings[2], "bot"); //Evening (19 to 22)
} else {
showMessage(timeGreetings[3], "bot"); //Late (23 to 4)
showMessage("Anyways, since you're up. What's your name?", "bot");
}
};
//1 second delay for greeting
setTimeout(greetUser, 1000, timeGreetings, time);
//--This is the general way of adding a chat bubble from both the user and the bot. Create more detailed ones for what we want to do later.
const showMessage = (msg, sender) => {
if (sender === 'user') {
chat.innerHTML += `<section class="user-msg">
<div class="bubble user-bubble">
<p>${msg}</p>
</div>
<img src="./user.png" alt="chat bot" />
</section>`;
}
else if (sender === 'bot') {
chat.innerHTML += `<section class="bot-msg">
<img src="./bot.png" alt="user bot" />
<div class="bubble bot-bubble">
<p>${msg}</p>
</div>
</section>`;
}
//Makes sound when sending a message
messageSound.currentTime = 0
messageSound.play()
// This little thing makes the chat scroll to the last message when there are too many to be shown in the chat box
chat.scrollTop = chat.scrollHeight;
};
//Eventlistener: Starts the function when user clicks submit.
form.addEventListener('submit', (event) => {
event.preventDefault() //Stops it from autosaving.
const firstName = document.getElementById('firstName').value;
console.log(firstName)
// Calling the function "showMessage".
showMessage(firstName, 'user');
//This code slows it with 1 sec.
setTimeout(() => recognize(firstName), 1000)
})
//Question 2
const recognize = (firstName) => {
console.log(firstName);
chat.innerHTML += `<section class="bot-msg">
<img src="./bot.png" alt="user bot" />
<div class="bubble bot-bubble">
<p>Which book would you like ${firstName}?</p>
</div>
</section>`;
console.log(formWrapper);
formWrapper.innerHTML = `<button id="yogaBtn">How to Yoga book</button>
<button id="cookBtn">How to cook book</button>
<button id="englishBtn">Learn English book</button>`;
let yogaBtn = document.getElementById('yogaBtn');
yogaBtn.addEventListener('click', () => choiceBook())
let cookBtn = document.getElementById('cookBtn');
cookBtn.addEventListenerById('click',() => choiceBook())
let englishBtn = document.getElementById('englishBtn');
englishBtn.addEventListenerById('click',() => choiceBook())
}
/*
setTimeout(() => choiceBook(firstName), 1000)
*/
// Question number 3
const choiceBook = (firstName) => {
chat.innerHTML += `<section class="bot-msg">
<img src="./bot.png" alt="user bot" />
<div class="bubble bot-bubble">
<p>Which book would you like ${firstName}?</p>
</div>
</section>`;
showMessage(`Would you like bound or pocket book, ${firstName}?`, 'bot');
formWrapper.innerHTML =
`<button id="boundBtn" type="submit" value="Bound book">Bound Book</button>
<button id="pocketBtn" type="submit" value="Pocket book">Pocket Book</button>
<button id="neverMindBtn" type="submit" value="Changed my mind">Changed my mind</button>`
let boundBtn = document.getElementById('boundBtn');
boundBtn.addEventListener('click',() => choiceBook())
let pocketBtn = document.getElementById('pocketBtn');
pocketBtn.addEventListener('click',() => choiceBook())
let neverMindBtn = document.getElementById('neverMindBtn');
neverMindBtn.addEventListener('click',() => choiceBook())
}
I think I need to do else, else if and if to access the other replies, but I can't seem to get them working.
Related
This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 3 months ago.
I have tried the answers given on the similar questions but I really can't do this one and I actually have no idea what I am supposed to do which is why I made this new question. The respective counter is supposed increase by one each time the respective countUp button is clicked. But now, I got NaN in both counter when I click on the first countUp button. Could you please help? Thank you.
const countUp = document.querySelectorAll('.countUp')
const countDown = document.querySelector('.countDown')
const counter = document.querySelectorAll('.num')
let count = counter.textContent
countUp.forEach((countUp) => {
countUp.addEventListener('click', () => {
counter.forEach((countUp) => {
count++
countUp.innerHTML = count
})
})
});
<div class="rating">
<button class="countUp">+</button>
<span class="num">0</span>
<button class="countDown">-</button>
</div>
<div class="rating">
<button class="countUp">+</button>
<span class="num">0</span>
<button class="countDown">-</button>
</div>
You cannot access the relative span using querySelectorAll. It returns a collection
If you delegate and navigate relatively among siblings, you can save a lot of code and headaches
const container = document.getElementById("container");
container.addEventListener('click', (e) => {
const tgt = e.target.closest("button");
if (!tgt) return; // or use e.target and test tgt.matches("button")
const numSpan = tgt.closest(".rating").querySelector(".num");
if (numSpan.matches(".clicked")) return; // already clicked
numSpan.classList.add("clicked");
let num = +numSpan.textContent;
num += tgt.classList.contains("countUp") ? 1 : -1;
numSpan.textContent = num;
});
<div id="container">
<div class="rating">
<button class="countUp">+</button>
<span class="num">1</span>
<button class="countDown">-</button>
</div>
<div class="rating">
<button class="countUp">+</button>
<span class="num">0</span>
<button class="countDown">-</button>
</div>
</div>
I am creating a quiz game, but I only want the user to be able to submit if all of the input fields are filled out using only JavaScript. I saw other similar questions on StackOverflow that used jquery, but I want to only use JavaScript.
html (Django template)
<h1 class="all_headings" id="quiz_title">{{ quiz.title }}</h1>
<h4 class="quiz_description">By: {{ quiz.user }}</h4>
<h4 class="quiz_description">Created On: {{ quiz.date_and_time }}</h4>
<br>
{% for q in quiz_questions %}
<h3 class="quiz_questions">{{q.1}}
<input type="text" id="id_question{{q.0}}" class="input">
</h3>
<div id="div{{ q.0 }}"></div>
<br>
<br>
{% endfor %}
<input type="submit" value="Submit" class="button quiz_button" id="{{ quiz.id }}">
<h2 id="score"></h2>
<input type="hidden" id="user_id" value="{{ request.user.id }}">
<input type="hidden" id="user_points" value="{{ request.user.points }}">
{% if request.user.is_anonymous %}
<h3 class="all_headings">Join now to earn 10 points for every question you answer correctly!</h3>
{% endif %}
Update: I added the entire Django template code so that you can see what is going on.
current JavaScript
function bindText(e){
const required = [...document.querySelectorAll(".inputs")];
required.forEach(input => input.oninput = checkText);
}
function checkText(e){
const required = [...document.querySelectorAll(".inputs")];
const button = document.getElementsByClassName(".quiz_button");
button.disabled = !required.every(input => input.value.length > 0);
}
document.addEventListener('DOMContentLoaded', function(){
//gets all the quiz_buttons enableChecking();
const quizButton = document.querySelectorAll('.quiz_button');
for (const button of quizButton){
button.addEventListener('click', (event) => check_quiz(event.target.id));
}
})
function check_quiz(id){
console.log("button is clicked");
//get answers
let response1 = document.getElementById('id_question1').value.toUpperCase().replace(/\s/g, "");
let response2 = document.getElementById('id_question2').value.toUpperCase().replace(/\s/g, "");
//repeats 8 more times
//get divs
let div1 = document.getElementById('div1');
let div2 = document.getElementById('div2');
//repeats 8 more times
var correctAnswers = 0;
//get quiz
fetch(`/check/${id}`)
.then(response => response.json())
.then(quiz => {
rightM = "You got this correct. Great job!";
//checking if the answers are right
//#1
let answ1 = quiz.answer1.toUpperCase().replace(/\s/g, "");
if(answ1 === response1){
div1.innerHTML = rightM;
div1.classList.add("correct");
correctAnswers++;
} else{
div1.innerHTML = `The correct answer is ${quiz.answer1}. Nice try!`;
div1.classList.add("incorrect");
}
//#2
let answ2 = quiz.answer1.toUpperCase().replace(/\s/g, "");
if(answ2 === response2){
div2.innerHTML = rightM;
div2.classList.add("correct");
correctAnswers++;
} else{
div2.innerHTML = `The correct answer is ${quiz.answer2}. Nice try!`;
div2.classList.add("incorrect");
}
//repeats 8 more times
console.log(correctAnswers)
//display score
let score = document.getElementById("score");
score.innerHTML = `Your score is ${correctAnswers}. Great job! :)`;
score.classList.add("score_style");
//points
let newPoints = correctAnswers * 10;
let currentUser = parseInt(document.getElementById("user_id").value);
let currentPoints = parseInt(document.getElementById("user_points").value);
let numOfPoints = currentPoints + newPoints;
console.log(numOfPoints);
fetch(`/points/${currentUser}`,{
method: "PUT",
body: JSON.stringify({
points: numOfPoints
})
})
})
}
I updated this with my current code and fixed all the errors from Update 2 of the answer, but the submit button still does not work when it is pressed.
Update 2
You need to go to JSHint and debug your code frequently. In Update 2 I have corrected as much as I care to. Before I can help you any further, you need to address the issues marked with a ❓.
Mark
Description
Corrected
❌
There are 12 typos, even if there was only one ❌ it would FUBAR whatever follows it.
Yes
❓
There are 5 questionable areas which will most likely need to be addressed because it may cause problems later on, or is pointless, etc.
No
🚩
Areas that could be modified to be more efficient, succinct, etc.
No
⭕
Areas that are modified to be more efficient, succinct, etc.
Yes
In Example D I placed where my code should go. There's always the chance that none of it may work because of Django. I have no idea, but on the surface it doesn't look debilitating.
Concerning <form>s, they are the the backbone of most interactive webpages but not necessary if you have other means such as fetch(). That is true in your case which means that you don't trigger "submit" events and you don't need a type="submit" unless there's something Django does that I'm ignorant to.
It isn't obvious to me how the HTML layout is exactly. I'm not certain whether there's one button (good) or multiple buttons (a very critical detail to know from the start).
Example D
document.addEventListener('DOMContentLoaded', bindText);
function bindText(e) {
const required = [...document.querySelectorAll(".inputs")];
required.forEach(input => input.oninput = checkText);
}
function checkText(e) {
/*❌: = Does not belong at end of line */
const required = [...document.querySelectorAll(".inputs")];
/*❌: `${id}` NOT "${id}"|BUT `${id}` === id */
/*❓: Is id declared elsewhere? If not, use it's actual "idOfButton".
If you have multiple submit buttons then you should reassess
your strategy.
*/
const button = document.getElementById(id);
/*❌: = missing */
button.disabled = !required.every(input => input.value.length > 0);
}
/*❌: '...' or "..." NOT "...' */
document.addEventListener('DOMContentLoaded', function() {
/*❌: = : ' missing */
const quizButton = document.querySelectorAll('.quiz_button');
for (const button of quizButton) {
/*⭕: In event handlers/listeners if it is a named function that's
defined separately, remove the ()
*/
button.addEventListener('click', (event) => checkQuiz);
}
});
/*⭕: Event handlers pass the (e)vent object by default */
function checkQuiz(e) {
const id = e.target.id;
/*❌: / missing a \ needs to be escaped: \\ */
/*❌: response* number 1 NOT letter l */
let response1 = document.getElementById('id_question1').value.toUpperCase().replace(/\\/g, "");
/*❌: / missing a \ needs to be escaped: \\ */
let response2 = document.getElementById('id_question2').value.toUpperCase().replace(/\\/g, "");
/*❓: Are sure there's a <div id="div">? */
let div1 = document.getElementById('div');
/*❌: '...' or '..." NOT '..." */
let div2 = document.getElementById('div2');
/*❓: var hoists to be global use let or const. In this case let
is the best choice
*/
var correctAnswers = 0;
fetch(`/check/${id}`)
.then(response => response.json())
.then(quiz => {
/*❓: Is rightM declared elsewhere? If not,
use let or const
*/
rightM = "You got this correct. Great job!";
let answ1 = quiz.answer1.toUpperCase().replace(/\s/g, "");
if (answ1 === response1) {
div1.innerHTML = rightM;
div1.classList.add("correct");
correctAnswers++;
} else {
div1.innerHTML = `The correct answer is ${quiz.answer1}. Nice try!`;
div1.classList.add("incorrect");
}
let answ2 = quiz.answer1.toUpperCase().replace(/\s/g, "");
if (answ2 === response2) {
div2.innerHTML = rightM;
div2.classList.add("correct");
correctAnswers++;
} else {
div2.innerHTML = `The correct answer is ${quiz.answer2}. Nice try!`;
div2.classList.add("incorrect");
}
/*🚩: DRY = Don't Reapeat Yourself. Iterate through quiz.answer1 with
a loop or an array method.
*/
//this repeats 8 more times
console.log(correctAnswers);
let score = document.getElementById("score");
/*❌: ` missing */
/*❌: $' '{ space between $ and { breaks interpolation */
score.innerHTML = `
Your score is ${correctAnswers}.Great job!:)`;
score.classList.add("score_style");
/*❓: is newPoint declare elsewhere? If not use let or const */
newPoints = correctAnswers * 10;
let currentUser = parseInt(document.getElementById("user_id").value);
let currentPoints = parseInt(document.getElementById("user_points").value);
let numOfPoints = currentPoints + newPoints;
/*❌: ` missing*/
fetch(`/points/${currentUser}`, {
method: "PUT",
body: JSON.stringify({
points: numOfPoints
})
});
});
}
Update 1
As requested examples B and C include JavaScript that'll enable a disabled <button> when all <input>have text.
If you have a <form> wrapped around everything (which is very simple to do if you don't), add required to all of the <input> -- that'll prevent the <form> from being submitted should there be any blank <input>s (see Example A).
Example A - Has no JavaScript or CSS -- just HTML. The <button> isn't disabled, but the <form> will not allow itself to be submitted if any <input> is blank.
Example B - Has a <form> and uses HTMLFormElement and HTMLFormControlsCollection interfaces which facilitates the use of form controls.
Example C - Is a less elegant solution involving standard DOM manipulation.
Note that in Example B the event handler is bound to the <form> and that it is shared by each <input>. Should any form control be added to the <form> later on, the event handling will apply to it as well. In Example C each <input> has the input bound to them individually. Should any form control be added later on they'll need to have their own event handler/listener attached after they have been created.
Examples B and C have commented details
Example A
<form>
<input required value='XXXXXXXXXXX'><br>
<input required value='XXXXXXXXXXX'><br>
<input required placeholder='Enter text here'><br>
<button>Submit</button>
</form>
Example B
// Reference the <form>
const F = document.forms[0];
// Reference all form controls
const fc = F.elements;
// Collect all name='required' into a HTMLCollection, convert it into an array
const required = [...fc.required];
// Reference the <button>
const done = fc.done;
/**
* Bind input event to <form>...
* ...enable the <button> if .every() <input> has a value
*/
F.oninput = e =>
done.disabled = !required.every(input => input.value.length > 0);
<form>
<input name='required' value='XXXXXXXXXXX'><br>
<input name='required' value='XXXXXXXXXXX'><br>
<input name='required' placeholder='Enter text here'><br>
<button id='done' disabled>Done</button>
</form>
Example C
// Collect all .required into a NodeList, convert it into an array
const required = [...document.querySelectorAll('.required')];
// Reference the <button>
const done = document.getElementById('done');
/**
* Bind the input event to each <input>...
* ...<button> is enabled if .every() <input> has a value
*/
required.forEach(input => input.oninput = e =>
done.disabled = !required.every(input => input.value.length > 0));
<form>
<input class='required' value='XXXXXXXXXXX'><br>
<input class='required' value='XXXXXXXXXXX'><br>
<input class='required' placeholder='Enter text here'><br>
<button id='done' disabled>Done</button>
</form>
Im currently working on a timed quiz application and got a majority of the functionality working. But, when I went to test it I noticed the question element I set up in the HTML wasn't changing with the question objects I defined in the js file. The two files are linked together correctly, but I can't figure out where I went wrong. Tbh after looking at this for hours a fresh set of eyes would really come in handy.
HTML:
<body>
<div class="container">
<div id="game" class="justify-center">
<div id="hud">
<div class="hud-item">
<!-- container desc -->
<p id="container-text" class="hud-prefix">
Question:
</p>
<!-- timer function -->
<div id="timer">
</div>
<!-- end of timer -->
</div>
<div class="hud-item">
<p class="hud-prefix">
Score:
</p>
<h1 class="hud-main-text" id="score">
0
</h1>
</div>
</div>
<h1 id="question">What is the answer?</h1>
<!-- making possible answers to given question -->
<div class="choice-container">
<p class="choice-prefix">A</p>
<p class="choice-text" data-number="1">Choice 1</p>
</div>
<!-- making possible answers to given question -->
<div class="choice-container">
<p class="choice-prefix">B</p>
<p class="choice-text" data-number="2">Choice 2</p>
</div>
<!-- making possible answers to given question -->
<div class="choice-container">
<p class="choice-prefix">C</p>
<p class="choice-text" data-number="3">Choice 3</p>
</div>
<!-- making possible answers to given question -->
<div class="choice-container">
<p class="choice-prefix">D</p>
<p class="choice-text" data-number="4">Choice 4</p>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="./assets/script.js"></script>
Here is my JavaScript file:
const question = $('#question');
const choices = Array.from($('.choice-text'));
const scoreText = $('#score');
//defining let var which values will change throughout the game
let currentQuestion = {};
let acceptingAnswers = true;
let score = 0;
let questionCounter = 0;
let availableQustions = [];
//defining list of potential questions to be called apon by currentQuestions
let questions = [
{
question: 'What types of variables can you define?',
choice1: 'var',
choice2: 'let',
choice3: 'const',
choice4: 'all of the above',
answer: 'all of the above'
},
// question 1 ^^^^
{
question: 'How would you store an item to local storage?',
choice1: 'localStorage.getItem()',
choice2: 'localStorage.setItem()',
choice3: 'localStorage.store()',
choice4: 'localStorage.setLocal()',
answer: 'localStorage.setItem()'
},
// question 2 ^^^^
]
console.log(questions)
//start game functionality and needed var
const SCORE_POINTS = 100;
const MAX_QUESTIONS = 10;
startGame = () => {
questionCounter = 0;
score = 0;
availableQustions = [...questions];
getNewQuestion();
}
//get new question function supplies new q when previous gets answered
getNewQuestion = () => {
if(availableQustions.length === 0 || questionCounter > MAX_QUESTIONS) {
localStorage.setItem('mostRecentScore', score)
return window.location.assign('/end.html')
}
questionCounter++
//making random question appear
const questionIndex = Math.floor(Math.random() * availableQustions.length)
currentQuestion = availableQustions[questionIndex]
question.innerHTML = currentQuestion.question
//was originally choices.array.forEach
choices.forEach((choice)=> {
const number = choice.dataset['number'];
choice.innerText = currentQuestion['choice' + number];
});
availableQustions.splice(questionIndex, 1);
acceptingAnswers = true;
}
choices.forEach(choice => {
choice.addEventListener('click', e => {
if (!acceptingAnswers) return
acceptingAnswers = false
const selectedChoice = e.target
const selectedAnswer = selectedChoice.dataset['number']
let classToApply = selectedAnswer == currentQuestion.answer ? 'correct' : 'incorrect'
//if answer is correct add 100 to score
if (classToApply === 'correct') {
incrementScore(SCORE_POINTS)
}
selectedChoice.parentElement.classList.add(classToApply)
setTimeout(() => {
selectedChoice.parentElement.classList.remove(classToApply)
getNewQuestion();
}, 1000)
})
});
//increment score funt and calling start game
incrementScore = num => {
score += num
scoreText.innerText = score
}
startGame();
I originally had ten questions but I deleted the other 8 because of stacks code to normal text ratio.
The problem that is happening is the questions aren't toggling red and green for correct and wrong answers. and the questions aren't displaying on the #question HTML element.
Heres the CSS for the correct and wrong bits
.correct {
background-color: green;
border: green 4px solid;
}
/* will change wrong answer color to red */
.wrong {
background-color: red;
border: red 4px solid;
}
I'm learning JS and created an app game in which a user guesses random day and random month. When the user gets both of them right, I want to replace the question mark with a heart icon from JS icons. Somehow it doesn't work.
I tried this code:
if (guessDay === secretDay && guessMonth === secretMonth) {
document.getElementById("victory").innerHTML = "💖";
}
I also tried replacing the heart icon with a word: "Victory" but it didn't work either.
Full code below:
let secretMonth = Math.trunc(Math.random() * 12) + 1;
let secretDay = Math.trunc(Math.random() * 31) + 1;
console.log(secretMonth, secretDay);
document.querySelector(".btn-month").addEventListener("click", function () {
const guessMonth = Number(document.querySelector(".guess-month").value);
if (guessMonth === secretMonth) {
document.querySelector(
".hint-month"
).textContent = `You got the month right.`;
document.querySelector(".left").style.backgroundColor = "blue";
} else if (guessMonth >= secretMonth) {
document.querySelector(".hint-month").textContent = `Go lower.`;
document.querySelector(".left").style.backgroundColor = "#d9480f";
} else {
document.querySelector(".hint-month").textContent = `Go higher.`;
document.querySelector(".left").style.backgroundColor = "#d9480f";
}
});
document.querySelector(".btn-day").addEventListener("click", function () {
const guessDay = Number(document.querySelector(".guess-day").value);
if (guessDay === secretDay) {
document.querySelector(".hint-day").textContent = `You got the day right.`;
document.querySelector(".right").style.backgroundColor = "blue";
} else if (guessDay >= secretDay) {
document.querySelector(".hint-day").textContent = `Go lower.`;
document.querySelector(".right").style.backgroundColor = "#d9480f";
} else {
document.querySelector(".hint-day").textContent = `Go higher.`;
document.querySelector(".right").style.backgroundColor = "#d9480f";
}
});
document.querySelector(".btn-reset").addEventListener("click", function () {
document.querySelector(".hint-day").textContent = "";
document.querySelector(".hint-month").textContent = "";
document.querySelector(".right").style.backgroundColor = "#d9480f";
document.querySelector(".left").style.backgroundColor = "#d9480f";
document.querySelector(".guess-month").value = "";
document.querySelector(".guess-day").value = "";
});
if (guessDay === secretDay && guessMonth === secretMonth) {
document.getElementById("victory").innerHTML = "victory";
}
<div class="wrapper">
<header>
<h1>Guess my birthday</h1>
<div class="divider"><span id="victory">?</span></div>
</header>
<main>
<section class="left">
<div class="label-container">
<p class="range">Between 1-12</p>
<p class="label">month</p>
</div>
<input class="guess guess-month" type="number" min="0" max="12" />
<button class="btn btn-month">Check</button>
<p class="hint hint-month"></p>
</section>
<section class="right">
<div class="label-container">
<p class="range">Between 1-31</p>
<p class="label">day</p>
</div>
<input class="guess guess-day" type="number" min="0" max="31" />
<button class="btn btn-day">Check</button>
<p class="hint hint-day"></p>
</section>
<button class="btn btn-reset">Reset</button>
</main>
</div>
The logic is correct but the code is not running at the right moment in the right scope. The conditional check happens at the same time as registering event handlers.
// register month click
// register day click
// register reset click
// too early to check the guess, no guesses have been made yet
if (guessDay === secretDay && guessMonth === secretMonth) {
document.getElementById("victory").innerHTML = "victory";
}
In order to fix the problem, there are two steps.
Put the victory check in a helper function to call on both the day and month submit if the guess is right.
Keep track of the day and month guess in the parent scope to allow checking for victory after guessing either value.
let secretMonth = Math.trunc(Math.random() * 12) + 1;
let secretDay = Math.trunc(Math.random() * 31) + 1;
// keep track of last day and month guess in parent scope
let guessMonth;
let guessDay;
// in click event handler set outer scope variable (no const)
guessMonth = Number(document.querySelector(".guess-month").value);
In terms of checking for victory it could be a helper function.
function checkVictory() {
if (guessDay === secretDay && guessMonth === secretMonth) {
document.getElementById("victory").innerHTML = "victory";
}
}
// in click event handler
if (guessDay === secretDay) {
// update styles
checkVictory();
}
I had to change the conditions for the month. Because after I checked the victory for the day and styles were applied, the same style was supposed to be applied to the month div but only the victory for both was applied. Therefore the game must be done in the predifined order. Guess the day first, then guess the month and the month styling must be applied together with the victory styling. (I removed the victory for the month and applied victory for the game instead.
I'm trying to make a Ping Pong scoreKeeper. Everything is done except the part where the scores are compared and a winner is declared. I'm trying to use the if statement to compare the innerText of two variables and whether their scores match or not. But it's not working.
Here's the Javascript and HTML code I've written.
const p1Score = document.querySelector("#p1Score")
const p2Score = document.querySelector("#p2Score")
const increaseP1Score = document.querySelector("#increaseP1Score")
const increaseP2Score = document.querySelector("#increaseP2Score")
const resetScore = document.querySelector("#resetScore")
const scoreKeeper = document.querySelector("#scoreKeeper")
increaseP1Score.addEventListener('click', function(event) {
p1Score.innerText++
// if (p1Score.innerText == 5 && p1Score.innerText > p2Score.innerText) {
// console.log("Here it works!")
})
increaseP2Score.addEventListener('click', function() {
p2Score.innerText++
})
resetScore.addEventListener('click', function() {
p1Score.innerText = 0;
p2Score.innerText = 0;
})
if (p1Score.innerText == 5 && p1Score.innerText > p2Score.innerText) {
console.log("Working!")
}
<div id="container">
<header id="header">
<h1 id="scoreKeeper">Current Score: <span id="p1Score">0</span> to <span id="p2Score">1</span></h1>
</header>
<footer id="footer">
<button id="increaseP1Score">+1 Player One</button>
<button id="increaseP2Score">+1 Player Two</button>
<button id="resetScore">Reset</button>
</footer>
</div>
You'll see a comment in my JS code. When I try to compare the values there, it somehow works. But I don't know why it doesn't work outside the event listener.
const p1Score = document.querySelector("#p1Score")
const p2Score = document.querySelector("#p2Score")
const increaseP1Score = document.querySelector("#increaseP1Score")
const increaseP2Score = document.querySelector("#increaseP2Score")
const resetScore = document.querySelector("#resetScore")
const scoreKeeper = document.querySelector("#scoreKeeper")
increaseP1Score.addEventListener('click', function(event) {
p1Score.innerText++
checkScore();
// if (p1Score.innerText == 5 && p1Score.innerText > p2Score.innerText) {
// console.log("Here it works!")
})
increaseP2Score.addEventListener('click', function() {
p2Score.innerText++
checkScore();
})
resetScore.addEventListener('click', function() {
p1Score.innerText = 0;
p2Score.innerText = 0;
})
function checkScore(){
if (p1Score.innerText == 5 && p1Score.innerText > p2Score.innerText) {
//console.log("Working!")
alert("working!");
}
}
<div id="container">
<header id="header">
<h1 id="scoreKeeper">Current Score: <span id="p1Score">0</span> to <span id="p2Score">1</span></h1>
</header>
<footer id="footer">
<button id="increaseP1Score">+1 Player One</button>
<button id="increaseP2Score">+1 Player Two</button>
<button id="resetScore">Reset</button>
</footer>
</div>
Your if statement is just running once when the page loads. You could put the functionality... in a function like checkScore() above and call it when you increment the scores. This is more re-usable and a better solution to hard-coding it in each incrementer.