How can I call a function multiple times from different buttons? - javascript

I am building a quiz page using javascript, and want the user to select from a multiple choice and then hit 'Go' to check their answer. Here is the html for the first question:
<p class="question">What is the name of Joey's bedtime penguin pal?</p>
<div class="radio">
<div>
<input type="radio" class="wrong" name="q1">Maurice
</div>
<div>
<input type="radio" class="wrong" name="q1">Clunkers
</div>
<div>
<input type="radio" class="right" name="q1">Hugsy
</div>
<div class="button">
<button type="button" class="go">Go</button>
</div>
<div>
<img src="images/hugsy.jpg" class="image" style="display: none;"
</div>
I have created a function which is called by the Go button which informs the user if they are right or not. Here is the javascript:
let go = document.querySelector('.go');
let correct = document.querySelector('.right');
let showPic = document.querySelector('img');
let remGo = document.querySelector('button');
let choices = document.querySelector('.radio');
let score = 0;
go.addEventListener('click', checkAnswer);
function checkAnswer() {
if (correct.checked) {
showPic.classList.remove('image');
remGo.remove();
choices.innerHTML = '<h2 style="color: green;">Correct!</h2>';
score++;
} else {
remGo.remove();
choices.innerHTML = '<h2 style="color: red;">Incorrect</h2>';
}
}
This code works the way I want it to but only for the first question. When I try to call the function again by clicking 'Go' on question 2 nothing happens.
Is there a way to call a function multiple times using different buttons?

document.querySelector('.go');
only selects the first matching element.
To select all elements with the .go class you need to use querySelectorAll
Then you'll need to assign your event listener to all elements returned.
Here is a minimal example:
let buttons = document.querySelectorAll('.go');
for (const button of buttons) {
button.addEventListener('click', checkAnswer);
}
function checkAnswer() {
console.log("checkingAnswer...")
}
<div class="button">
<button type="button" class="go">Go</button>
</div>
<div class="button">
<button type="button" class="go">Go</button>
</div>
<div class="button">
<button type="button" class="go">Go</button>
</div>

Thanks to those who helped. I have solved my issue now using jquery. This was the code I used:
$(".container").on("click", "button", function (e) {
var container = $(e.target).closest(".container");
if ($(container).find("input:checked").hasClass("right")) {
$(container).find("img").show();
$(container).find("button").remove();
$(container).find(".radio").html('<h2 style="color: green;">Correct!</h2>');
score++;
} else {
$(container).find(".radio").html('<h2 style="color: red;">Incorrect</h2>');
}
});

Related

voting with javascript - form.onsubit

I'm making a website for my school (I'm 16 years old) and I need that when I submit a form, it can change things within the form itself.
I tried to do something using "this", but it didn't work. Can someone help me?
HTML
<form class="form-votacao" name="form-votacao">
<div class="participant-box">
<img src="../images/blank.png" alt="blank" />
<p id="name">participant name undefined</p>
<p id="category">participant category undefined</p>
<p id="talent-info">talent info undefined</p>
<input
type="submit"
value="VOTAR"
name="vote-button"
id="vote-button"
/>
</div>
</form>
JAVASCRIPT
var form_votacao = document.forms["vote-form"];
form_votacao.onsubmit = function (event) {
let fundo = this.querySelector(".participant-box")
fundo.style.background = "green"
};
As there will be several divs with the ".participant-box" class inside the form, I would like you to change only the div that I click on the submit button
First, I changed the button's type as button, because if you make its type as submit, then the form will be submitted, hence the javascript will be useless.
Below is the code using javascript to change the background of the parent div by clicking the button inside it.
Please click on the Run code snippet button for the demo.
const buttons = document.querySelectorAll('.vote-button');
buttons.forEach(button => {
button.addEventListener('click', function() {
this.parentElement.style.backgroundColor = 'green';
});
});
<form class="form-votacao" name="form-votacao">
<div class="participant-box">
<p id="name">participant name undefined</p>
<p id="category">participant category undefined</p>
<p id="talent-info">talent info undefined</p>
<input
type="button"
value="VOTAR"
name="vote-button"
id="vote-button"
class="vote-button"
/>
</div>
<br/><br/>
<div class="participant-box">
<p id="name">participant name undefined</p>
<p id="category">participant category undefined</p>
<p id="talent-info">talent info undefined</p>
<input
type="button"
value="VOTAR"
name="vote-button"
id="vote-button"
class="vote-button"
/>
</div>
<br/><br/>
<div class="participant-box">
<p id="name">participant name undefined</p>
<p id="category">participant category undefined</p>
<p id="talent-info">talent info undefined</p>
<input
type="button"
value="VOTAR"
name="vote-button"
id="vote-button"
class="vote-button"
/>
</div>
</form>
I hope I understood your situation.

Is there a way to make every bouton using a single code

For a school project, I'm coding a porfolio.
I want to use jQuery hide() and show() to have popups that appear after clicking on buttons.
Is there a way, with a single code, to make every HTML element with the class="vignette" and an id="bouton1" show a div with the same number in id (id=popup1).
I don't know if I'm clear, I'm a student in graphic design, and I'm not having a good time.
As far as I can understand from your question, you want to show a modal whose ID is the same number as the button's ID?
You can use this same logic to work with your modal instead
// This regex just gets the number part from the ID
const re = /bouton(\d+)/
$('button.vignette').click(e => {
const res = re.exec(e.target.id)
if(res) {
// "popup" + res[1] gives the popup id
$('#content').html("popup" + res[1])
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class = "vignette" id = "bouton1">B1</button>
<button class = "vignette" id = "bouton2">B1</button>
<button class = "vignette" id = "bouton3">B1</button>
<button class = "vignette" id = "bouton4">B1</button>
<div id = "content"></div>
You can create a function that will be added via addEventListener. Alternatively you can add an onclick attribute to the HTML elements whose click you want to handle.
let activeDiv;
function myClick() {
if (activeDiv) activeDiv.classList.add("invisible");
(activeDiv = document.getElementById(this.id.replace("bouton", "popup"))).classList.remove("invisible");
}
let buttons = document.getElementsByClassName("vignette");
for (let button of buttons) {
button.addEventListener("click", myClick);
}
.invisible {
display: none;
}
<input type="button" id="bouton1" class="vignette" value="First">
<input type="button" id="bouton2" class="vignette" value="Second">
<input type="button" id="bouton3" class="vignette" value="Third">
<input type="button" id="bouton4" class="vignette" value="Fourth">
<input type="button" id="bouton5" class="vignette" value="Fifth">
<input type="button" id="bouton6" class="vignette" value="Sixth">
<input type="button" id="bouton7" class="vignette" value="Seventh">
<input type="button" id="bouton8" class="vignette" value="Eigth">
<input type="button" id="bouton9" class="vignette" value="Ninth">
<div id="popup1" class="invisible">1</div>
<div id="popup2" class="invisible">2</div>
<div id="popup3" class="invisible">3</div>
<div id="popup4" class="invisible">4</div>
<div id="popup5" class="invisible">5</div>
<div id="popup6" class="invisible">6</div>
<div id="popup7" class="invisible">7</div>
<div id="popup8" class="invisible">8</div>
<div id="popup9" class="invisible">9</div>
suppose you have 10 buttons with class vignette then you code would be:
$.each( "button.vignette", function( i, obj) {
$(obj).attr( "id", i ).on('click',function(){
$('#popup'+i).toggle();
});
});
You can replace toggle() function with your code as desired.

selecting all class within this in query

well right now I am doing something like this to find all textbox values which has the same class name.
function generalBottom(anchor) {
var sends = $('input[data-name^="noValues"]').map(function(){
$(this).attr('value',$(this).val());
return $(this).val();
}).get();
}
and i call this function on a onclick of submit button like generalBottom(this)
and I have something like as per my requirement
When I click submit button of User I call a general function passing this as a parameter, but the above code gives me the text values of client as well
["perfect", "hyperjack", "julie", "annoying", "junction", "convulated"], which is undesired, I want only ["annoying", "junction", "convulated"] using my anchor params.
How to do this via my this parameter, I thought to traverse through my tags using children(), parent() but I won't be knowing how many fields user have added as its all dynamic, user can add as many values(text boxes).
I tried this
1) $(anchor).find('.rightAbsNo')
2) $(anchor).find('input[data-name^="noValues"]')
3) $(anchor).find('.rightAbsNo').map(function () {
console.log($(this).find('. showNoButton')); })
None of this worked for me.
My html is somewhat like this, code
<div id="attach0" class="leftbottomno">
<div style="overflow: hidden" class="leftbottomAbsolute" id="">
<form>
<span class="absno"><input type="text" required=""
id="absdelete" data-inputclass="leftbottomAbsoluteNo_class"
value="" class="leftbottomabsolutenotest keys" data-value=""
style="margin-bottom:4px; color: #1c1c1c;"> </span>
<a onclick="addAbsoluteValues(this);" style="margin-left: 50px">
<i class="fa fa-plus-circle color-blue-grey-lighter"></i> </a>
</form>
<a onclick="deleteAbsoluteEmpty(this);> </a><br>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue">
<input type="text" id="nonattach" placeholder="values"
data-name="noValues" data-inputclass="absYes_class" value="annoying"
class="showNoButton showActivity value" data-value="">
<button type="button" onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i></button>
</div>
</div>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue" id=""> <input type="text"
data-name="noValues" data-inputclass="absYes_class" subattribute=""
value="" class="showNoButton showActivity value" data-value="">
<button type="button" onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i></button>
</div>
</div>
<div class="rightAbsNo" id="yesValueattach">
<div class="rightAbsNoValue" id="">
<input type="text" data-name="noValues"
data-inputclass="absYes_class" placeholder="values" subattribute=""
value="junction" class="showNoButton showActivity value"
data-value="" >
<button type="button" style="display: none;"
onclick="generalBottom(this);">
<i class="glyphicon glyphicon-ok"></i>
</button>
</div>
</div>
</div>
</div>
First of all, you need to define a container to the groups with something like :
<div class="container">input groups</div>
<div class="container">input groups</div>
and change <button type='submit'> to <button type='button'> to prevent submitting the form.
Then change your function to this:
function generalBottom(anchor) {
var all_inputs = $(anchor).parent(".container").find("input");
var input = $(anchor).siblings('input').first();
all_inputs.each(function(){
$(this).val(input.val());
});
}
Here's Jsfiddle
first $(anchor).siblings(input) find inputs
then go through each element from first step and return their value
function generalBottom(anchor) {
var input = 'input[data-name^="noValues"]'
var values = $.map($(anchor).siblings(input), (elemnt, index)=>{
return elemnt.value
})
$('#shows').val(values.join())
}
$('button').on('click',function(){
generalBottom(this)
})
hope this helps

