dzenesiz
dzenesiz

Reputation: 1542

Populating HTML with Javascript onload

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>&nbsp;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/

Upvotes: 0

Views: 2349

Answers (2)

cezar
cezar

Reputation: 12012

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.

Upvotes: 1

Amitd
Amitd

Reputation: 4849

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?

Upvotes: 3

Related Questions