Question

I am making a simple quiz, and I have gotten to the point that my script loads a new question and new answers. My submit button only works the first time, if I select an answer the second time and press submit, the script/page seems to reload. Why?

JSFiddle: http://jsfiddle.net/4XxzT/

HOWTO: Choose the SECOND answer (Gul, Grøn, Blå) and press 'SVAR'. It will say you're right. Then press the button 'FORTSÆT'. New question. Choose any button and press submit. Error!
I hope you can decode my script -and- language ;) Just ask if you need more info.

CODE:

$(document).ready(function () {

var current = 0;

var spg = [{
    "question": "Hvilke farver har det BRASILIANSKE flag?",
    "answer1": "Rød, Grøn, Gul",
    "answer2": "Gul, Grøn, Blå",
    "answer3": "Hvid, Grøn, Rød",
    "answer4": "Blå, Rød, Hvid",
    "correct": "Gul, Grøn, Blå"
}, {
    "question": "Hvilke farver har det ITALIENSKE flag?",
    "answer1": "Gul, Grøn, Rød",
    "answer2": "Blå, Grøn, Gul",
    "answer3": "Rød, Grøn, Hvid",
    "answer4": "Hvid, Rød, Blå",
    "correct": "Rød, Grøn, Hvid"
}, {
    "question": "Hvilke farver har det AUSTRALSKE flag?",
    "answer1": "Grøn, Gul, Rød",
    "answer2": "Grøn, Gul, Blå",
    "answer3": "Grøn, Hvid, Rød",
    "answer4": "Rød, Blå, Hvid",
    "correct": "Rød, Blå, Hvid"
}, ];

var flag = [{
    "start": ""
}, {
    "flags": "brasil.png"
}, {
    "flags": "italy.png"
}, {
    "flags": "australia.png"
}, ];

function questions() {
    $("#q").html('Spørgsmål: <br>' + spg[current].question);
};

questions();

function answers() {
    $("#a").html('Svarmuligheder: <br>' + '<input type="radio" name="a" id="1">' + spg[current].answer1 + '<br>' + '<input type="radio" name="a" id="2">' + spg[current].answer2 + '<br>' + '<input type="radio" name="a" id="3">' + spg[current].answer3 + '<br>' + '<input type="radio" name="a" id="4">' + spg[current].answer4 + '<br>' + '<input id="knapsvar" type="submit" value="Svar"><input id="continue" type="submit" value="fortsæt"><input id="forfra" type="submit" value="forfra">');
    $("#continue").hide();
    $("#forfra").hide();
};

answers();

function rigtig() {
    event.preventDefault();
    $("#c").html('svaret er RIGTIGT: <br> ' + spg[current].correct);
    $("#extra").html('<img id="flagsize" src="' + flag[1].flags + '">');
    $("#q").html('');
    $("#knapsvar").hide();
    $("#continue").show();
    $("#forfra").show(1000);

};

$('#knapsvar').click(function () {
    event.preventDefault();
    if ($('#2').is(':checked')) {
        rigtig();
    } else {
        $('#c').html('Du har ikke valgt rigtigt! Prøv igen.');
    };
});

$('#continue').click(function () {
    current++;
    $("#continue").hide(1000)
    $("#c").html('')

    questions();
    answers();
});

$('#forfra').click(function () {
location.reload();
});

});

Was it helpful?

Solution

The assignment of the "click" handler for "knapsvar" should be done like this:

$('body').on('click', '#knapsvar', function() {
  event.preventDefault();
  // and so on
}

If you do it that way, you fix the current issue: every time you overwrite the HTML for the questions/answers, you're getting rid of the event handler assignment. In other words, the code you have now sets up the "click" handler directly on the element you created. When you create the next question, you eliminate that element, and with it goes the event handler assignment.

By using the delegated form above, the handler goes on the <body> element. The handler responds to clicks on any target element whose id is "knapsvar", so it won't matter that you've generated new HTML for each question.


This isn't really on the original topic, but you could improve the data structure used for your question/answer list to make creating the HTML a lot easier.

var spg = [{
    "question": "Hvilke farver har det BRASILIANSKE flag?",
    answers: [
      "Rød, Grøn, Gul",
      "Gul, Grøn, Blå",
      "Hvid, Grøn, Rød",
      "Blå, Rød, Hvid"
    ],
    "correct": 1
}, {
    "question": "Hvilke farver har det ITALIENSKE flag?",
    answers: [
      "Gul, Grøn, Rød",
      "Blå, Grøn, Gul",
      "Rød, Grøn, Hvid",
      "Hvid, Rød, Blå"
    ],
    "correct": 2
}, {
    "question": "Hvilke farver har det AUSTRALSKE flag?",
    answers: [
      "Grøn, Gul, Rød",
      "Grøn, Gul, Blå",
      "Grøn, Hvid, Rød",
      "Rød, Blå, Hvid"
    ],
    "correct": 3
}, ];

Now, to build the HTML from that:

function answers() {
  $("#a").html(
   'Svarmuligheder: <br>' +
   spg[current].answers.map(function(ans, index) {
     return "<input type=radio name=a id=" + index + (class == spg[current].correct ? " class=correct " : "") + "> " +
       ans + "<br>";
   }).join("") +
   '<input id="knapsvar" type="submit" value="Svar"><input id="continue" type="submit" value="fortsæt"><input id="forfra" type="submit" value="forfra">'
 );

Now the code that checks to see if the answer is correct can just check to see if the checked radio button has the class "correct".

Note that people taking the quiz can quite easily examine the page source and cheat, and that's true no matter how you write the JavaScript code. The only way to make it secure is to check the answers at the server.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top