pass values from separate divs into a javascript function

I have a form that has three separate divs within it.
<form method="post">
<div id = "f1">
<div class="label">Value 1:</div>
<input type="text" name="name"/>
<button id = "next1" type="button" onclick="checkValue()">Next</button>
</div>
<div id ="f2">
<div class="label">Value 2:</div><br>
<input type="text" name="name"/>
<button type="button" onclick="checkValue()">Next</button><br>
</div>
<div id ="f3">
<div class="label">Value 3:</div><br>
<input type="text" name="name"/>
<button type="button" onclick="checkValue()">Next</button><br>
</div>
</div>
</form>
In my javascript function. I have a fadein and fadeout attached to each div when the next button is pressed. When the "next1" button is pressed the first div will be faded out and the second div will fade in. I want to check the values inputted in the first div when the user presses the first next button. I know how to do this if i just passed in the whole form into my javascript function on the final submit button, but I would like to know how to do this after each next button is pressed.
I also will have more than one value in each of the divs (f1, f2, f3) but for simplicity I only included one value.
EDIT*: further explaintaion
If i did this by passing in the form into checkValue. I could just do an onsubmit = "checkValue()". And then in my JS file, I would just include checkValue(form) as its parameter. If i want to do a check after every single button is pressed, I am not sure how to do this or what to pass in as its parameter.
Simple mock up hopefully to get you one your way.
Fiddle: http://jsfiddle.net/AtheistP3ace/krr3tgLx/1/
HTML:
<form method="post">
<div id="f1" style="display: block;">
<div class="label">Value 1:</div>
<input type="text" name="name" />
<button id="next1" type="button" onclick="checkValue(this)">Next</button>
</div>
<div id="f2">
<div class="label">Value 2:</div>
<br>
<input type="text" name="name" />
<button type="button" onclick="checkValue(this)">Next</button>
<br>
</div>
<div id="f3">
<div class="label">Value 3:</div>
<br>
<input type="text" name="name" />
<button type="button" onclick="checkValue(this)">Next</button>
<br>
</div>
</div>
</form>
JS:
function checkValue (button) {
// Finds the sibling input of the button
var input = $(button).siblings('input');
// Gets input value
var value = input.val();
// Stops showing next div if no value
if (value == '') {
return false;
}
else {
// Finds the parent div holding button and input
var div = $(button).closest('div');
// Fades out current div
div.fadeOut();
// Gets next div and fades it in
div.next().fadeIn();
}
}
CSS:
form > div {
display: none;
}
From my assumptions this is what you are looking for :
Multipart form handler
Basically I wired up each button with a class
<button id = "next1" type="button" class="check-btn">Next</button>
Then I used Jquery to get all those buttons and find the parent div (based on your structure) and then get all the child inputs (can include selects etc). From here you can continue to tweak to perform a check on each type of input etc.
$(document).ready(function(){
$('.check-btn').on('click',function(){
var parent = $(this).parent('div');
var elems = parent.find('input');
alert(elems.length);
//DO checks here for each element
});
});

Show new field after button click

I want to make a field that only shows up after a button click.
Heres my code so far:
<div class="control-group" style="display:none" id="passwordfield">
<label class="control-label">Password:</label>
<div class="controls"><input id="pw" type="password"></div>
</div>
The "display:none" makes it invisible, after that I have my button and a javascript which should change the display to "block", thus making it visible again.
<div style="padding-left: 160px;padding-bottom:20px">
<button class="btn btn-primary" onclick="showPWField()">Log-In</button>
<script>
function showPWField() {
document.getElementByID("passwordfield").style.display = "block";
}
</script>
</div>
But it just doesnt work. The function gets called I tested that with an alert, but I just can't change the style :/
Thanks for help in advance
the error is that getElementByID does not exist, you should use getElementById:
function showPWField() {
document.getElementById("passwordfield").style.display = "block";
}
<div class="control-group" style="display:none" id="passwordfield">
<label class="control-label">Password:</label>
<div class="controls"><input id="pw" type="password"></div>
</div>
<div style="padding-left: 160px;padding-bottom:20px">
<button class="btn btn-primary" onclick="showPWField()">Log-In</button>
<script>
function showPWField() {
document.getElementById("passwordfield").style.display = "block";
}
</script>
</div>
Javascript is a case sensitive,the method you used is getElementByID() won't work in javascript, better to use getElementById()
function showPWField() {
document.getElementById("passwordfield").style.display = "block";
}enter code here

Categories