简体   繁体   中英

JQuery: Checking / Unchecking Radio Buttons

I trying to figure out the error in my script and am hoping somebody is able to tell me where I am going wrong. It is an attempt to create a quiz based on JS/Jquery (the javascriptissexy exercises).

So far it is working fine, except: I want to use a back button that recalls the previous answers given by the user and sets the radio buttons accordingly. The script doesn't go back and even if I click forward it gives me no errors that would help me to pinpoint the problem.

Again I am really sorry that I can not narrow it more down because I really don't know which parts are relevant/not relevant. If anyone has some suggestions how to present those "I'm close to giving up because I don't know how to pinpoint the issue" problems in a better way I would be happy to do so.

The HTML radio buttons are all structured like this:

 <input type="radio" name="radio" id="Option0" value="Option0" />
 <label for ="Option0">Option0</label>

The JS/Jquery:

 $(document).ready(function () {
 var allQuestions = [
    {question: "Who is Prime Minister of the United Kingdom?",
        choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
        correctAnswer: 0},
    {question: "Which color has the sky?",
        choices: ["Grey", "Black", "Blue", "Green"],
        correctAnswer: 2},
    {question: "What's on the chain?",
        choices: ["Monster", "Magician", "Bull", "Skull"],
        correctAnswer: 3}
];

var counter = 0;     // Question No currently processed
var points = 0;        // Total points currently reached by the player
var answers = new Array(); // Array of the choices the player made  eg Q1:0

// Back button in a function
function back() {
    if (counter > 0)          //Checks if there is at least one question already answered
    {
        //Goes back one question

        $("#back").show().on('click', function () {
            counter = counter--;
            quiz();
        });      //Executes quiz loading

    }
    else {
        $("#back").hide();         //If there is no previous question existing the back button is deactivated
    }
}


function qload(counter) {
    $("title").text("Question No ");
    $("#question").text(allQuestions[counter].question);
    back();
    for (var i = 0; i < allQuestions[counter].choices.length; i++) {
        $('label[for=Option' + i + ']').html(allQuestions[counter].choices[i]);

        if (answers["Q" + i]) {
            $("#Option" + i).attr("checked","checked");
        }

        else {
            $("#Option" + i).removeAttr('checked');
        }
    }
};
//this is the result screen giving the final amount of points
function result() {
    $("title").text("Your Results");
    for (var i = 0; i < allQuestions.length; i++) {
        if (allQuestions[i].correctAnswer == answers["Q" + i]) {
            points++;
        }


        $("#result").show().text("CONGRATULATIONS! You answered " + points + " out of " + allQuestions.length + " correct!");
        $(".qbox").hide();
        console.log(answers);

    }
}

function welcome() {
    // this is the welcome screen inviting to start the quizz
    $("title").text("Welcome to the JQuery QuizY");
    $(".qbox").hide();
    $("#result").append().html("Random");
    $("#result").append().html("<p id='start'>Start</p>");
    $("#start").on('click', function () {
        quiz();
    });
}

function quiz() {
    $("#start, #result").hide();
    $(".qbox").show();
    qload(counter);
    $("#next").on('click', function () {
        // this checks that one question is selected before processing
        if ($('#Option0').is(':checked')) {
            answers["Q" + counter] = 0;
            counter++;
        }

        else if ($('#Option1').is(':checked')) {
            answers["Q" + counter] = 1;
            counter++;
        }

        else if ($('#Option2').is(':checked')) {
            answers["Q" + counter] = 2;
            counter++;
        }

        else if ($('#Option3').is(':checked')) {
            answers["Q" + counter] = 3;
            counter++;
        }

        else {
            alert("Please make your selection before continuing!");
        }

        // this checks if there are any questions left, otherwise it goes to the result screen
        if (allQuestions[counter]) {
            qload(counter);
        }
        else {
            result();
        }
    });
}

welcome();

});

1) You cannot refer to element of array by using a string as index (answers["Q" + i]). You have to either use number as array index, or use object instead of array.

2) Don't use the .attr() method for modifying DOM properties such as the "checked". Use the .prop() method instead. So you have to replace this snippet:

if (answers["Q" + i]) {
    $("#Option" + i).attr("checked","checked");
}

else {
    $("#Option" + i).removeAttr('checked');
}

with the following:

$("#Option" + i).prop("checked", Boolean(answers["Q" + i]));

3) Your way of getting value of user's answer is very cumbersome yet strange. This code:

    if ($('#Option0').is(':checked')) {
        answers["Q" + counter] = 0;
        counter++;
    }

    else if ($('#Option1').is(':checked')) {
        answers["Q" + counter] = 1;
        counter++;
    }

    else if ($('#Option2').is(':checked')) {
        answers["Q" + counter] = 2;
        counter++;
    }

    else if ($('#Option3').is(':checked')) {
        answers["Q" + counter] = 3;
        counter++;
    }

    else {
        alert("Please make your selection before continuing!");
    }

may be replaced with the following:

var oEl = $('input:radio[name=radio]:checked');
if (oEl.length) {
    answers[counter] = parseInt(oEl.val());
    counter++;
}
else {
    alert("Please make your selection before continuing!");
}

Also the following fix of html code of radio buttons is needed:

<input type="radio" name="radio" id="Option0" value="0" />
<label for ="Option0">Option0</label>

Plus some other changes...

So the total code update:

