JavaScript - How to show the next div and hide the previous one? - javascript

I am creating a simple quiz and would like to know how to show one question at a time but only using JavaScript. I do not know jQuery. Essentially, I would like the first question to be shown automatically.
Here is an example of what my HTML looks like:
<div id="q0">
<li>
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</li>
</div>
<div id="q1" style="visibility:hidden">
<li>
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</li>
</div>
<div id="q2" style="visibility:hidden">
<li>
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</li>
</div>
I currently don't have script for showing next div and hiding the previous one because I don't know how to even start.
I'm looking to have it put into this form...
function nextQ(){
// code
}
... and for it to be called by this button:
<button onclick="next()">Next Question</button>
I am really new to HTML and JavaScript and would appreciate any help.
Thanks.

Pure JavaScript version (config):
var showing = [1, 0, 0];
var questions = ['q0', 'q1', 'q2'];
function next() {
var qElems = [];
for (var i = 0; i < questions.length; i++) {
qElems.push(document.getElementById(questions[i]));
}
for (var i = 0; i < showing.length; i++) {
if (showing[i] == 1) {
qElems[i].style.display = 'none';
showing[i] = 0;
if (i == showing.length - 1) {
qElems[0].style.display = 'block';
showing[0] = 1;
} else {
qElems[i + 1].style.display = 'block';
showing[i + 1] = 1;
}
break;
}
}
}
<div id="questions">
<div id="q0">
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</div>
<div id="q1" style="display: none">
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</div>
<div id="q2" style="display: none">
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</div>
</div>
<button onclick="next()">Next Question</button>
Pure JavaScript version (no config):
function next() {
var qElems = document.querySelectorAll('#questions>div');
for (var i = 0; i < qElems.length; i++) {
if (qElems[i].style.display != 'none') {
qElems[i].style.display = 'none';
if (i == qElems.length - 1) {
qElems[0].style.display = 'block';
} else {
qElems[i + 1].style.display = 'block';
}
break;
}
}
}
<div id="questions">
<div id="q0">
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</div>
<div id="q1" style="display: none;">
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</div>
<div id="q2" style="display: none;">
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</div>
</div>
<button onclick="next()">Next Question</button>
jQuery version:
$(function() {
$('.next').on('click', function() {
$('#questions>div').each(function() {
var id = $(this).index();
if ($(this).is(':visible')) {
$(this).hide();
if (id == $('#questions>div').length - 1) {
$('#questions>div').eq(0).show();
} else {
$('#questions>div').eq(id + 1).show();
}
return false;
}
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="questions">
<div id="q0">
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</div>
<div id="q1" style="display: none">
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</div>
<div id="q2" style="display: none">
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</div>
</div>
<button class="next">Next Question</button>

Though I agree with #Bitwise on using jQuery instead on javascript alone to ensure cross-browser compatibility. But since you insist on using javascript, here's what you should do.
1) Ensure that your <li>'s are enclosed in a container tag first (say, <ul>) so you iterate only through desired list.
2) use display:none property instead of visibility:hidden. visibility:hidden simply hides an element, but it will still take up the same space as before. display:none hides an element, and it will not take up any space.
Here's the updated code.
HTML:
<ul id="listContainer">
<div id="q0">
<li style="display:list-item">
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A"/>Green<br/>
<input type="radio" name="question0" value="B"/>Blue<br/>
<input type="radio" name="question0" value="C"/>Red<br/>
<input type="radio" name="question0" value="D"/>Purple<br/>
</li>
</div>
<div id="q1" >
<li style="display:none">
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A"/>Water<br/>
<input type="radio" name="question1" value="B"/>Cement<br/>
<input type="radio" name="question1" value="C"/>Trees<br/>
<input type="radio" name="question1" value="D"/>The Sky<br/>
</li>
</div>
<div id="q2" >
<li style="display:none">
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A"/>24<br/>
<input type="radio" name="question2" value="B"/>22<br/>
<input type="radio" name="question2" value="C"/>16<br/>
<input type="radio" name="question2" value="D"/>48<br/>
</li>
</div>
</ul>
<button id="next">next</button>
Javascript:
document.getElementById('next').addEventListener("click",function(){
var listContainer = document.getElementById("listContainer");
var listItem = listContainer.getElementsByTagName("li");
for (var i=0; i < listItem.length-1; i++)
{
if(listItem[i].style.display == "list-item")
{
listItem[i].style.display = "none";
listItem[i+1].style.display = "list-item";
break;
}
}
});
Here's the fiddle.
Cheers!

I would twist the code a little. Add question class to every div which acts as question i.e .question { display:none }. Add active class to first question (i.e. .active{display:block}, it shows the first question. Look for all divs with question class and add them to a variable, with every next button pressed,remove active class from current question add active class to next div with class question using classList.add and classList.remove of Javascript until last question is reached. Count keeps the current question's number.
I've done it in the codepen http://codepen.io/dwanirdesh/pen/EaQOPg
Or code directly from below:
<div id="q0" class="question active">
<li>
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</li>
</div>
<div id="q1" class="question" >
<li>
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</li>
</div>
<div id="q2" class="question">
<li>
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</li>
</div>
<button onclick="next()">Next Question</button>
## CSS ##
.question{
display:none
}
.active{
display:block
}
## JAVASCRIPT ##
var questionNumber=0;
var questions=document.querySelectorAll('.question');
function next(){
questionNumber++;
if(questions.length>questionNumber)
{
document.querySelector('.active').classList.remove('active');
questions[questionNumber].classList.add('active');
}
}

Here is the java script function code. For this to work, you need to make sure that the div display property to be set as or in the html code. Also you need to name the id of the button to be "next" so that it can be hidden on reaching the last button.
function nextQ(){
var blockFound = 0;
var lastQuestion = 0;
var divs = document.getElementsByTagName("div");
for(var i = 0; i < divs.length; i++){
if ( blockFound == 1){
blockFound = 0;
divs[i].style.display = 'block';
}else if ( divs[i].style.display == 'block' ){
if ( i + 2 == divs.length){
lastQuestion = 1;
}
blockFound = 1;
divs[i].style.display = 'none';
}
}
if ( lastQuestion == 1){
document.getElementById('next').style.visibility = 'hidden';
}
}
Html code here.
<div id="q0" style="display:block">
<li>
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</li>
</div>
<div id="q1" style="display:none">
<li>
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</li>
</div>
<div id="q2" style="display:none">
<li>
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</li>
</div>
<button id="next" onclick="nextQ()">Next Question</button>

Is it what you need?
<div id="q0">
<li>
<h3>1. The color of the sky is... </h3>
<input type="radio" name="question0" value="A">Green<br>
<input type="radio" name="question0" value="B">Blue<br>
<input type="radio" name="question0" value="C">Red<br>
<input type="radio" name="question0" value="D">Purple<br>
</li>
<button class="next" onclick="goNext(0)">Next Question</button>
</div>
<div id="q1" style="display:none">
<li>
<h3>2. Paper comes from... </h3>
<input type="radio" name="question1" value="A">Water<br>
<input type="radio" name="question1" value="B">Cement<br>
<input type="radio" name="question1" value="C">Trees<br>
<input type="radio" name="question1" value="D">The Sky<br>
</li>
<button class="next" onclick="goNext(1)">Next Question</button>
</div>
<div id="q2" style="display:none">
<li>
<h3>3. How many hours in a day? </h3>
<input type="radio" name="question2" value="A">24<br>
<input type="radio" name="question2" value="B">22<br>
<input type="radio" name="question2" value="C">16<br>
<input type="radio" name="question2" value="D">48<br>
</li>
<button class="next" onclick="goNext(2)">Next Question</button>
</div>
<script language=javascript>
function goNext(i)
{
document.getElementById("q"+i).style.display = 'none';
i++;
document.getElementById("q"+i).style.display = 'block';
}
</script>

Related

How to get total yes value from a set of survey question

I have a short survey questions with answer YES/ NO
How can I get the total number of YES when submit button is clicked?
I will need to display certain images later according to the number of YES
<form>
<div class="field">
<label class="label">This is question number 1</label>
<div class="control">
<label class="radio">
<input type="radio" name="question1" value="1">
Yes
</label>
<label class="radio">
<input type="radio" name="question1" value="0">
No
</label>
</div>
</div>
<div class="field">
<label class="label">This is question number 2</label>
<div class="control">
<label class="radio">
<input type="radio" name="question2" value="1">
Yes
</label>
<label class="radio">
<input type="radio" name="question2" value="0">
No
</label>
</div>
</div>
<div class="field">
<label class="label">This is question number 3</label>
<div class="control">
<label class="radio">
<input type="radio" name="question3" value="1">
Yes
</label>
<label class="radio">
<input type="radio" name="question3" value="0">
No
</label>
</div>
</div>
<div class="field is-grouped">
<div class="control">
<div class="button is-link" onclick="countYes()">Submit</div>
</div>
<div class="control">
<button class="button is-link is-light">Cancel</button>
</div>
</div>
</form>
<script>
function countYes() {
totalVal = 0;
for(var y=0; y<3; y++)
{
var questionNo = document.getElementsByName("question" + y);
for (i=0; i<questionNo.length; i++)
{
if (document.forms.question[i].checked==true)
{
totalVal = totalVal + parseInt(document.forms.question[i].value);
console.log(totalVal);
}
}
}
}
</script>
I have a short survey questions with answer YES/ NO
How can I get the total number of YES when submit button is clicked?
I will need to display certain images later according to the number of YES

Get all radio inputs from dynamically generated divs

I have a series of dynamically generated div that each one has 4 radio buttons inside:
$(".wrapper").on("custom", ".item", function(){
$.each($(".item"),function(){
// Get all radio names and check if at least one is checked
var radio_groups = [];
$.each($(this).find('input[type="radio"]'), function(){
var myname= this.name;
if($.inArray( myname, radio_groups ) < 0){
radio_groups.push(myname);
}
});
console.log(radio_groups);
return false;
// Check if there is a radio selected for each radio group
for(var i=0; i<radio_groups.length; i++) {
if($(this).find('input[type="radio"][name="' + radio_groups[i] + '"]:checked').length <= 0) {
// $('input[type="radio"][name="' + radio_groups[i] + '"]').first().closest('.row').append('<p class="input-error">Please select one option.</p>');
$('input[type="radio"][name="' + radio_groups[i] + '"]').first().closest('.condition').append('<p class="input-error">Please select one option.</p>');
errors = true;
}
}
})
})
$('.item').trigger("custom");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div class="item">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
</div>
<div class="item">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
</div>
<div class="item">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
</div>
<div class="item">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
</div>
</div>
I have tried this but doesn't seem to work, mostly the problem is that the .item divs are dynamically generated with php.
I probably didn't understand the problem but why not just use querySelectorAll with a simple forEach like that:
let result = [];
document.querySelectorAll('.item').forEach((el) =>{
const radioboxname = el.querySelectorAll('input[type="radio"]')[0].name;
if(!result.includes(radioboxname)){
result.push(radioboxname);
}
});
console.log(result);
<div class="wrapper">
<div class="item">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
<input type="radio" name="dynamic_name_123">
</div>
<div class="item">
<input type="radio" name="dynamic_name_124">
<input type="radio" name="dynamic_name_124">
<input type="radio" name="dynamic_name_124">
<input type="radio" name="dynamic_name_124">
</div>
<div class="item">
<input type="radio" name="dynamic_name_125">
<input type="radio" name="dynamic_name_125">
<input type="radio" name="dynamic_name_125">
<input type="radio" name="dynamic_name_125">
</div>
<div class="item">
<input type="radio" name="dynamic_name_126">
<input type="radio" name="dynamic_name_126">
<input type="radio" name="dynamic_name_126">
<input type="radio" name="dynamic_name_126">
</div>
</div>
After comment by OP
I add an array and instead of select all radios i select all item divs and check the name of first radio button compare with array and include if wasn't include

multiple choice quiz with class correct and wrong

I created a multiple choice quiz, and it working perfectly, I mean get the total score written on the website, but I wish to change it to just giving an extra 'correct' or 'wrong' CSS class to the selected input radio buttons after the Submit button has been hit.
HTML:
<section class="quiz">
<div id="results"></div>
<form name="quizForm" onsubmit="return submitAnswer()">
<h4 class="quiz-title knowledge-content-list-item-subheader">Question 1</h4>
<p>Question 1</p>
<div class="quiz-answers">
<input data-answer type="radio" name="q1" value="a" id="q1a"><label for="q1a">Test 1</label><br>
<input data-answer type="radio" name="q1" value="b" id="q1b"><label for="q1b">Test 2</label><br>
<input data-answer type="radio" name="q1" value="c" id="q1c"><label for="q1c">Test 3</label><br>
</div>
<h4 class="quiz-title knowledge-content-list-item-subheader">Question 2</h4>
<p>Question 2</p>
<div class="quiz-answers">
<input data-answer type="radio" name="q2" value="a" id="q2a"><label for="q2a">Test 4</label><br>
<input data-answer type="radio" name="q2" value="b" id="q2b"><label for="q2b">Test 5</label><br>
<input data-answer type="radio" name="q2" value="c" id="q2c"><label for="q2c">Test 6</label><br>
</div>
<h4 class="quiz-title knowledge-content-list-item-subheader">Question 3</h4>
<p>Question 3</p>
<div class="quiz-answers">
<input data-answer type="radio" name="q3" value="a" id="q3a"><label for="q3a">Test 7</label><br>
<input data-answer type="radio" name="q3" value="b" id="q3b"><label for="q3b">Test 8</label><br>
<input data-answer type="radio" name="q3" value="c" id="q3c"><label for="q3c">Test 9</label><br>
</div>
<h4 class="quiz-title knowledge-content-list-item-subheader">Question 4</h4>
<p>Question 4</p>
<div class="quiz-answers">
<input data-answer type="radio" name="q4" value="a" id="q4a"><label for="q4a">Test 10</label><br>
<input data-answer type="radio" name="q4" value="b" id="q4b"><label for="q4b">Test 11</label><br>
<input data-answer type="radio" name="q4" value="c" id="q4c"><label for="q4c">Test 12</label><br>
</div>
<button id="btn-submit" class="btn btn-submit" type="submit" name="submit" value="submit">submit</button>
</form>
</div>
</section>
JavaScript:
function submitAnswer() {
var total = 4;
var score = 0;
// Get User Input
var q1 = document.forms["quizForm"]["q1"].value;
var q2 = document.forms["quizForm"]["q2"].value;
var q3 = document.forms["quizForm"]["q3"].value;
var q4 = document.forms["quizForm"]["q4"].value;
// Validation
for(i = 1; i <= total; i++){
if(eval('q'+i) == null || eval('q'+i) == ''){
alert('You missed question '+ i);
return false;
}
}
// Set Correct Answers
var answers = ["a", "b", "c", "a"];
// Check Answers
for(i = 1; i <= total; i++){
if(eval('q'+i) == answers[i - 1]){
score++;
}
}
// Display results
var results = document.getElementById('results');
results.innerHTML = '<h3>You scored <span>'+score+'</span> out of <span>'+total+'</span></h3>';
return false;
}
I would be really appreciated for any kind of help. Cheers
You can use classLis.add() for that. So in your JS you'd do
document.getElementById('q4a').classList.add('correct')
document.getElementById('q4b').classList.add('wrong')
document.getElementById('q4c').classList.add('wrong')

How Can I Cascade Radio Buttons In Javascript?

I'm new to programming and am tasked with creating a clickable tournament bracket. 8 teams, where you can pick the winners who will advance to the next round.
The problem I'm running into is when a person would want to revise picks in the first or second round after filling out the bracket.
For example in the first round the user picks:
Team1 v. Team8 --> #1 moves on
Team4 v. Team5 --> #4 moves on
Team3 v. Team6 --> #3 moves on
Team2 v. Team7 --> #2 moves on
In the Second Round let's say they pick:
Team1 v. Team4 --> #1 moves on
Team2 v. Team3 --> #2 moves on
In the Finals, they pick:
Team1 v. Team2 --> #1 wins.
Then, let's say the user changes their mind and picks Team8 to upset Team1 in the first round. Right now the code would still show Team1 as the winner and in the final game. How can I remove the text for the future rounds that currently shows Team1?
Attaching JSFiddle here: https://jsfiddle.net/a4hya2c7/5/ or see below code:
<!DOCTYPE html>
<html>
<head>
<title>Button</title>
</head>
<body>
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" onclick="changeText(this.value);"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" onclick="changeText(this.value);"><label id="r2">#8</label></br>
<input type="radio" name="g2" id="i3" value="#4" onclick="changeText2(this.value);"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" onclick="changeText2(this.value);"><label id="r4">#5</label></br>
<input type="radio" name="g3" id="i5" value="#3" onclick="changeText3(this.value);"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" onclick="changeText3(this.value);"><label id="r6">#6</label></br>
<input type="radio" name="g4" id="i7" value="#7" onclick="changeText4(this.value);"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" onclick="changeText4(this.value);"><label id="r8">#2</label></br>
</div>
</br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" onclick="changeText5(this.value);"><label id="r9"></label>
<input type="radio" name="g5" id="i10" onclick="changeText5(this.value);"><label id="r10"></label></br>
<input type="radio" name="g6" id="i11" onclick="changeText6(this.value);"><label id="r11"></label>
<input type="radio" name="g6" id="i12" onclick="changeText6(this.value);"><label id="r12"></label></br>
</div>
</br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" onclick="changeText7(this.value);"><label id="r13"></label>
<input type="radio" name="g7" id="i14" onclick="changeText7(this.value);"><label id="r14"></label></br>
</div>
</br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label></br>
</div>
</br>
</body>
</html>
JS:
function changeText(value) {
document.getElementById('r9').innerHTML = value;
document.getElementById('i9').value = value;
}
function changeText2(value) {
document.getElementById('r10').innerHTML = value;
document.getElementById('i10').value = value;
}
function changeText3(value) {
document.getElementById('r11').innerHTML = value;
document.getElementById('i11').value = value;
}
function changeText4(value) {
document.getElementById('r12').innerHTML = value;
document.getElementById('i12').value = value;
}
function changeText5(value) {
document.getElementById('r13').innerHTML = value;
document.getElementById('i13').value = value;
}
function changeText6(value) {
document.getElementById('r14').innerHTML = value;
document.getElementById('i14').value = value;
}
function changeText7(value) {
document.getElementById('r15').innerHTML = value;
document.getElementById('r15').value = value;
}
Firstly your <br> tags aren't correct as you can see here:
</div>
</br>
You are using the close tag without the opening. You can either use:
<br/>
Or use the newer html5 self closing tags style:
<br>
As to the JS itself, you can simplify it a lot if you use an attribute, similar as the name you are already using to point where it must put the value. With that change the code would be a lot smaller and simpler:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
targetLabel.previousSibling.value = inp.value;
targetLabel.innerHTML = inp.value;
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>
Note that the targets i set were directly to the labels:
<input type="radio" ... data-target="r9">
Then to get to the corresponding radio i used previousSibling.
I used several functions that you may not know:
querySelectorAll - to get an array of elements matching the selector passed
for ... of to iterate on all inputs retrieved by the querySelectorAll
addEventListener - to set the event handler directly on Javascript and make the code cleaner
And with just those little lines of Javascript you have the same functionality, and most importantly, without code duplication.
Now if you want to cascade a change on the first radios to the lower ones, you can call the change event directly with:
const event = new Event('change');
element.dispatchEvent(event);
Whenever you see that the target element already has a value set. This works like a recursive call:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
let targetRadio = targetLabel.previousSibling;
targetRadio.value = inp.value;
targetLabel.innerHTML = inp.value;
//if this isn't the last and it's checked, to not cascade non selected radios
if (targetRadio.hasAttribute && targetRadio.checked){
const nextTargetLabel = document.getElementById(targetRadio.dataset.target);
if (nextTargetLabel.innerHTML != ''){ //if it has a value then cascade
targetRadio.dispatchEvent(new Event('change'));
}
}
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>
Edit:
To clear the following radios instead of cascading the values you can use a while, and navigating with the targets until you reach the end:
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs){
inp.addEventListener("change", function(){
let targetLabel = document.getElementById(inp.dataset.target);
let targetRadio = targetLabel.previousSibling;
targetLabel.innerHTML = inp.value;
targetRadio.value = inp.value;
//while there is a next target clear it
while (targetLabel.previousSibling.hasAttribute){
targetLabel = document.getElementById(targetRadio.dataset.target);
targetRadio = targetLabel.previousSibling;
targetRadio.checked = false;
targetLabel.innerHTML = '';
}
});
}
<p>First Round</p>
<div id="round1">
<input type="radio" name="g1" id="i1" value="#1" data-target="r9"><label id="r1">#1</label>
<input type="radio" name="g1" id="i2" value="#8" data-target="r9"><label id="r2">#8</label><br>
<input type="radio" name="g2" id="i3" value="#4" data-target="r10"><label id="r3">#4</label>
<input type="radio" name="g2" id="i4" value="#5" data-target="r10"><label id="r4">#5</label><br>
<input type="radio" name="g3" id="i5" value="#3" data-target="r11"><label id="r5">#3</label>
<input type="radio" name="g3" id="i6" value="#6" data-target="r11"><label id="r6">#6</label><br>
<input type="radio" name="g4" id="i7" value="#7" data-target="r12"><label id="r7">#7</label>
<input type="radio" name="g4" id="i8" value="#2" data-target="r12"><label id="r8">#2</label><br>
</div>
<br>
<p>Second Round</p>
<div id="round2">
<input type="radio" name="g5" id="i9" data-target="r13"><label id="r9"></label>
<input type="radio" name="g5" id="i10" data-target="r13"><label id="r10"></label><br>
<input type="radio" name="g6" id="i11" data-target="r14"><label id="r11"></label>
<input type="radio" name="g6" id="i12" data-target="r14"><label id="r12"></label><br>
</div>
<br>
<p>Finals</p>
<div id="round3">
<input type="radio" name="g7" id="i13" data-target="r15"><label id="r13"></label>
<input type="radio" name="g7" id="i14" data-target="r15"><label id="r14"></label><br>
</div>
<br>
<p>Winner</p>
<div id="round4">
<label value="#8" id="r15"></label><br>
</div>
<br>

Trying to use Javascript/CSS to change a property, but can't get it to work within an if/else statement?

So you're my last hope.
I need to create a quiz, that validates name and email. Once the name and email have been validated ONLY THEN will the quiz show up. Thing is, when I put my code of
function changeStyle() {
if (document.getElementById('quiz').style.display == "none") {
document.getElementById('quiz').style.display = "block";
} else {
document.getElementById('quiz').style.display = "none";
}
}
in, my if/else statement it doesn't work. Running this code outside of the if/else statement works, albeit simply on the click of a button. The alert in the if/else statement runs as well, as does the rest of script afterwards. It seems to be just ignoring this script. Here is the Jquery i'm using:
$(document).ready(function() {
$('#contact_name').on('input', function() {
var input = $(this);
var re = /^[A-Za-z0-9]+ [A-Za-z0-9]+$/;
var is_name = re.test(input.val());
if (is_name) {
input.removeClass("invalid").addClass("valid");
} else {
input.removeClass("valid").addClass("invalid");
}
});
$('#contact_email').on('input', function() {
var input = $(this);
var re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
var is_email = re.test(input.val());
if (is_email) {
input.removeClass("invalid").addClass("valid");
} else {
input.removeClass("valid").addClass("invalid");
}
});
$("#contact_submit button").click(function(event) {
var form_data = $("#contact").serializeArray();
var error_free = true;
for (var input in form_data) {
var element = $("#contact_" + form_data[input]['name']);
var valid = element.hasClass("valid");
var error_element = $("span", element.parent());
if (!valid) {
error_element.removeClass("error").addClass("error_show");
error_free = false;
} else {
error_element.removeClass("error_show").addClass("error");
}
}
if (!error_free) {
event.preventDefault();
} else {
alert('This alert is working');
function changeStyle() {
if (document.getElementById('quiz').style.display == "none") {
document.getElementById('quiz').style.display = "block";
} else {
document.getElementById('quiz').style.display = "none";
}
}
}
});
});
CSS:
#quiz{
display:none;
}
Please help! I have tried body:onload aswell, but it seems to just have the same issue. And I've already scoured the internet for answers. I seem to be missing something, I just don't know what.
Thanks
EDIT* changeStyle is being called. Here is the HTML relating to this part.
<form id="contact" method="post" action="">
<!-- Name -->
<div>
<label for="contact_name">Name:</label>
<input type="text" id="contact_name" name="name"></>
<span class="error">This field is required</span>
</div>
<!-- Email -->
<div>
<label for="contact_email">Email:</label>
<input type="email" id="contact_email" name="email"></>
<span class="error">A valid email address is required</span>
</div>
<!-- Submit Button -->
<div id="contact_submit">
<button type="button" onclick="show()">Submit</button> </div>
</form>
<content>
<form id="quiz" name="quiz">
<h1>Test your CSS knowledge!</h1>
<h3>What does CSS stand for?</h3>
<fieldset class="question">
<input type="radio" id="q1a1" class="answer" value="Cascading CSS" data- correct="false" name="q1" ><label for="q1a1">Cascading Css</label><br>
<input type="radio" id="q1b2" class="answer" value="Cascading Style Sheets" data-correct="true" name="q1"><label for="q1b2">Cascading Style Sheets</label><br>
<input type="radio" id="q1c3" class="answer" value="Cascading Seperate Style" data-correct="false" name="q1"><label for="q1c3">Cascading Separate Style</label><br>
</fieldset>
<h3>Which attribute can be set to bold?</h3>
<fieldset class="question">
<input type="radio" id="q2a1" class="answer" value="Text Decoration" data-correct="false" name="q2" ><label for="q2a1">Text Decoration</label><br>
<input type="radio" id="q2b2" class="answer" value="Font Style" data-correct="false" name="q2"><label for="q2b2">Font Style</label><br>
<input type="radio" id="q2c3" class="answer" value="Font Weight" data-correct="true" name="q2"><label for="q2c3">Font Weight</label><br>
</fieldset>
<h3>Which tag is used to link an external CSS file?</h3>
<fieldset class="question">
<input type="radio" id="q3a1" class="answer" value="Script" data-correct="false" name="q3" ><label for="q3a1">Script</label><br>
<input type="radio" id="q3b2" class="answer" value="Link" data-correct="true" name="q3"><label for="q3b2">Link</label><br>
<input type="radio" id="q3c3" class="answer" value="Rel" data-correct="false" name="q3"><label for="q3c3">Rel</label><br>
</fieldset>
<h3>Which attribute sets the underline property?</h3>
<fieldset class="question">
<input type="radio" id="q4a1" class="answer" value="Font Style" data-correct="false" name="q4" ><label for="q4a1">Font Style</label><br>
<input type="radio" id="q4b2" class="answer" value="Text Decoration" data-correct="true" name="q4"><label for="q4b2">Text Decoration</label><br>
<input type="radio" id="q4c3" class="answer" value="Font Weight" data-correct="false" name="q4"><label for="q4c3">Font Weight</label><br>
</fieldset>
<h3>Which element is NOT relative?</h3>
<fieldset class="question">
<input type="radio" id="q5a1" class="answer" value="Px" data-correct="true" name="q5" ><label for="q5a1">Px</label><br>
<input type="radio" id="q5b2" class="answer" value="Cm" data-correct="false" name="q5"><label for="q5b2">Cm</label><br>
<input type="radio" id="q5c3" class="answer" value="%" data-correct="false" name="q5"><label for="q5c3">%</label><br>
<input type="radio" id="q5d4" class="answer" value="Em" data-correct="false" name="q5"><label for="q5d4">Em</label><br>
</fieldset>
<h3>Which element IS relative?</h3>
<fieldset class="question">
<input type="radio" id="q6a1" class="answer" value="Em" data-correct="true" name="q6" ><label for="q6a1">Em</label><br>
<input type="radio" id="q6b2" class="answer" value="Cm" data-correct="false" name="q6"><label for="q6b2">Cm</label><br>
<input type="radio" id="q6c3" class="answer" value="MM" data-correct="false" name="q6"><label for="q6c3">MM</label><br>
<input type="radio" id="q6d4" class="answer" value="Inch" data-correct="false" name="q6"><label for="q6d4">Inch</label><br>
</fieldset>
<h3>What attribute is used to move an elements content away from its border?</h3>
<fieldset class="question">
<input type="radio" id="q7a1" class="answer" value="Margin" data-correct="false" name="q7" ><label for="q7a1">Margin</label><br>
<input type="radio" id="q7b2" class="answer" value="Padding" data-correct="true" name="q7"><label for="q7b2">Padding</label><br>
<input type="radio" id="q7c3" class="answer" value="Border" data-correct="false" name="q7"><label for="q7c3">Border</label><br>
<input type="radio" id="q74d" class="answer" value="Width" data-correct="false" name="q7"><label for="q7d4">Width</label><br>
</fieldset>
<h3>Which element does not contribute to a block elements total width?</h3>
<fieldset class="question">
<input type="radio" id="q8a1" class="answer" value="Width" data-correct="false" name="q8" ><label for="q8a1">Width</label><br>
<input type="radio" id="q8b2" class="answer" value="Border" data-correct="false" name="q8"><label for="q8b2">Border</label><br>
<input type="radio" id="q8c3" class="answer" value="Background-image" data-correct="true" name="q8"><label for="q8c3">Background-image</label><br>
<input type="radio" id="q8d4" class="answer" value="Padding" data-correct="false" name="q8"><label for="q8d4">Padding</label><br>
</fieldset>
<h3>Which property changes positioned elements display order?</h3>
<fieldset class="question">
<input type="radio" id="q9a1" class="answer" value="Width" data-correct="false" name="q9" ><label for="q9a1">Width</label><br>
<input type="radio" id="q9b2" class="answer" value="Background" data-correct="false" name="q9"><label for="q9b2">Background</label><br>
<input type="radio" id="q9c3" class="answer" value="z-index" data-correct="true" name="q9"><label for="q9c3">Z-index</label><br>
<input type="radio" id="q9d4" class="answer" value="Azimuth" data-correct="false" name="q9"><label for="q9d4">Azimuth</label><br>
</fieldset>
<h3>Which value of background-repeat will cause the background to repeat vertically?</h3>
<fieldset class="question">
<input type="radio" id="q10a1" class="answer" value="repeat-x" data-correct="false" name="q10" ><label for="q10a1">repeat-x</label><br>
<input type="radio" id="q10b2" class="answer" value="repeat" data-correct="false" name="q10"><label for="q10b2">repeat</label><<br>
<input type="radio" id="q10c3" class="answer" value="repeat-y" data-correct="true" name="q10"><label for="q10c3">repeat-y</label><br>
<input type="radio" id="q10d4" class="answer" value="No-repeat" data-correct="false" name="q10"><label for="q10d4">No-repeat</label><br>
</fieldset>
<footer>
<fieldset class="calc-percentage" name="score">
<input type="button" id="calc" value="Get score" />
<div>
<p><label for="percentage">Score = </label><input type=text size=15 id="percentage" name="percentage" /></p>
<input type="submit" onclick="checkQuiz()">
</div>
</fieldset>
You only redefine function changeStyle(){}, never calling it. Also, if you're going to use jQuery then use it. Just use .css(), if you don't want to .toggle(). Get rid of onclick='changeStyle()' in your HTML.
Despite all of your other possible errors:
$(document).ready(function(){
$('#contact_name').on('input', function(){
var input = $(this);
var re = /^[A-Za-z0-9]+ [A-Za-z0-9]+$/;
var is_name = re.test(input.val());
if(is_name){
input.removeClass('invalid').addClass('valid');
}
else{
input.removeClass('valid').addClass('invalid');
}
});
$('#contact_email').on('input', function(){
var input = $(this);
var re = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/;
var is_email = re.test(input.val());
if(is_email){
input.removeClass('invalid').addClass('valid');
}
else {
input.removeClass('valid').addClass('invalid');
}
});
$('#contact_submit button').click(function(event){
var form_data = $('#contact').serializeArray(), error_free = true;
for(var input in form_data){
var element = $('#contact_' + form_data[input]['name']);
var valid = element.hasClass('valid');
var error_element = $('span', element.parent());
if(!valid){
error_element.removeClass('error').addClass('error_show');
error_free = false;
}
else{
error_element.removeClass('error_show').addClass('error');
}
}
if(!error_free){
event.preventDefault();
}
else{
// look what changed here - you have to call a function to execute it
$('#quiz').css('display', 'block');
}
});
});
Again get rid of your regular JavaScript function changeStyle() and remove it from HTML, as well!!!

Categories

Resources