I am trying to create a basic quizz webpage. I read some articles here, but most of the javascript code that I wrote I learned through books and video tutorials, so I am very confused with why they won't work. Here is the HTML:
<!DOCTYPE HTML>
<html>
<head>
<title>Quizz</title>
<script type = "text/javascript" src = "script.js"></script>
</head>
<body onload="init(); postaviPitanje();">
<div id="title">
<span> Quizz</span>
<div> <!--end title-->
<div id="form">
<form>
<fieldset>
<legend id="legend">
Question <span id="brPitanja"></span><!--span in wich a question number is sent-->
</legend>
<p id="pitanjeTxt"></p><!--question text field-->
<p><input type="radio" name="odgovor" id ="odg1" value ="1"/></p><!--question 1-->
<p><input type="radio" name="odgovor" id ="odg2" value ="2"/></p><!--question 2-->
<p><input type="radio" name="odgovor" id ="odg3" value ="3"/></p><!--question 3-->
<p><input type="radio" name="odgovor" id ="odg4" value ="4"/></p><!--question 4-->
</fieldset>
</form>
<div><!--end form-->
</body>
</html>
The Javascript code below is incomplete because it didn't even populate the first question on load. I was going to add additional logic afterwards, but as I'm stuck here, I didn't move past the initial function of the test version:
function init() {
//question number on start
var brojPitanja = 0;
//span with question No into a variable
var brPitanjaSpan = document.getElementById("brPitanja");
//p with question teks into a variable
var tekstPitanjaParagraph = document.getElementById("pitanjeTxt");
//radio buttons into variables
var radio1 = document.getElementById("odg1");
var radio2 = document.getElementById("odg2");
var radio3 = document.getElementById("odg3");
var radio4 = document.getElementById("odg4");
//question object initialization function
function pitanje (br, txt, a, b, c, d, t) { //br - question number;
//txt- question text;
//a, b, c, d - possible answers;
//t - int value for correct answer;
this.number = br;
this.text = txt;
this.answ1 = a;
this.answ2 = b;
this.answ3 = c;
this.answ4 = d;
this.correct = t;
}
//question objects
var p1 = new pitanje(1, "Whats my name?", "marko", "lazar", "perisa", "bogdan", 1);
var p2 = new pitanje(2, "How old I am?", "25", "24", "22", "21", 3);
//question array
var nizPitanja = new Array (p1, p2);
}
//setting question onto document
function postaviPitanje() {
var current = nizPitanja[brojPitanja]; //current cuestion
brPitanjaSpan.innerHTML = "" + brojPitanja; //place question number in question title
tekstPitanjaParagraph.innerHTML = current.text; //place question text in HTML
//fill radiobuttons with question text
radio1.innerHTML = current.answ1;
radio2.innerHTML = current.answ2;
radio3.innerHTML = current.answ3;
radio4.innerHTML = current.answ4;
}
The problem is that the page displays only that text that is already in HTML. I would appreciate any help as I'm just starting with Javascript, so I can't debug this myself. Also, I changed everything I could to English. Some things, like id values, I left as they were so I don't break it even more :)
As I said, I did read and learn from several sources, insluding stackoverflow, so if I missed any question that could help and made a double, I apologize in advance. And thanks in advance, also.
[EDIT] Here is the fiddle with edited code https://jsfiddle.net/uazntz1u/1/
Problem is you are defining your questions and answers array within init()
var nizPitanja = new Array (p1, p2);
this variable is scoped to the function itself(var) and won't be accessible anywhere outside.
Just declare it above init() so that postaviPitanje() can have access to it.
var nizPitanja=null;
init(); // Assign it inside init() without var.
postaviPitanje();
More about scope of variables here
What is the scope of variables in JavaScript?
Here is what I would suggest to do:
var quiz = (function () {
//question number on start
var brojPitanja = 0;
//span with question No into a variable
var brPitanjaSpan = document.getElementById("brPitanja");
//p with question teks into a variable
var tekstPitanjaParagraph = document.getElementById("pitanjeTxt");
//radio buttons into variables
var radio1 = document.getElementById("odg1");
var radio2 = document.getElementById("odg2");
var radio3 = document.getElementById("odg3");
var radio4 = document.getElementById("odg4");
//question object initialization function
function Pitanje (br, txt, a, b, c, d, t) {
//br - question number;
//txt- question text;
//a, b, c, d - possible answers;
//t - int value for correct answer;
// remark: change the lines below so that you
// have the same variable names like the parameters
this.number = br;
this.text = txt;
this.answ1 = a;
this.answ2 = b;
this.answ3 = c;
this.answ4 = d;
this.correct = t;
}
//question objects
var p1 = new Pitanje(1, "Whats my name?",
"marko", "lazar", "perisa", "bogdan", 1);
var p2 = new Pitanje(2, "How old I am?",
"25", "24", "22", "21", 3);
// you can remove this:
//question array
//var nizPitanja = new Array (p1, p2);
return {
brojPitanja : brojPitanja,
brPitanjaSpan : brPitanjaSpan,
textPitanjaSpan : textPitanjaParagraph,
radios : [radio1, radio2, radio3, radio4],
nizPitanja : [p1, p2]
}
})();
Now this is an Immediately-Invoked Function Expression (IIFE):
https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
It will return an object assigned to the variable quiz, which is your only global variable, so you don't pollute the global scope unnecessary with all the variables.
Now you can rewrite your function for making the questions:
function postaviPitanje() {
var current = quiz.nizPitanja[quiz.brojPitanja]; //current cuestion
quiz.brPitanjaSpan.innerHTML = "" + quiz.brojPitanja; //place question number in question title
quiz.tekstPitanjaParagraph.innerHTML = current.text; //place question text in HTML
//fill radiobuttons with question text
quiz.radios[0].innerHTML = current.answ1;
quiz.radios[1].innerHTML = current.answ2;
quiz.radios[2].innerHTML = current.answ3;
quiz.radios[3].innerHTML = current.answ4;
}
Regarding the radios you certainly know that the array index starts at 0, so the first radio button is radios[0], the second radios[1] and so on.
In your HTML file make the following changes:
<script type="text/javascript" src="script.js"></script>
<!-- add here these lines -->
<script type="text/javascript">
window.onload = postaviPitanje; // important: without braces
</script>
and change this:
<body onload="init(); postaviPitanje();">
to:
<body>
The whole code can be certainly refactored much better, but it would take long time to explain so many things. Since you said you're still beginner, this should give you some idea how to better organize your code.
EDIT:
There is one more issue in your HTML and JavaScript code: you are trying to access the property innerHTML of an input element of type radio. But this isn't possible. Change your code rather to:
<p>
<input type="radio" name="odgovor" id ="odg1" value ="1"/>
<label for="odg1" id="odg1_label"></label>
</p>
<p>
<input type="radio" name="odgovor" id ="odg2" value ="2"/>
<label for="odg2" id="odg2_label"></label>
</p>
<p>
<input type="radio" name="odgovor" id ="odg3" value ="3"/>
<label for="odg3" id="odg3_label"></label>
</p>
<p>
<input type="radio" name="odgovor" id ="odg4" value ="4"/>
<label for="odg4" id="odg4_label"></label>
</p>
And then get the labels in your JS-code:
var radio1 = document.getElementById("odg1_label");
var radio2 = document.getElementById("odg2_label");
var radio3 = document.getElementById("odg3_label");
var radio4 = document.getElementById("odg4_label");
Now it is possible to set the property innerHTML of the labels. That will result in placing the answer options ('marko', 'lazar', 'perisa', 'bogdan') where you want.
Related
Currently I'm trying to create a quiz, right now it displays the first question with 4 answer choices after the start button I am stuck on how to retrieve the answer. The user clicks, check to see if its correct and loop to the next question. I just want to give the user one chance per question and move on regardless if it's correct or not. If their answer is wrong I will remove seconds from the timer. I have the questions, answer choices, and correct answers in arrays.
<div class="card-body">
<p id="header">
You have 75 seconds to complete this asessment.
Every incorrect answer will cost you time.
<br>
</p>
<button id="start-button" class="btn">Start</button>
<div id="start-game" style="visibility: hidden">
<button id="option0" data-index="0"></button><br>
<button id="option1" data-index="1"></button><br>
<button id="option2" data-index="2"></button><br>
<button id="option3" data-index="3"></button><br>
</div>
</div>
<script src="./script.js"></script>
var timerEl = document.getElementById("timer");
var start = document.getElementById("start-button");
var questionEl = document.getElementById("header");
var option0 = document.getElementById("option0");
var option1 = document.getElementById("option1");
var option2 = document.getElementById("option2");
var option3 = document.getElementById("option3");
var intials = document.getElementById("user-initials");
var buttonEl = document.getElementById("start-game");
var totalTime = 75;
var elapsedTime = 0;
var questionNum = 0;
var questions =["The condition in an if/else statement is enclosed with in _______",
"Arrays in JavaScript can be used to store ______",
"Commonly used data types do not include ______",
"String values must be enclosed within _____ when being assigned to variables"];
var answers =[question1= ["Quotes","Curly brackets","Parentheses","Square brackets"],
question2= ["Numbers and strings","Other arrays","Booleans","All of the above"],
question3= ["Strings","Booleans","Alerts","Numbers"],
question4= ["Commas","Curly brackets","quotes","parentheses"],
];
var correctAnswers = [2,3,2,2];
start.addEventListener("click", function(){
timer();
displayQuestion();
start.style.visibility = "hidden";
buttonEl.style.visibility = "visible";
});
function timer(){
var timerInterval = setInterval(function(){
totalTime --;
timerEl.textContent = totalTime;
if(totalTime === 0){
clearInterval(timerInterval);
endQuiz();
return;
}
}, 1000);
}
function newQuiz(){
questionEl.textContent = (questions[0]);
};
function displayQuestion(){
for( var i = 0; i < questions.length ; i++){
questionEl.textContent=(questions[i]);
option0.textContent=(answers[i][0]);
option1.textContent=(answers[i][1]);
option2.textContent=(answers[i][2]);
option3.textContent=(answers[i][3]);
console.log(i);
return;
}
}
Hi I will try to provide an easy solution to your question without using any kind of difficult javascript syntax so here goes..
First in your html file update the option button and add a class property called clickOption(you can change the class name if you want, but be sure to change in other places in script.js as well). The code is shown below.
<button id="option0" class="clickOption" data-index="0"></button><br>
<button id="option1" class="clickOption" data-index="1"></button><br>
<button id="option2" class="clickOption" data-index="2"></button><br>
<button id="option3" class="clickOption" data-index="3"></button><br>
Now in your script.js file add the line of code shown below. I have added inline comments for better understanding
// get all elements with class clickoption i.e all option buttons
var elements = document.getElementsByClassName("clickOption");
//use the below array to track the selected answers
var selectedAnswers = [];
var clickOption = function() {
/** Here I have reached the end of the test and,
I am logging the array of user-selected options.
This array can be compared with correctAnswers array
to determine whether the answer is correct or not **/
if(questionNum >= questions.length) {
console.log(selectedAnswers);
return;
}
/**Get the option value that was clicked.
Here I am using parseInt because,
the data-index attribute value will be in string format,
and the correctAnswers array is in Number format so it is better,
to keep the selectedAnswers array in Number format as it will faciliate
easier data comparison**/
var selectedOption = parseInt(this.getAttribute('data-index'));
// add the selected option to the selectedAnwsers Array
selectedAnswers.push(selectedOption);
/** here I am assuming that you are using the questionNum variable
to track the current question Number **/
questionNum += 1;
/** here I am again checking if I have reached the end of test and
thus log the answers
Instead of logging the answer you can create a function
that compares the result and display it on screen **/
if(questionNum >= questions.length) {
console.log(selectedAnswers);
return;
}
// update the next question text
questionEl.textContent = questions[questionNum];
// update next options
displayQuestion(questionNum);
}
//loop through all the elements with class clickOption
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', clickOption);
}
start.addEventListener("click", function() {
timer();
/** I have updated the displayQuestion call implementation
so that the function is called with a parameter
(here the parameter it is zero) **/
displayQuestion(questionNum);
start.style.visibility = "hidden";
buttonEl.style.visibility = "visible";
});
/**Finally I have updated the display question method
so that it updates the option buttons based on the index parameter **/
function displayQuestion(index){
questionEl.textContent = questions[index];
option0.textContent = answers[index][0];
option1.textContent = answers[index][1];
option2.textContent = answers[index][2];
option3.textContent = answers[index][3];
}
Hope this solution helps you. Happy Coding!
I wrote the code provided. But on clicking the button, nothing appears.
function calculate() {
var colony = document.getElementById("co").value;
var dilution = document.getElementById("dil").value;
var inoculum = document.getElementById("in").value;
var b = parseFloat(dilution) * parseFloat(inoculum);
var c = parseFloat(colony) / b;
if (!isNaN(c)) {
document.getElementById("multiplication").innerHTML = "the conentration is " + c;
}
}
<button type="button" onclick="calculate">Calculate</button>
<p id="multiplication"></p>
You didn't call calculate() function. It should be onclick="calculate()" not onclick="calculate".
There's no value property in an element. Use innerText property of an element.
function calculate() {
var colony = document.getElementById("co").innerText;
var dilution = document.getElementById("dil").innerText;
var inoculum = document.getElementById("in").innerText;
var b = parseFloat(dilution) * parseFloat(inoculum);
var c = parseFloat(colony) / b;
if (!isNaN(c)) {
document.getElementById("multiplication").innerHTML = "the conentration is " + c;
}
}
<button type="button" onclick="calculate()">Calculate</button>
<p id="multiplication"></p>
<div id="co">1</div>
<div id="dil">2</div>
<div id="in">4</div>
I have added the HTML, which wasn't provided in the shared code
and it works. It is permissible for input fields to not have an ID attribute.
Client Side:
function calculate() {
var colony = document.getElementById("co").value;
var dilution = document.getElementById("dil").value;
var inoculum = document.getElementById("in").value;
var b = parseFloat(dilution) * parseFloat(inoculum);
var c = parseFloat(colony) / b;
if (!isNaN(c)) {
document.getElementById("multiplication").innerHTML =
"the conentration is " + c;
}
}
HTML:
co: <input type="text" id="co"><br>
dil: <input type="text" id="dil"><br>
in: <input type="text" id="in"><br>
<button type="button" onclick="calculate()">Calculate</button>
<div id="multiplication">fff</div>
In your inital code, your onclick="calculate" was missing () after calculate.
I've added that as well as a script tag within your html with your JavaScript function without changing much of your original code's text.
Working Jsfiddle: https://jsfiddle.net/yuL58da1/
For presentation/educational purposes, I solved the problem using JQuery as well to show you what the solution would look like using JQuery.
Working JsFiddle: https://jsfiddle.net/4g9ayoqb/
Using the JQuery method, I've updated your html button to include a id attribute and removed onclick:
<button id="calculate" type="button">Calculate</button>
and added a JQuery click selector for that button's id:
$(document).on('click','#calculate',function()
I am a beginner in javascript, I am learning arrays. I am working on creating a html interface with javascript to use parallel arrays to obtain a users name and numeric value for each user (Score) I am stuck on understanding how I can save users input in each of the new arrays I created for each input. I have a button to save each name and score entry then I want to create a summary output that will check each score input and pass it through a loop to assign it a category such as A, B, C. I haven't gotten that far as I am confused on how to store each input in their array. The examples provided to me and the ones I found use predetermined values vs user input. This is what I have so far.
<h1>Grades</h1>
</header>
<br>
<p><b>Student Name:</b></p>
<input id="inp" type="text">
<br>
<br>
<p><b>Test Score:</b></p>
<input id="inps" type="text">
<br>
<br>
<br>
<button type="button" onclick="enter()">Enter</button>
<br>
<br>
<button type="button" onclick="summ()">Summary</button>
<br>
<p id="iop"></p>
<br>
<script>
var studentArr = new Array();
var scoreArr = new Array();
function enter() {
var studentName = document.getElementById("inp").value;
studentArr.push(inp);
var stuval = "";
for(i=0; i < studentArr.length; i++)
{
stuval = stuval + studentArr[i] + "<br/>";
}
document.getElementById("iop").innerHTML = stuval;
var studentScore = document.getElementById("inps").value;
scoreArr.push(inps);
var scoreval = "";
for(i=0; i < scoreArr.length; i++)
{
scoreval = scoreval + scoreArr[i] + "<br/>";
}
}
</script>
I belive more easier way exists:
var students = new Array();
function enter() {
students.push({
name: document.getElementById("inp").value,
score: document.getElementById("inps").value
});
show();
}
function show() {
document.getElementById("iop").innerHTML = "";
students.forEach(x => {
document.getElementById("iop").innerHTML += x.name + "<br/>";
});
}
You aren't using the right variable when pushing to your array here
studentArr.push(inp);
and here
scoreArr.push(inps);
Those variables do not exist in your code. You've defined 'studentName' and 'studentScore' so use them and you should have some data in your arrays.
I'm struggling for this work, and I couldn't get help from any other valuable resources. I guess the main problem is the referencing of the variables in the DOM format.
I have the code right here(I'm not sharing the CSS as it may not be important in this error)
`
<script>
var a, b, c;
a = document.forms["inputs"]["deg_2"].value;
b = document.forms["inputs"]["deg_1"].value;
c = document.forms["inputs"]["deg_0"].value;
var D = b^2 - 4*a*c;
var ans1 = (-b + sqrt(D)/2*a);
var ans2 = (-b - sqrt(D)/2*a);
function result(){
document.getElementById('answer1').innerHTML = ans1;
document.getElementById('answer2').innerHTML = ans2;
}
</script>
</head>
<body>
<div class = "head">
<h1 class = "head"> Quad Root Finder </h1>
</div>
<div class = "message">
<h3 class = "message"> Hello user, I am making this Quad Root Finder as one of my starting project. </h3>
</div>
<div class = "derivative">
<form name = "inputs">
<input type="text" name = "deg_2" ></input><lable for = "x^2"> x^2 + </lable>
<input type = "text" name = "deg_1"></input><lable for = "x"> x + </lable>
<input type = "text" name = "deg_0"></input><lable for = "constant"> </lable><br><br>
<button onclick="result()"> Find Roots </button>
</form>
</div>
<p class = "answer_title">
Answer:
</p>
<div class = "answer">
<h3 id = "answer1"> </h3>
<h3 id = "answer2"> </h3>
</div>
</body>
`
The reason you're getting your error is because your JavaScript code is at the top of your HTML page. This means it gets executed before your HTML gets parsed. Therefore, when your code gets run, the elements don't exist as far as the browser's DOM is concerned.
As is pointed out in the comments of the question, you should move all of that logic within your result function otherwise ans1 and ans2 will only ever have the original value when the page loads.
As good practice, you should also move your JavaScript to the bottom of your HTML in order to allow the DOM to be loaded before it executes.
<body>
// All your other HTML
<script>
function result(){
var a, b, c;
a = document.forms["inputs"]["deg_2"].value;
b = document.forms["inputs"]["deg_1"].value;
c = document.forms["inputs"]["deg_0"].value;
var D = b^2 - 4*a*c;
var ans1 = (-b + sqrt(D)/2*a);
var ans2 = (-b - sqrt(D)/2*a);
document.getElementById('answer1').innerHTML = ans1;
document.getElementById('answer2').innerHTML = ans2;
}
</script>
</body>
I need to do the following (I'm a beginner in programming so please excuse me for my ignorance): I have to ask the user for three different pieces of information on three different text boxes on a form. Then the user has a button called "enter"and when he clicks on it the texts he entered on the three fields should be stored on three different arrays, at this stage I also want to see the user's input to check data is actually being stored in the array. I have beem trying unsuccessfully to get the application to store or show the data on just one of the arrays. I have 2 files: film.html and functions.js. Here's the code. Any help will be greatly appreciated!
<html>
<head>
<title>Film info</title>
<script src="jQuery.js" type="text/javascript"></script>
<script src="functions.js" type="text/javascript"></script>
</head>
<body>
<div id="form">
<h1><b>Please enter data</b></h1>
<hr size="3"/>
<br>
<label for="title">Title</label> <input id="title" type="text" >
<br>
<label for="name">Actor</label><input id="name" type="text">
<br>
<label for="tickets">tickets</label><input id="tickets" type="text">
<br>
<br>
<input type="button" value="Save" onclick="insert(this.form.title.value)">
<input type="button" value="Show data" onclick="show()"> <br>
<h2><b>Data:</b></h2>
<hr>
</div>
<div id= "display">
</div>
</body>
</html>
var title=new Array();
var name=new Array();
var tickets=new Array();
function insert(val){
title[title.length]=val;
}
function show() {
var string="<b>All Elements of the Array :</b><br>";
for(i = 0; i < title.length; i++) {
string =string+title[i]+"<br>";
}
if(title.length > 0)
document.getElementById('myDiv').innerHTML = string;
}
You're not actually going out after the values. You would need to gather them like this:
var title = document.getElementById("title").value;
var name = document.getElementById("name").value;
var tickets = document.getElementById("tickets").value;
You could put all of these in one array:
var myArray = [ title, name, tickets ];
Or many arrays:
var titleArr = [ title ];
var nameArr = [ name ];
var ticketsArr = [ tickets ];
Or, if the arrays already exist, you can use their .push() method to push new values onto it:
var titleArr = [];
function addTitle ( title ) {
titleArr.push( title );
console.log( "Titles: " + titleArr.join(", ") );
}
Your save button doesn't work because you refer to this.form, however you don't have a form on the page. In order for this to work you would need to have <form> tags wrapping your fields:
I've made several corrections, and placed the changes on jsbin: http://jsbin.com/ufanep/2/edit
The new form follows:
<form>
<h1>Please enter data</h1>
<input id="title" type="text" />
<input id="name" type="text" />
<input id="tickets" type="text" />
<input type="button" value="Save" onclick="insert()" />
<input type="button" value="Show data" onclick="show()" />
</form>
<div id="display"></div>
There is still some room for improvement, such as removing the onclick attributes (those bindings should be done via JavaScript, but that's beyond the scope of this question).
I've also made some changes to your JavaScript. I start by creating three empty arrays:
var titles = [];
var names = [];
var tickets = [];
Now that we have these, we'll need references to our input fields.
var titleInput = document.getElementById("title");
var nameInput = document.getElementById("name");
var ticketInput = document.getElementById("tickets");
I'm also getting a reference to our message display box.
var messageBox = document.getElementById("display");
The insert() function uses the references to each input field to get their value. It then uses the push() method on the respective arrays to put the current value into the array.
Once it's done, it cals the clearAndShow() function which is responsible for clearing these fields (making them ready for the next round of input), and showing the combined results of the three arrays.
function insert ( ) {
titles.push( titleInput.value );
names.push( nameInput.value );
tickets.push( ticketInput.value );
clearAndShow();
}
This function, as previously stated, starts by setting the .value property of each input to an empty string. It then clears out the .innerHTML of our message box. Lastly, it calls the join() method on all of our arrays to convert their values into a comma-separated list of values. This resulting string is then passed into the message box.
function clearAndShow () {
titleInput.value = "";
nameInput.value = "";
ticketInput.value = "";
messageBox.innerHTML = "";
messageBox.innerHTML += "Titles: " + titles.join(", ") + "<br/>";
messageBox.innerHTML += "Names: " + names.join(", ") + "<br/>";
messageBox.innerHTML += "Tickets: " + tickets.join(", ");
}
The final result can be used online at http://jsbin.com/ufanep/2/edit
You have at least these 3 issues:
you are not getting the element's value properly
The div that you are trying to use to display whether the values have been saved or not has id display yet in your javascript you attempt to get element myDiv which is not even defined in your markup.
Never name variables with reserved keywords in javascript. using "string" as a variable name is NOT a good thing to do on most of the languages I can think of. I renamed your string variable to "content" instead. See below.
You can save all three values at once by doing:
var title=new Array();
var names=new Array();//renamed to names -added an S-
//to avoid conflicts with the input named "name"
var tickets=new Array();
function insert(){
var titleValue = document.getElementById('title').value;
var actorValue = document.getElementById('name').value;
var ticketsValue = document.getElementById('tickets').value;
title[title.length]=titleValue;
names[names.length]=actorValue;
tickets[tickets.length]=ticketsValue;
}
And then change the show function to:
function show() {
var content="<b>All Elements of the Arrays :</b><br>";
for(var i = 0; i < title.length; i++) {
content +=title[i]+"<br>";
}
for(var i = 0; i < names.length; i++) {
content +=names[i]+"<br>";
}
for(var i = 0; i < tickets.length; i++) {
content +=tickets[i]+"<br>";
}
document.getElementById('display').innerHTML = content; //note that I changed
//to 'display' because that's
//what you have in your markup
}
Here's a jsfiddle for you to play around.