$(document).ready(function () {
var allQuestions = [
    {question: "Who is Prime Minister of the United Kingdom?",
        choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
        correctAnswer: 0},
    {question: "Which color has the sky?",
        choices: ["Grey", "Black", "Blue", "Green"],
        correctAnswer: 2},
    {question: "What's on the chain?",
        choices: ["Monster", "Magician", "Bull", "Skull"],
        correctAnswer: 3}
];

var counter = 0; // Question No. currently processed
var answers = new Array(); // Array of the choices the player made

$('#back').click(function(){
    counter++;
    quiz();
});

// update Back button appearance
function updateBackBtn() {
    if (counter > 0)
        $("#back").show();
    else
        $("#back").hide();
}

// set current question
function qload(counter) {
    $("title").text("Question No ");
    $("#question").text(allQuestions[counter].question);
    updateBackBtn();
    for (var i = 0; i < allQuestions[counter].choices.length; i++) {
        $('label[for=Option' + i + ']').html(allQuestions[counter].choices[i]);

        $("#Option" + i).prop("checked", Boolean(answers[i]));
    }
};

// this is the result screen giving the final amount of points
function result() {
    $("title").text("Your Results");
        var points = 0; // Total points currently reached by the player
    for (var i = 0; i < allQuestions.length; i++) {
        if (allQuestions[i].correctAnswer == answers[i]) {
            points++;
        }
        $("#result").show().text("CONGRATULATIONS! You answered " + points + " out of " + allQuestions.length + " correct!");
        $(".qbox").hide();
        console.log(answers);

    }
}

function welcome() {
    // this is the welcome screen inviting to start the quizz
    $("title").text("Welcome to the JQuery QuizY");
    $(".qbox").hide();
    $("#result").append().html("Random");
    $("#result").append().html("<p id='start'>Start</p>");
    $("#start").on('click', function () {
        quiz();
    });
}

function quiz() {
    $("#start, #result").hide();
    $(".qbox").show();
    qload(counter);
    $("#next").on('click', function () {
        // get an input element containing selected option (answer)
        var oEl = $('input:radio[name=radio]:checked');
        // if such input element exists (any answer selected)
        if (oEl.length) {
            answers[counter] = parseInt(oEl.val());
            counter++;
        }
        else {
            alert("Please make your selection before continuing!");
        }

        // this checks if there are any questions left, otherwise it goes to the result screen
        if (counter < allQuestions.length) {
            qload(counter);
        }
        else {
            result();
        }
    });
}

welcome();

});

I have gone through the code and made few chagnes.

Please review below updated code.

$(document).ready(function () {
                var allQuestions = [
                    {question: "Who is Prime Minister of the United Kingdom?",
                        choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"],
                        correctAnswer: 0},
                    {question: "Which color has the sky?",
                        choices: ["Grey", "Black", "Blue", "Green"],
                        correctAnswer: 2},
                    {question: "What's on the chain?",
                        choices: ["Monster", "Magician", "Bull", "Skull"],
                        correctAnswer: 3}
                ];

                var counter = 0;     // Question No currently processed
                var points = 0;        // Total points currently reached by the player
                var answers = new Array(); // Array of the choices the player made  eg Q1:0

                // Back button in a function
                function back() {
                    if (counter > 0)          //Checks if there is at least one question already answered
                    {
                        $("#back").show();
                    }
                    else {
                        $("#back").hide();         //If there is no previous question existing the back button is deactivated
                    }
                }

                $('#back').click(function(){
                    counter = --counter;
                    quiz();//Executes quiz loading
                });

                function qload(counter) {
                    $("#title").html("Question No "+counter);
                    $("#question").text(allQuestions[counter].question);
                    back();
                    for (var i = 0; i < allQuestions[counter].choices.length; i++) {
                        $('label[for=Option' + i + ']').html(allQuestions[counter].choices[i]);
                        if (answers["Q" + counter] == i) {
                            $("#Option" + i).prop('checked',true);
                        }

                        else {
                            $("#Option" + i).removeAttr('checked');
                        }
                    }
                };

                //this is the result screen giving the final amount of points
                function result() {
                    $("#title").html("Your Results");
                    for (var i = 0; i < allQuestions.length; i++) {
                        if (allQuestions[i].correctAnswer == answers["Q" + i]) {
                            points++;
                        }


                        $("#result").show().text("CONGRATULATIONS! You answered " + points + " out of " + allQuestions.length + " correct!");
                        $(".qbox").hide();
                        console.log(answers);

                    }
                }

                function welcome() {
                    // this is the welcome screen inviting to start the quizz
                    $("title").html("Welcome to the JQuery QuizY");
                    $(".qbox").hide();
                    $("#result").append().html("Random");
                    $("#result").append().html("<p id='start'>Start</p>");
                    $("#start").on('click', function () {
                        quiz();
                    });
                }

                function quiz() {
                    $("#start, #result").hide();
                    $(".qbox").show();
                    qload(counter);
                }
                $("#next").click(function () {
                    // this checks that one question is selected before processing
                    if ($('#Option0').is(':checked')) {
                        answers["Q" + counter] = 0;
                        ++counter;
                    }

                    else if ($('#Option1').is(':checked')) {
                        answers["Q" + counter] = 1;
                        ++counter;
                    }

                    else if ($('#Option2').is(':checked')) {
                        answers["Q" + counter] = 2;
                        ++counter;
                    }

                    else if ($('#Option3').is(':checked')) {
                        answers["Q" + counter] = 3;
                        ++counter;
                    }

                    else {
                        alert("Please make your selection before continuing!");
                    }

                    // this checks if there are any questions left, otherwise it goes to the result screen
                    if (allQuestions[counter]) {
                        qload(counter);
                    }
                    else {
                        result();
                    }
                });

                welcome();

            });

I have made above changes and tested it on my local and it worked.

Please let me know if you face any issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM