Vanilla Javascript : how to make a button clickable once only - javascript

I have a quiz app application that I am working on that dynamically creates 2-4 buttons for the answer. However, if you click on an answer, you can keep clicking on the same answer or keep clicking the other answers. I want the user to be able to click one of the buttons but then not be able to keep clicking. caveat though: when a user clicks one of the buttons, a new "Next" button gets created and that one does still need it's click event.
tl;dr
I need dynamically created buttons to be clickable only once but a "Next" button to still be clickable.
Code:
function renderButtons() {
var answerContainer = document.getElementById("answer-buttons");
answerContainer.innerHTML = "";
for (var i = 0; i < 4; i++) {
var button = document.createElement("button");
button.classList.add("btn");
button.setAttribute("id", "answerBtns");
button.hasAttribute("data-correct");
button.setAttribute("data-correct", questions[count].answers[i].correct);
button.onclick = btnclick;
button.textContent = questions[count].answers[i].text;
answerContainer.appendChild(button);
}
}
// if user clicks on button check if true
function btnclick(e) {
e.preventDefault();
var value = event.target.dataset.correct;
scoreBox.textContent = "Score: " + score;
if (value === "true") {
score += 5;
document.body.style.background = "green";
} else {
document.body.style.background = "red";
}
var next = document.getElementById("answer-buttons");
var nextBtn = document.createElement("button");
nextBtn.classList.add("nextBtn");
nextBtn.textContent = "Next";
next.appendChild(nextBtn);
nextBtn.onclick = nextBtnFx;
if you want to see what I'm talking about, the app can be found here:
https://andrethetallguy.github.io/Animal-Quiz/
Thanks!!!

In the handler function nextBtnFx you could disable the button with
this.disabled = "true"
that would make it unclickable after the first click
ref: https://stackoverflow.com/a/17115132/13998159

<!DOCTYPE html>
<html>
<head>
<title>Button</title>
</head>
<body>
<input type="button" id="btn01" value="OK">
<button onclick="disableElement()">Disable</button>
<button onclick="enableElement()">Enable</button>
<script>
function disableElement() {
document.getElementById("btn01").disabled = true;
}
function enableElement() {
document.getElementById("btn01").disabled = false;
}
</script>
</body>
</html>
You can use these functions to disable/enable the buttons.

Related

hiding a button in html [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 10 months ago.
Improve this question
I want to hide a button on the click of another button. So i checked some questions on stack overflow . I used display property and assigned it to hidden. And now I want to unhide it on the click of another button.
I want to increment variable "a" on the click of button1. and when the variable a is greater or equal to three i want to unhide 'button' (The button which has id #again) which is hidden. That means after clicking in button1 twice i want to unhide the button. But It is not working. No mater how many times i click in the button1, it is not working.I used display property and made it to hidden in the html file.
Could anybody say what i want to do here in order to unhide the button when clicked on the button1 twice.
let a = 1;
let button = document.querySelector("#again");
let button1 = document.querySelector("#again1");
button1.onclick = () => {
a++;
}
if (a >= 3) {
button.style.display = "block";
}
<button id="again" style="display:none;">click me</button>
<button id="again1">here</button>
<script src="practise.js"></script>
Your if block is calculated just once in the beginning when the browser parses through the js file. Instead, you want to check it every time button1 is clicked. Move it inside the event listener.
let a = 1;
let button = document.querySelector("#again");
let button1 = document.querySelector("#again1");
button1.onclick = () => {
a++
if (a >= 3) {
button.style.display = "block";
}
}
<button id="again" style="display:none;">click me</button>
<button id="again1">here</button>
spelling onclick
if needs to go inside the function
let a = 1;
let button = document.querySelector("#again");
let button1 = document.querySelector("#again1");
button1.onclick = () => {
a++;
if (a >= 3) {
button.style.display = "block";
}
}
<button id="again" style="display:none;">click me</button>
<button id="again1">here</button>
<script src="practise.js"></script>
Alternative using eventListener and hidden
let a = 1;
let button = document.querySelector("#again");
let button1 = document.querySelector("#again1");
button1.addEventListener("click", () => {
a++;
button.hidden = a < 3
})
<button id="again" hidden>click me</button>
<button id="again1">here</button>
<script src="practise.js"></script>
Just put the if condition inside the onClick() function .
let a = 1;
let button = document.querySelector("#again");
let button1 = document.querySelector("#again1");
button1.onclick = () => {
a++
if (a > 2) {
button.style.display = "block";
}
}
<button id="again" style="display:none;">click me</button>
<button id="again1">here</button>
Try this simple:
var button = document.getElementById("again1")
let button1 = document.querySelector("#again");
count = 0;
button.onclick = function() {
count += 1;
if (count >= 3) {
button1.style.display = "block";
}
button.innerHTML = "Click me: " + count;
};
<button id="again" style="display:none;">click me</button>
<button id="again1">here</button>
Here in the above responses 'display: hidden' means it will occupy the space in UI where as 'display: none' means it won't occupy the space. Now you can decide which one to use as well

Display button value in div onclick. Javascript/HTML

I have a set of buttons with different values. When I press a button I want the value of the button to be displayed in the div picked_letters, but nothing is showing. The code is divided in an html file and a javascript file.
html file looks like this:
<body>
<script src="cases.js"></script>
<div id="written_word">
</div>
<div id="list_of_letters">
</div>
<div id="picked_letters">
</div>
</body>
and the onclick in the javascript file looks like this:
for(let i = 0; i < 26; i++) {
let btn = document.createElement("button");
btn.style.background = 'silver';
btn.style.width = '15%';
btn.style.fontWeight = 'bold';
btn.style.fontSize = '135%';
btn.style.display = 'inline-block';
btn.value = case_values[i];
btn.onmouseover = function (){
btn.style.background = 'goldenrod';
}
btn.onmouseleave = function() {
btn.style.background = 'silver';
}
btn.onclick = function() {
btn.style.background = 'darkgrey';
btn.disabled = true;
btn.innerHTML = String(btn.value);
document.getElementById("picked_letters").innerHTML =
String(btn.value);
}
btn.innerHTML = String(i+1);
document.body.appendChild(btn);
}
The button changes color, becomes disabled and displays the value inside the button but it's the last line with getting the button value into a div that I am having problems with. Have looked around but haven't found a solution that solves this problem.
##Edit: The problem seems to have been fixed when I put the script import at the end of the body (and some other minor changes).
Where are you setting the value of the button?
Can you share the button code?
Does your button look like this?
<button>My Button</button>
or do you set your value like this?
<button value="my button value">My button</button>
If you have a value set - you can do this:
btn.onclick = function () {
console.log(btn.innerHTML);
btn.style.background = "darkgrey";
btn.disabled = true;
document.getElementById("picked_letters").innerHTML = btn.value;
};
If you don't have a value set - using btn.value won't return anything.
I would try adding a value to your button if you dont have one. Or if you want to call the innerhtml of the button:
<button>My button</button>
and then
btn.onclick = function () {
console.log(btn.innerHTML);
btn.style.background = "darkgrey";
btn.disabled = true;
document.getElementById("picked_letters").innerHTML = btn.innerHTML;
};
The code above is perfectly fine, the is definately being displayed in the "picked_letters" div, but the value of btn is ""(empty) so the value set to the div is also empty. To solve this issue, add value to the button by doing:-
. and the issue will be gone.
const btn = document.querySelector('#btn')
btn.onclick = function() {
btn.style.background = 'darkgrey';
btn.disabled = true;
console.log(btn.value)
btn.innerHTML = String(btn.value);
document.getElementById("picked_letters").innerHTML =
String(btn.value);
}
<body>
<div id="written_word">
</div>
<div id="list_of_letters">
</div>
<div id="picked_letters">
</div>
<button id='btn' value='5'>Tap me</button>
</body>

object oriented quiz application

I am trying to build a simple quiz app with javascript, and it goes all well, but when it comes to validation something weird happens, it validates my code twice! Once with the correct answer of previous question and another time with the correct one for the current one!
Can anyone please check my code out? Finds where the bug is? Thanks so much
(function () {
// Question Function Constructor
const Question = function (question, answers, correct) {
this.question = question;
this.answers = answers;
this.correct = correct;
}
// Questions Prototypes
Question.prototype.displayQuestion = function () {
// getting html elements
const qHolder = $('#question').get(0);
const list = $('#listOfAnswers').get(0);
// show questions
$(qHolder).empty();
$(qHolder).append(this.question);
// show answers
this.answers.forEach(answer => {
let li = ` <li>
<label for="${answer}">
<input class="option" type="radio" name="answer" value="${answer}" id="${answer}"> ${answer}
</label>
</li>`;
$(list).append(li);
});
}
Question.prototype.validate = function (ans, callback) {
let score;
if (ans === this.correct) {
console.log('**** TRUE ****');
score = callback(true);
console.log(`YOURE ANSWERE === ${ans}`);
} else {
console.log('---- FALSE ----');
score = callback(false);
console.log(`YOURE ANSWERE === ${ans}`);
console.log(`CORRECT ANSWER IS =====> ${this.correct}`);
}
this.displayScore(score);
}
Question.prototype.displayScore = function (score) {
console.log(`your current score is : ${score}`);
console.log(`=======================================================`);
}
// instance of Questions
const q1 = new Question('what\'s max\'s name?', [
'lax',
'max',
'wax',
'pax',
], 1);
const q2 = new Question('2+2?', [
'4',
'12',
'99',
'none',
], 0);
const q3 = new Question('... jobs?!', [
'andrew',
'what?!',
'why?!',
'steve',
], 3);
const q4 = new Question('which one is not a programming language?', [
'javascript',
'python',
'apple',
'c#',
], 2);
// Array of Questions
const Questions = [q1, q2, q3, q4];
// console.log(Questions);
function score() {
let sc = 0;
return function (correct) {
if (correct) {
sc++;
}
return sc;
}
}
let keepScore = score();
function nextQuestion() {
// getting the list and emptying the it for new list items
const list = $('#listOfAnswers');
$(list).empty();
// alerting in the console that its a new question
console.log('A NEW QUESTION');
//generate a random number
let n = Math.floor(Math.random() * Questions.length);
console.log(`random number generated --> ${n}`);
// display the question
Questions[n].displayQuestion();
console.log(`answer to the question ==>${Questions[n].correct}`);
// validating the answer by click on the submit button
const submitBtn = $('#submitBtn');
submitBtn.on('click', function (e) {
e.preventDefault();
let options = $('.option');
for (i = 0; i < options.length; i++) {
const option = options[i];
if ($(option).is(':checked')) {
// console.log(option);
userAnswerIndex = i;
// validation
Questions[n].validate(userAnswerIndex, keepScore);
}
}
})
}
// displaying next question by clicking next
const nextQbtn = document.querySelector('#next');
nextQbtn.addEventListener('click', nextQuestion);
nextQuestion();
})();
here is my HTML Markup, thanks again --->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/style.css">
<title>Quiz App</title>
</head>
<body dir="rtl">
<header>
<h3>welcome to the quiz app</h3>
</header>
<div class="container">
<div id="card">
<header>
<p id="question">
<!-- Question displays here -->
</p>
</header>
<form id="answers">
<ol id="listOfAnswers">
<!-- answers will generate here -->
</ol>
</form>
<button type="submit" id="submitBtn">submit</button>
<button id="next">next!</button>
</div>
</div>
<script src="http://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"></script>
<script src="/quiz.js"></script>
</body>
</html>
I was not able to run the code to be sure since I didn't have the relevant markup but from reading it seems like problem can be in this block of code
submitBtn.on('click', function (e) {
e.preventDefault();
let options = $('.option');
for (i = 0; i < options.length; i++) {
const option = options[i];
if ($(option).is(':checked')) {
// console.log(option);
userAnswerIndex = i;
// validation
Questions[n].validate(userAnswerIndex, keepScore);
}
}
})
Let's go to third line which is let options = $('.option'); now again, since I don't have markup I can be wrong but this seems a bit fishy. You are selecting all the elements with class option and then iterating over them. In each iteration you check if option is checked, if it is you validate it.
Now in only way in which you can confirm that validate will run only once is when $('.option') contains only one selected element. But if you have multiple selects or input elements with class option and user has selected multiple of them you might get more than one selected elements. In that case you might see question being validated more than one time
Your problem is that every time the user presses the next button a new click event handler is added to the submit button.
You would think that since it is the same function that wouldn't happen but you are actually doing it again and again. If the user clicks three times the next button before he submits it will trigger the validation functionality three times and so on...
You can handle this by either removing all other click event handlers every time you add your event. (The simplest one)
You can do that with the jquery off like this
submitBtn.off().on('click', function (e) {
Where you just unbind all click event handlers before you add your new one. (This way you will always have one click event handler on your submit button). Of course If you want to add other click event handlers to this button (not very often but maybe sometimes you want to do that) you should use it with caution
Another way to go is just not add the click event handler every time the next button is pressed. Just add the event once outside of your NextQuestion function like this (outside from document ready if you want or inside it doesn't matter)
$(document).on("click", "#submitBtn", function(e) {
e.preventDefault();
var options = $('.option');
for (i = 0; i < options.length; i++) {
var option = options[i];
if ($(option).is(':checked')) {
// console.log(option);
userAnswerIndex = i;
// validation
Questions[n].validate(userAnswerIndex, keepScore);
}
}
});
or
function nextQuestion(){
// do everything else
}
var submitBtn = $('#submitBtn');
submitBtn.on('click', function (e) {
e.preventDefault();
var options = $('.option');
for (i = 0; i < options.length; i++) {
var option = options[i];
if ($(option).is(':checked')) {
// console.log(option);
userAnswerIndex = i;
// validation
Questions[n].validate(userAnswerIndex, keepScore);
}
}
})

Reset only 1 radio group with OnClick Event

I have a form that has several radio groups. There is one particular radio group that I want the user to be able to reset without resetting the entire form. I created a button whose value is Reset Participation Levels. Here is the function for the click event of that button:
<script>
function ParticipationReset(){
document.getElementById('SponsorshipParticipaton_0').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_1').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_2').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_3').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_4').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_5').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_6').removeAttribute('disabled');
document.getElementById('ExhibitorParticipaton_0').removeAttribute('disabled');
document.getElementById('ExhibitorParticipaton_1').removeAttribute('disabled');
document.getElementById('SponsorshipParticipaton_0').checked = false;
document.getElementById('SponsorshipParticipaton_1').checked = false;
document.getElementById('SponsorshipParticipaton_2').checked = false;
document.getElementById('SponsorshipParticipaton_3').checked = false;
document.getElementById('SponsorshipParticipaton_4').checked = false;
document.getElementById('SponsorshipParticipaton_5').checked = false;
document.getElementById('SponsorshipParticipaton_6').checked = false;
document.getElementById('ExhibitorParticipaton_0').checked = false;
document.getElementById('ExhibitorParticipaton_1').checked = false;
}
</script>
However, when I click the button, all radio buttons in the form are reset even if they are not specified in the function. The link to the page is www.pfacmeeting.org/2016/exhibitorform.htm.
Any advice would be appreciated. Thank you
cdr6545
this is happening because the button is set as "reset" , for a particular reset, please change the line to:
<input type="button" name="ResetSponsor" id="ResetSponsor" value="Reset Sponsorship Participation" onclick="javascript:SponsorshipReset(this);" />
type="button"
You can reset all of the radio buttons in a group with a simple for loop like this:
var elements = document.getElementsByName("SponsorshipParticipation");
for(var i = 0; i < elements.length; i++) {
elements[i].removeAttribute("disabled");
elements[i].checked = false;
}
Or if you want to reset all radio button groups with a name ending in "Participation", you could change the first line to this:
var elements = document.querySelectorAll("input[name$='Participation']");
Here is an example of how you could implement the code I provided above:
HTML
<input type="button" value="Reset" onclick="resetParticipation()" />
JavaScript
function resetParticipation() {
var elements = document.querySelectorAll("input[name$='Participation']");
for(var i = 0; i < elements.length; i++) {
elements[i].removeAttribute("disabled");
elements[i].checked = false;
}
}

Javascript function executes only after second hover

I have got a small javascript function and a piece of html code where i have a button, and I want that whenever user hovers that button, a little box to appear.Everything seems to be working great,despite that my function executes only after I hover that button for the 2 time(after the page has just loaded and I try to use my function for the 1 time, later everything executes after a firs hover).So what can I do about it?
HTML code
<body>
<div id = "searchBox">
<p id = "paragraph"><input type = "text" name = "serachBar"/>
<input type = "button" value = "szukaj" name = "search"/>
</p>
<div id = "searchButton">Szukaj</div>
</div>
</body>
and javascript itself
<script type = "text/javascript">
function popUp(menu){
var searchBox = document.getElementById(menu).style;
var searcButton = document.getElementById('searchButton');
if(!searchBox || searchBox.display == "none"){
searchBox.display = "block";
}
else {
searchBox.display = "none";
}
};
</script>
Change your if statement like this:
function popUp(menu) {
var searchBox = document.getElementById(menu);
var searcButton = document.getElementById('searchButton');
if (searchBox) {
if(searchBox.style.display == ""){
searchBox.style.display = "block";
}
else {
searchBox.style.display = "";
}
}
};
The original value will be "" instead of "none".
I'm making the assumption that the CSS setting is to display:"none".
I also moved the searchBox condition. If it isn't found, you don't want to set properties at all.
<p> is a flow element and can't contain <input>s.
Besides, your function instructs to toggle hidden state, rather than show box on mouseover. Therefore, the box will hide on first hover, and reappear on the second one.
You probably want to define mouseover and mouseout event listeners.

Categories