I have created a quiz using HTML currently there are 5 questions in total and I have it coded so that only the question being answered appears so users taking the quiz cannot see upcoming questions. The way I have done it using multiple forms so for each question there is a separate form this makes it a pain to be able to send all of the answers to the questions via email, currently it only sends the last questions... Is there a way I can combine my forms into one big form or possibly have a button that submits all my forms?
Any help would be greatly appreciated :)
Currently, it won't let me send code. I'll try again.
Hi and welcome to Stackoverflow!
If I understood correctly, you can split the form in sections like the following:
<form POST="..." onsubmit="onNextStep">
<div class='form-section' id='question-1'>
<!-- code here -->
</div>
<div class='form-section' id='question-2'>
<!-- code here -->
</div>
<div class='form-section' id='question-3'>
<!-- code here -->
</div>
<div class="form-footer">
<button type="submit"> Next </button>
</div>
</form>
and then add an event on button click that increments the current step (0, 1, 2...) and hide all the divs without the correct id and then submit the form when on the final step.
let totalSteps = 3;
let step = 1;
function onNextStep(e) {
const currentStep = step;
const nextStep = step + 1;
// in the last step change the button text
if ( nextStep == totalSteps ) {
document.querySelector('form button[type="submit"]').innerText = "Submit"
}
// If the last step is completed, submit the form.
if ( nextStep > totalSteps ) {
return
}
// prevent form submission
e.preventDefault()
// hide the current section
document.getElementById('question-'+nextStep).style.display = 'block'
// show the next section
document.getElementById('question-'+curentStep).style.display = 'none'
// increment our steps counter
step += 1
}
This example with some adjustments should fit your case.
Just use the one form.
Use the fieldset tag to encapsulate your questions then use javascript to hide and show as needed.
let questions = document.querySelectorAll(".question");
let answerButtons = document.querySelectorAll(".question button");
for (var i = 0; i < answerButtons.length; i++) {
answerButtons[i].addEventListener("click",function() {
//Get Closest question
var question = this.closest(".question");
//Remove Active class
question.classList.remove("active");
//Add active class to next sibling
question.nextElementSibling.classList.add("active");
});
}
.question:not(.active) {
display: none;
}
<form action="">
<fieldset class="question active">
<legend>Question 1 of 3</legend>
<label>What is your name? <input type="text" name="qName"></label>
<button type="button">Submit Answer</button>
</fieldset>
<fieldset class="question">
<legend>Question 2 of 3</legend>
<label>What is your quest? <input type="text" name="qQuest"></label>
<button type="button">Submit Answer</button>
</fieldset>
<fieldset class="question">
<legend>Question 3 of 3</legend>
<label>What is your quest? <input type="text" name="qName"></label>
<button type="submit">Submit Quiz</button>
</fieldset>
</form>
Related
I am working on a personal blog website project, and I wanted to implement a simple message board on my index page. Due to the projected site traffic (relatively low) I decided on only using a front-end implementation without linking to a database with the following js and html code:
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<textarea class="message" type="text"></textarea><br/>
<input value="submit" type="button" class="submit-btn">
<div class="display-area">
Existing comment:
</div>
</section>
and then the js,
<script>
window.onload=function() {
var displayArea = document.getElementsByClassName("display-area");
var btn = document.getElementsByClassName("submit-btn");
btn.onclick = function() {
var comment = document.getElementsByClassName("message").value;
displayArea.appendChild(comment);
};
}
</script>
My intention was to make my display-area contain whatever was put in textarea via .appendChild when submit is clicked. Sadly, it isn't working as intended-nothing actually happens. I am thinking about potential errors in my js code, but just couldn't figure out anything that would resolve the problem.
Any assistance will be greatly appreciated!!!
getElementsByClassName() returns a collection of elements (note the s in Elements). If you have only one element that matches the class name, you have this element in the first index of the array-like collection.
var displayArea = document.getElementsByClassName("display-area")[0];
var btn = document.getElementsByClassName("submit-btn")[0];
You can also use querySelector(), that uses CSS selectors (like jQuery) and returns a single element:
var displayArea = document.querySelector(".display-area");
In order to append a text node (your variable comment stores a string), use append() instead of appendChild():
displayArea.append(comment);
Two ways this can be done are by calling the JavaScript function on click, or by calling it on form submission.
1) call function onclick:
Wrap your form within a form tag, and call your JavaScript function based on the element Ids.
Note the showInput function is being called onclick when the button is clicked.
function showInput() {
console.log('showInput called...')
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
display.innerHTML = userInput;
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form>
<textarea class="message" type="text" id="userInput"></textarea><br/>
</form>
<input type="submit" onclick="showInput();">
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
Here's a jsfiddle, with the same code as above: http://jsfiddle.net/ethanryan/94kvj0sc/
Note the JavaScript in the jsfiddle is being called at the bottom of the Head section of the HTML.
2) call function on form submit:
You can also do this by calling the JavaScript function on the submission of the form, instead of on the click of the button. However, since this form uses a textarea, hitting return will add a line break to the text, and not submit the form, so the button still needs to be clicked for the function to be called.
function showInput() {
console.log('showInput called...')
event.preventDefault()
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
display.innerHTML = userInput;
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form onsubmit="showInput()">
<textarea class="message" type="text" id="userInput"></textarea><br/>
<input type="submit" value="Submit">
</form>
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
Note the event.preventDefault() in the form, since the default behavior of forms is to submit data to a backend database.
jsfiddle: http://jsfiddle.net/ethanryan/qpufd469/
3. appending instead of replacing text
Finally, my examples above used innerHTML to replace the userInput text. If you want to append instead of replace the text, you can use insertAdjacentHTML to add the text to the end, and then append a linebreak to it. Finally, you can reset the form.
function showInput() {
console.log('showInput called...')
event.preventDefault()
var userInput = document.getElementById("userInput").value;
var display = document.getElementById("display");
var theForm = document.getElementById("theForm");
var linebreak = document.createElement("br");
display.insertAdjacentHTML('beforeend', userInput);
display.appendChild(linebreak);
theForm.reset();
}
<section class="message-board">
<div class="title">
<h2>
Leave a message
</h2>
</div>
<form onsubmit="showInput()" id="theForm">
<textarea class="message" type="text" id="userInput"></textarea><br/>
<input type="submit" value="Submit">
</form>
<div class="display-area">
Existing comment:
</div>
<p><span id="display"></span></p>
</section>
jsfiddle: http://jsfiddle.net/ethanryan/x4hq0Lzp/
I am new to the javascript developing world and I took it upon myself to create a small game that my fathers students will be able to play at school. This game consists of 4 different mathematical operations (Adding,Subtracting,Multiplication,Division). Once the student clicks on the operation button, they will then be transferred to a new page. This page will have numbers from 1 to 10. This number will be used as a static number. After the user selects this number, they will have 10 different problems to answer. The first number will be a random number from 1 to 12 and the second number will be the digit they selected on the page before. After completing the 10 problems, they will be greeted with a page that will inform them which questions they have missed. I have started the code for the addition part but I ran into several complications.
1) how do i transfer the answer from one function, to another? This will be used to check the input.
2) Will it be more intuitive to use a switch statement in order to select the operation & the static number?
3) Is there any other methods that would facilitate the making of this game?
I would like to thank you in advance and apologize for the long post. I am a bit lost and would love to get some kind of feedback.
var x;
function startAdd() {
var random = new Array();
for (var i = 0; i < 1; i++) {
random.push(Math.floor(Math.random() * 13));
// console.log(random[i]);
}
var allRadioButtons = document.getElementsByName("dif");
var secondNumber;
for (var i in allRadioButtons) {
if (allRadioButtons[i].checked) {
secondNumber = +allRadioButtons[i].value;
break;
}
}
for (var a = 0; a < 1; a++) {
document.getElementById('probFirst').innerHTML = random[a];
document.getElementById('probSecond').innerHTML = secondNumber;
/*
compareUser();
function compareUser(){
if (prob != )
} */
}
}
function myFunction() {
var x = document.getElementById("userNumb").value;
document.getElementById("Answer").innerHTML = x;
}
<title>RicoMath - Addition</title>
<body>
<h1>RicoMath</h1>
<h1 class="add">Addition</h1>
<h2>Difficulty</h2>
<div id="options">
<div>
<input id="num1" type="radio" name="dif" value="1">
<label for="num1">1</label>
</div>
<div>
<input id="num2" type="radio" name="dif" value="2">
<label for="num2">2</label>
</div>
<div>
<input id="num3" type="radio" name="dif" value="3" checked>
<label for="num3">3</label>
</div>
<div>
<input id="num4" type="radio" name="dif" value="4">
<label for="num4">4</label>
</div>
<div>
<input id="num5" type="radio" name="dif" value="5">
<label for="num5">5</label>
</div>
<button onclick="startAdd()">Begin!!!!</button>
<h4 id='probFirst'></h4>
<h4 id='probSecond'></h4>
</div>
<input type="number" id="userNumb" value="">
<button onclick='myFunction()'>Enter UserNumb</button>
<p id="Answer"></p>
</body>
1) To transfer the data to your next "page", the easy option for you would be to have seperate divs for seperate pages in the same html file. Then when you need to go the the "next page", just show the div you need to show and hide the others.
Here's a the html + pure javascript code for that with a working example:
<body>
<div id="page1" style="border-width:2px;border-style:solid">
your first page
<button onclick="showPage2()">Go to Page 2</button>
</div>
<div id="page2" style="border-width:2px;border-style:solid">
2nd page
</div>
<div id="page3">
3rd page
</div>
<script>
showPage1();
function hide(id){
document.getElementById(id).hidden = true;
}
function show(id){
document.getElementById(id).hidden = false;
}
function showPage1(){
show("page1");
hide("page2");
hide("page3");
}
function showPage2(){
show("page2");
hide("page1");
hide("page3");
}
</script>
</body>
Here's a working fiddle.
To transfer your value from the input, just use document.getElementById() since you are in the same html document.
2) To get the selected value from the radio button list, just use (as per your code):
var rates = document.getElementById('options').value;
You can use the same method to get the value from a input box. Please make sure you add a check for empty input and also to check if a radio button has been selected before getting the value.
I don't see any need to loop as you have done.
3) Definitely learn and use jquery. It will make your effort much less.
Hope this helps and happy coding!
I am trying to set-up the multi steps form validation using the Parsely.js validation plugin.
I followed the documentation here: "http://parsleyjs.org/doc/examples/multisteps.html" - but the only problem is I am going to have few forms that will have multi steps across the site and on some pages there will be more than one.
The snippet provided only support one form at a time, I need to specify an ID for each form as showed below:
<script type="text/javascript">
$(document).ready(function () {
$('.next').on('click', function () {
var current = $(this).data('currentBlock'),
next = $(this).data('nextBlock');
// only validate going forward. If current group is invalid, do not go further
// .parsley().validate() returns validation result AND show errors
if (next > current)
if (false === $('#demo-form').parsley().validate('block' + current))
return;
// validation was ok. We can go on next step.
$('.block' + current)
.removeClass('show')
.addClass('hidden');
$('.block' + next)
.removeClass('hidden')
.addClass('show');
});
});
</script>
Is there a way to tweak the snippet so it automatically detect if the form has more than one step and apply the appropriate behavior/settings accordingly? Rather than having to duplicate that snippet over and over for each form.
Here is how the HTML would look like:
<form id="demo-form" data-parsley-validate>
<div class="first block1 show">
<label for="firstname">Firstname:</label>
<input type="text" name="firstname" data-parsley-group="block1" required/>
<label for="lastname">Lastname:</label>
<input type="text" name="lastname" data-parsley-group="block1" required />
<span class="next btn btn-info pull-right" data-current-block="1" data-next-block="2">Next ></span>
</div>
<div class="second block2 hidden">
<label for="fullname">Email:</label>
<input type="text" name="fullname" required data-parsley-type="email" data-parsley-group="block2" />
<span class="next btn btn-info pull-left" data-current-block="2" data-next-block="1">< Previous</span>
<input type="submit" class="btn btn-default pull-right" />
</div>
</form>
You need to change the code to specify the form the user is currently working with. I've altered the code block you're using to do that, comments included:
$(document).ready(function () {
$('.next').on('click', function () {
// Find the form whose button was just clicked
var currentForm = $(this).parents('form').first();
var current = $(this).data('currentBlock'),
next = $(this).data('nextBlock');
// only validate going forward. If current group is invalid, do not go further
// .parsley().validate() returns validation result AND show errors
if (next > current)
// Use currentForm found above here, rather than hard coded form id
if (false === currentForm.parsley().validate('block' + current))
return;
// validation was ok. We can go on next step.
// Hide current block on current form
currentForm.find('.block' + current)
.removeClass('show')
.addClass('hidden');
// Show next block on current form
currentForm.find('.block' + next)
.removeClass('hidden')
.addClass('show');
});
});
I'm trying to figure out how to disable a "Next section" button until all three groups of radio buttons have been answered. I've searched at length for a solution, but most refer to when a form is submitted. I'm trying to configure it so that the button is enable once all questions are answered.
This page has three panels, with only one visible at a time. When panel one is visible, panels two and three are hidden. Once all the questions on panel one are answered, the user clicks a "Next section" button, which slides up section one, and slides down section two. The trouble I'm having is the validation... making sure all questions on each panel are answered before enabling the button.
Here's a very shortened version of what I'm working with:
Q1
<div id="one">
<input type="radio" name="question01" value="Q1-A">
<input type="radio" name="question01" value="Q1-B">
<input type="radio" name="question01" value="Q1-C">
</div>
Q2
<div id="two">
<input type="radio" name="question02" value="Q2-A">
<input type="radio" name="question02" value="Q2-B">
<input type="radio" name="question02" value="Q2-C">
</div>Q3
<div id="three">
<input type="radio" name="question03" value="Q3-A">
<input type="radio" name="question03" value="Q3-B">
<input type="radio" name="question03" value="Q3-C">
</div>
<button class="btn btn-primary" type="button" id="submit1" disabled="true">Next section</button>
$(document).ready(function () {
var q01 = $('input[name=question01]');
var q02 = $('input[name=question02]');
var q03 = $('input[name=question03]');
validate();
$(q01, q02, q03).change(validate);
});
function validate() {
if ($(q01).is(':checked') && $(q02).is(':checked') && $(q03).is(':checked')) {
$(".btn#submit1").prop("disabled", false);
} else {
$(".btn#submit1").prop("disabled", true);
}
}
I think this is what you need:
http://jsfiddle.net/vss9D/4/
$(document).ready(function() {
var q01 = $('input[name=question01]');
var q02 = $('input[name=question02]');
var q03 = $('input[name=question03]');
validate();
$("input[type='radio']").change(validate);
function validate() {
if ($(q01).is(':checked') && $(q02).is(':checked') && $(q03).is(':checked')) {
$(".btn#submit1").removeAttr("disabled", false);
} else {
$(".btn#submit1").attr("disabled", true);
}
}
});
The important part here is where you bind the "validate" function to the radio groups.
$(q01, q02, q03).change(validate); is not a valid way to select three jQuery elements.
you can use the .add() function to select multiple jQuery variables (see this stack overflow question)
My site structure consists on an index.php which is styled by a css file. It then includes the following php code in a separate file:
<?php include("globals.php"); ?>
<form action="<?php echo $website.$relative_string;?>" name="subscribe" onsubmit="javascript:return checkEmail(this);" method="post">
<div id="cell8" class="titlecell2"><h3>Email:</h3></div>
<div id="cell9" class="inputcell2">
<input type="text" class="inputfield2" name="email" value="Your Email..." id="email2" maxlength="255" onfocus="this.value='';">
</div>
<div id="cell10" class="textcell3">
<input name="group" type="hidden" id="group[]" value="<?php echo $group; ?>">
<input name="subscribe" id="sub" type="radio" value="true" checked>
</span>Subscribe </p>
</div>
<div id="cell11" class="buttoncell">
<button type="submit" name="Submit2" value="Join" id="submitButton2">
<span>OK</span>
</button>
</div>
<div id="cell8" class="textcell4">
<input type="radio" name="subscribe" id="unsub" value="false">
</span>Un-Subscribe </p>
</div>
</form>
It appears on screen with no problems in the correct layout as my css style sheet. What I would like this to do is when I select the "Subscribe" radio button the submit button text "OK" changes to "Join". When I click on the Unsubscribe button text "OK" or "Join" changes to "Leave".
I tried to make some code from research:
if(document.getElementById('sub').checked) {
document.write("<span>Join</span>"
}
else if(document.getElementById('unsub').checked) {
document.write("<span>Leave</span>)
}
I think this kind of worked in that it changed to Join (replacing the OK line, but obviously didn't update on clicking unsubscribe. I guess it would update on refreshing the page if my default wasn't join. I guess I need to do some form of onclick but then I have no idea how to adjust that span ok bit.
Please help?
Many thanks Chris
Here is a solution in plain JavaScript without jQuery. It avoids the unnecessary overhead.
This should work, but I haven't had a chance to test it:
var sub = document.getElementById('sub'); // Save element to a variable, so you don't have to look for it again
var unsub = document.getElementById('unsub');
var btn = document.getElementById('submitButton2');
sub.onchange = function() //When sub changes
{
if(sub.checked) //If it's checked
{
btn.innerHTML = "<span>Join</span>"; // Set button to Join
}
else // If not..
{
btn.innerHTML = "<span>OK</span>"; // Set button to OK
}
}
unsub.onchange = function() //When unsub changes
{
if(unsub.checked) //If it's checked
{
btn.innerHTML = "<span>Leave</span>"; // Set button to Leave
}
else // If not..
{
btn.innerHTML = "<span>OK</span>"; // Set button to OK
}
}
However, you should not do it like this.
You should combine the two radio buttons into a radio group.
In that case you will listen for radio group to change, get the value of the radio group, set button text according to the value.
if you label your <span>OK</span> to something like <span id="your_id">OK</span> then added a class to your radio button like this <input class="your_class" type="radio" name="subscribe" id="unsub" value="false"> them...
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script>
$("#your_class").change(function () {
if ($(this).is(':checked')) {
$("#your_id").text('Join');
}else {
$("#your_id").text('Leave');
}
});
</script>
This was all written in the browser so let me know if there are any problems.