Javascript Quiz - problems reaching the next sibling through next() method on jQuery - javascript

I'm creating a quiz with JavaScript where I'm trying to use the jQuery to make 1 question appear at a time. I was able to get the html to show only one question on the page, by hiding the other elements, but for some reason I can't get the next sibling to show.
The jQuery API Documentation says the next() method reaches for the sibling element, but I’m not sure where the problem is.
My jQuery code is.
function main()
{
$('.slide').hide();
$('.active-slide').show();
var currentSlide = $('.active-slide')
var nextSlide = currentSlide.next();
$('.btnNext').click(function() {
currentSlide.removeClass('active-slide');
nextSlide.addClass('active-slide');
})
}
$(document).ready(main);
My HTML is.
<div class="slide active-slide">
<h3>Question 1: Answer is A! </h3>
<input type="radio" name="q1" value="correct">A</input><br>
<input type="radio" name="q1" value="incorrect">B</input><br>
<input type="radio" name="q1" value="incorrect">C</input><br>
<input type="radio" name="q1" value="incorrect">D</input>
<input type="button" class="btnNext" value="Next">
</div>
<div class="slide">
<h3>Question 2: Answer is B! </h3>
<input type="radio" name="q2" value="incorrect">A</input><br>
<input type="radio" name="q2" value="correct">B</input><br>
<input type="radio" name="q2" value="incorrect">C</input><br>
<input type="radio" name="q2" value="incorrect">D</input>
<input type="button" class="btnNext" value="Next">
</div>
The console on Chrome shows no errors which makes it harder to find.
Thanks for any help.

