yesman
yesman

Reputation: 7829

Javascript/jQuery - How do you pause the execution of a loop until a form is submitted?

I'm following this guide: http://javascriptissexy.com/how-to-learn-javascript-properly/ Currently, I'm trying to make the Dynamic Quiz detailed further down that page. The idea: loop past all the questions, and for every question in the array, create a new form, wait for it to be submitted, process the submitted information, and continue to the next loop interation. I am currently having trouble, in that I don't know how to pause the loop to wait for the form to be submitted. How do I do this? See the below code, and the function "presentQuestion()" specifically.

$(document).ready(function () {

var questionArray = [
{ question: "The Netherlands", choices: ["Amsterdam", "Monaco", "Chisinau"], correctAnswer: 0 },
{ question: "Austria", choices: ["Bern", "Vienna", "Copenhagen"], correctAnswer: 1 },
{ question: "Bulgaria", choices: ["Budapest", "Sofia", "Minsk"], correctAnswer: 1 },
{ question: "Sweden", choices: ["Stockholm", "Malmo", "Gothenburg"], correctAnswer: 0 },
{ question: "Latvia", choices: ["Vilnius", "Skopje", "Riga"], correctAnswer: 2 },
{ question: "Lithuania", choices: ["Riga", "Skopje", "Vilnius"], correctAnswer: 2 }];;

var score;
var questionField = $("#questionDiv");
var tallyField = $("#tallyDiv");

$("#startButton").on("click", function () {
    resetTally();
    askQuestions();
});

$("#answerButton").on("click", function () {
    // The button from the generated question form.
    // When pressed, call evaluateAnswer() 
})

function askQuestions() {
    for (var i = 0; i < questionArray.length; i++) {
        questionField.empty();
        presentQuestion(questionArray[i]);
    }
}

function presentQuestion(q) {
    questionField.append("What is the capital of " + q.question + "?");
    questionField.append('<form method="POST">');

    for (var i = 0; i < q.choices.length; i++) {
        questionField.append(q.choices[i] + ' <input type="radio" name="answers" id="' + i + '"/></p>')
    }

    questionField.append('<input type="submit" id="answerButton" value="submit answer"/>');

    // to do: code that pauses the askQuestions() for loop
}

function evaluateAnswer() {
    // to do: take the submitted form info and evaluate the given answer. If correct, send  
    // feedback to updateTally()
}

function updateTally(givenAnswer) {
    if (givenAnswer == true) {
        // to do: increase score by 1, loop iteration ends and the next iteration 
        // in askQuestions() starts
    }
    else {
        // Same, but with a score increase of 0
    }
}

function resetTally() {
    tallyField.text("Start answering!");
    score = 0;
}

});

Upvotes: 2

Views: 325

Answers (2)

Mysteryos
Mysteryos

Reputation: 5791

The Short Answer is:

Don't use a loop. Use a javascript variable to keep track of the quiz step where the user currently is.

The Long Answer:

1) Create a new variable to keep track of quiz step

$(document).ready(function () {

var quizstep = 0;

var questionArray = [
{ question: "The Netherlands", choices: ["Amsterdam", "Monaco", "Chisinau"], correctAnswer: 0 },
{ question: "Austria", choices: ["Bern", "Vienna", "Copenhagen"], correctAnswer: 1 },
{ question: "Bulgaria", choices: ["Budapest", "Sofia", "Minsk"], correctAnswer: 1 },
{ question: "Sweden", choices: ["Stockholm", "Malmo", "Gothenburg"], correctAnswer: 0 },
{ question: "Latvia", choices: ["Vilnius", "Skopje", "Riga"], correctAnswer: 2 },
{ question: "Lithuania", choices: ["Riga", "Skopje", "Vilnius"], correctAnswer: 2 }];

...

2) Replace askQuestions function with the one below.

...
function askQuestions() {

    if(quizstep < questionArray.length)
    {
        questionField.empty();
        presentQuestion(questionArray[quizstep]);
        quizstep++;
    }
}
...

Upvotes: 3

Ryan Mitchell
Ryan Mitchell

Reputation: 744

In your case, Mysteryos' solution is the way to go.

But your question got me thinking: how would you pause a for-loop?

One way of doing it is to change the for-loop into a recursive function that waits for a promise to be resolved() before it calls itself again. I'm thinking something like this:

var current = 0;
var max = 10;
var deferred = null;

function selfReferential() {
    if (current < max) {
        $("body").append("<p>"+current+"</p>");
        current += 1;
        deferred = $.Deferred();
        deferred.promise().then(selfReferential);
    } else {
        $("body").append("<p>All done!</p>");
    }
}


selfReferential();


    // Somewhere else in your code...

    if (deferred && deferred.state() == "pending") {
        deferred.resolve();
    }

There's a working example in this jsFiddle.

If you want to know more about promises, you can look here.

Upvotes: 3

Related Questions