The first issue is the result of a jQuery selector is not live meaning if the selector properties of an element changes the cached object will not get updated. So you need to find the active slide inside the event handler.
The second issue could be related to css, since you are using hide() to hide the element, it will be using an inline display rule, but to show the element back you are only setting the active-slide class which might be having a lower order rule.
function main() {
$('.btnNext').click(function() {
var currentSlide = $('.active-slide').removeClass('active-slide');
currentSlide.next().addClass('active-slide');
})
}
$(document).ready(main);
.slide {
display: none;
}
.slide.active-slide {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="slide active-slide">
<h3>Question 1: Answer is A! </h3>
<input type="radio" name="q1" value="correct">A
<br>
<input type="radio" name="q1" value="incorrect">B
<br>
<input type="radio" name="q1" value="incorrect">C
<br>
<input type="radio" name="q1" value="incorrect">D
<input type="button" class="btnNext" value="Next">
</div>
<div class="slide">
<h3>Question 2: Answer is B! </h3>
<input type="radio" name="q2" value="incorrect">A
<br>
<input type="radio" name="q2" value="correct">B
<br>
<input type="radio" name="q2" value="incorrect">C
<br>
<input type="radio" name="q2" value="incorrect">D
<input type="button" class="btnNext" value="Next">
</div>

Your problem is that you only run the jQuery hide and show functions once; changing the classes of your divs isn't going to run that code again. Your jQuery needs to do something like this JSFiddle.
This way, the shown div is updated each time the classes are changed.

Related

changing the input class of a radio button dynamically with javascript

I am trying to make a small question web app using javascript/html. what I am trying to do is, assign a class to each of the radio buttons for each question-i.e. all the radio buttons for question 1 will have an input class of "question1" and 2 will have a class of "question2" and so on.
Because I don't know how many questions I will have, I was wondering if there was a way to achieve this dynamically through javascript using element.classList.add and increment the value of the question by 1 each time. I have received a response using jquery, but I was wondering if there was also a way to achieve this using pure javascript.
After some research, I have tried accessing all the elements inside a form using "form.elements" however it does not seem to be working.
HTML:
<form name="quizForm">
<div class="content">
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
</form>
Javascript:
//counting the index of the class
let ind =0;
//access the named elements within the form
let elements = form.elements;
for(i=0;i<elements.length;i++){
element.classList.add(`quiz${ind+1}`)
}
Any information towards the right direction is greatly appreciated. Thank you.
I apologise for my initial question as I am realising that I have been unclear explaining some aspects of the issue that I was having. I managed to solve the problem. When I ask questions in the future, I will make sure I double check my code so that it is working. Posting an solution here for those who are interested and in the hopes that it will help someone.
What I did:
make a variable that keeps a track of the class number (ind)
using "querySelectorAll" I can select all the elements with the class "quiz"
loop through the returned array with forEach, increment the "ind" variable
select all the inputs that are inside each "quiz"
the "quiz" loop through those inputs and add a class to the input elements
HTML:
<div class="quiz">
<p>Question 1</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 2</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
<div class="quiz" style="display: none;">
<p>Question 3</p>
<input type="radio" name="answer" value="1">
<input type="radio" name="answer" value="2">
<input type="radio" name="answer" value="3">
</div>
Javascript:
const quizes = document.querySelectorAll('.quiz');
//a variable to increment the classes
let ind = 0;
quizes.forEach(function(element){
ind++;
let inputs = element.querySelectorAll('input');
inputs.forEach((input)=>{
input.classList.add(`question${ind}`)
})
//to test on the console
console.log(inputs)
})
All the radio button inputs for question 1 have the same "question1" class.

Default checked button

Below code is html produced from opencart 2
No radio button is selected when loading page.
How can i have selected the Value="2" as default checked. (javascript or CSS)
<div id="payment-custom-field1" class="form-group custom-field" data-sort="0">
<label class="control-label">Invoice</label>
<div id="input-payment-custom-field1">
<div class="radio">
<label>
<input type="radio" value="2" name="custom_field[1]">
Receipt
</label>
</div>
<div class="radio">
<label>
<input type="radio" value="1" name="custom_field[1]">
Invoice
</label>
</div>
</div>
</div>
Solution with javascript
(function() {
document.getElementsByName("custom_field[1]")[0].checked=true;
})();
<input type="radio" id="sample" value="2" name="custom_field[1]">
Receipt
</label>
Using javascript:
document.getElementById("sample").checked = true;
Using html:
You can simply add checked attribute to your html element
Using the element name:
(function() {
document.getElementsByName("custom_field[1]")[0].checked=true;
})();
https://jsfiddle.net/pandiyancool/vb73q59w/
You can simply add checked attribute
<input type="radio" value="2" name="custom_field[1]" checked>
The solution with javascript was the below code:
document.getElementsByName("custom_field[1]")[0].checked=tru‌​e;
Thank you Pandiyan Cool

Java script radio buttons

I'm using Javascript and radio buttons for the first time.
I need to know how to assign the script to each radio button that is selected? there seem to be a few ways of doing this and its just getting confusing!
Each question has 4 radio buttons to select from and I need to gather the answers at the end!
Any help appreciated
Just add an event listener to the radio buttons and maintain a mapping where you could store all your answers to.
let answers = {}
$('input[type=radio]').on('click', function (event) {
let question = event.currentTarget.name
let answer = event.currentTarget.value
answers[question] = answer
document.getElementById('result').innerHTML = JSON.stringify(answers, null, 2)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="question-block">
<div class="question">
1. Which one is the biggest?
</div>
<div class="answers">
<form>
<input type="radio" name="1" value="1" checked> Elephant<br>
<input type="radio" name="1" value="2"> Whale<br>
<input type="radio" name="1" value="3"> Giraffe
</form>
</div>
</div>
<div class="question-block">
<div class="question">
2. Which one is the smallest animal?
</div>
<div class="answers">
<form>
<input type="radio" name="2" value="1" checked> Bacteria<br>
<input type="radio" name="2" value="2"> Virus<br>
<input type="radio" name="2" value="3"> Ant
</form>
</div>
</div>
<div id="result">
</div>

Show/Hide divs on Form with multiple radio groups

I'm trying to create a form with 10+ questions on it.
Each question with have three answer options, "Yes" "No" "Not applicable" which are chosen via radio buttons.
When "No" is selected a div is shown with additional information, this would be applicable for each question.
Not being great at Javascript I consulted Stack Overflow, found something and have failed miserably to amend it:
<script type="text/javascript">
function yesnoCheck() {
if (document.getElementById('noCheck').checked) {
document.getElementById('ifNo').style.display = 'block';
}
else document.getElementById('ifNo').style.display = 'none';
}
</script>
<p>Question 1</p>
<input type="radio" onclick="javascript:yesnoCheck();" name="q1" id="yesCheck"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q1" id="noCheck"> No <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q1" id="naCheck"> Not applicable <br>
<div id="ifNo" style="display:none">
<p>Recommendation goes here</p>
</div>
<h2>Section header</h2>
<p>Question 2</p>
<input type="radio" onclick="javascript:yesnoCheck();" name="q2" id="yesCheck"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q2" id="noCheck"> No <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q2" id="naCheck"> Not applicable <br>
<div id="ifNo" style="display:none">
<p>Recommendation goes here</p>
</div>
<p>Question 3</p>
<input type="radio" onclick="javascript:yesnoCheck();" name="q3" id="yesCheck"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q3" id="noCheck"> No <br>
<input type="radio" onclick="javascript:yesnoCheck();" name="q3" id="naCheck"> Not applicable <br>
<div id="ifNo" style="display:none">
<p>Recommendation goes here</p>
</div>
This only works on the first question but not the others.
The intention is for this to go in a rails app and the number of questions could be large (more than 10) so was trying to create a short piece of code that would work on all questions.
Any help, from someone who knows what they're talking about (i.e. not me) would be extremely appreciated.
Do not use same id more than once. Here https://jsfiddle.net/o2kdb8ej/ you can find simple solution using jQuery, without any ids specified applicable for any number of questions. The main idea is to specify value for each radio button, handling change event for each radio button on the page, and in that handler check its value, and according to its value hide or show specified p element.
Is not valid html to have more than one element with the same id. You have multiple elements with id id=noCheck. When javascript code is executed the function getElementById() is looking for a single element, and returns the first one, that's why only the first div is showing.
You could assign the same name to every "No" radiobutton and use getElementsByName() instead. This returns a collection of elements, and then you could iterate over them to show all divs that must be shown.
Using same id for different elements in a html code is a bad way. You need to create different id's for different questions like:
<p>Question 1</p>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q1" id="yesCheck1"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q1" id="noCheck1"> No <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q1" id="naCheck1"> Not applicable <br>
<div id="ifNo1" style="display:none">
<p>Recommendation goes here</p>
<h2>Section header</h2>
<p>Question 2</p>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q2" id="yesCheck2"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q2" id="noCheck2"> No <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q2" id="naCheck2"> Not applicable <br>
<div id="ifNo2" style="display:none">
<p>Recommendation goes here</p>
<p>Question 3</p>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q3" id="yesCheck3"> Yes <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q3" id="noCheck3"> No <br>
<input type="radio" onclick="javascript:yesnoCheck(this.id);" name="q3" id="naCheck3"> Not applicable <br>
<div id="ifNo3" style="display:none">
<p>Recommendation goes here</p>
</div>
now in your javascript code:
function yesnoCheck() {
newId = id.split('k')[1]; //this will give 2 in "q2" (splitting)
var noCheck = "noCheck"
newNoCheck = noCheck.concat(newId); //if the newId is 2 then it will be "noCheck2"
var ifNo = "ifNo"
newifNo = ifNo.concat(newId); //if the newId is 2 then it will be "ifNo2"
if (document.getElementById(newNoCheck).checked) {
document.getElementById(newifNo).style.display = 'block';
}
else document.getElementById(newifNo).style.display = 'none';
}
You can find the working jsfiddle here

Finding value of closest set of radio buttons

I've got multiple sets of radio buttons and am trying to use the .find() function to dynamically find the value of radio buttons in the same grouping.
However, it keeps returning undefined.
<fieldset>
<div id="border1">
<input id="radio1a" type="radio" id="set1" class="animals radio" value="Zebra">
<input id="radio1b" type="radio" id="set1" class="animals radio" value="Lion">
</div>
<div id="border2">
<input id="radio2a" type="radio" id="set2" class="fruit" value="Oranges">
<input id="radio2b" type="radio" id="set2" class="fruit" value="Grapes">
</div>
</fieldset>
<fieldset>
<div class="border1">
<input id="radio3a" type="radio" id="set3" class="animals radio" value="Monkey">
<input id="radio3b" type="radio" id="set3" class="animals radio" value="Parrot">
</div>
<div class="border2">
<input id="radio4a" type="radio" id="set4" class="fruit radio" value="Bananas">
<input id="radio4b" type="radio" id="set4" class="fruit radio" value="Cherries">
</div>
</fieldset>
(Sorry, didn't mean to put the same IDs. Was a copy/paste.)
I'm trying to use jquery to dynamically find the values:
$(".animals .radio").change(function()
{
alert($(this).closest('fieldset').find('.fruit').val());
etc.
}
But it keeps returning undefined
Also tried:
$(this).closest('fieldset').find('.fruit:checked').val()
Is there another way I should be approaching this?
I don't want to have to write code for every single set of radio buttons.
$(".animals .radio") is not the query you are looking for, it should be $(".animals.radio") (no white space between classes).
$(".animals .radio") looks for an element with class "radio" inside an element with class "animals".
It should .animals.radio, not .animals .radio.
.animals.radio means these two classes belongs to same element. (in your case this is right)
.animals .radio means .animals is ancestor of .radio.
$(".animals.radio").change(function() {
alert($(this).closest('fieldset').find('.fruit').val());
});
AND ONE THINK, YOUR CODE HAVE DUPLICATE IDS, AVOID IT.
How about not using id="" twice, and setting a type="radio" on those inputs for starters ?
You are also using the same ID for multiple elements, stop that ?
It should probably be :
<fieldset>
<div id="border1">
<input type="radio" id="radio1a" name="set1" class="animals radio" value="Zebra" />
<input type="radio" id="radio1b" name="set1" class="animals radio" value="Lion" />
</div>
<div id="border2">
<input type="radio" id="radio1c" name="set2" class="fruit" value="Oranges" />
<input type="radio" id="radio1d" name="set2" class="fruit" value="Grapes" />
</div>
</fieldset>
<fieldset>
<div class="border1">
<input type="radio" id="radio2a" name="set3" class="animals radio" value="Monkey" />
<input type="radio" id="radio2b" name="set3" class="animals radio" value="Parrot" />
</div>
<div class="border2">
<input type="radio" id="radio2c" name="set4" class="fruit radio" value="Bananas" />
<input type="radio" id="radio2d" name="set4" class="fruit radio" value="Cherries" />
</div>
</fieldset>​​​​​​​​​​
To get both values :
$('input[type="radio"]').on('change', function() {
$(this).closest('fieldset').find('.fruit').each(function() {
alert(this.value);
});
}​);​
To get only the one that is checked :
$('input[type="radio"]').on('change', function() {
var elm = $(this).closest('fieldset').find('.fruit').filter(':checked');
alert(elm.value);
}​);​
$(".animals .radio") is getting you all the elements with class radio that have parents with class animals.
You want elements with both classes animals and radio, which is like $(".animals.radio")

Categories