Grabbing Values Without Radio Buttons

I put together a simple quiz that uses JavaScript to score the results. It works fine, but I’d like to render the radio buttons invisible using CSS (display: none), then styling each answer as a button (much easier to select than radio buttons). Someone showed me a jQuery script that enlarges radio buttons, but it doesn’t quite work for me.

So I wondered if there’s a way to modify the script I posted at the end of this post so that it somehow selects answers a user has chosen, even with the radio buttons inactive.

If it helps, I’m able to attach classes to various answers using the following jQuery script:

$(".submit").click(function(e) {
    e.preventDefault();
    $("#quiz").toggleClass("Results");
    $("li div").toggleClass("Wrongo");
    $("li.1-A div").toggleClass("Righto");
    $("li.2-B div").toggleClass("Righto");
    $("li.3-C div").toggleClass("Righto");
    $("li.4-D div").toggleClass("Righto");
    $("li.5-A div").toggleClass("Righto");
});

Thanks.

var imgpath = "/images/sections/test/";
var jsonpath = "/2b/inc/pages/quiz-php/json/";
var jsonfile = "key";

$(document).ready(function(){
 //Make sure radio buttons are not disabled or checked (helpful when refreshing)
 $("input[type='radio']").attr("disabled", false);
 $("input[type='radio']").attr("checked", false);
 $(".submit").click(function(e){
    e.preventDefault();
    //Check the quiz results
    checkQuiz();
});
//Build the json filename
jsonfile = $("#quiz").attr("rel")+".php";
});

//Load json file
function getData(update){
 $.getJSON(jsonpath+jsonfile, function(json){
 //Execute the callback
 update(json);
 }).error(function(){alert("error");});
}

function checkQuiz(){
 $(".submit").remove();
 getData(function(data){
    var ans = data.key;
    var result = {};
    $(".Question").each(function(){
        //Get the question id
        var _q = $(this).attr("id");
        //Get the selected answer class
        var _a = $("#"+_q+" input:checked").closest("li").attr("class");
        //Add the values to the result object
        result[_q] = _a;

        //Compare the selected answer with the correct answer
        if(ans[_q]==_a){
            $(this).addClass("correct");
        }else{
            $(this).addClass("wrong");
        }
    });
    //Build the feedback
    var fdbck = "You got "+$(".correct").length+" out of "+$(".Question").length+" correct.  "
    if($(".correct").length==0){
        fdbck += "Better luck next time.";
    }else if($(".correct").length>$(".Question").length/2){
        fdbck += "Good job!";
    }else{
        fdbck += "Not bad.";
    }
    $(".feedback").text(fdbck);
    $(".feedback").show();
 });
}

You can place a label around anything, and that entire section then becomes the active area for selecting things.

Here’s a quick example showing that the entire green background area is completely clickable to select the desired radio button:

<html>
<style>
label p {
    margin: 0;
    padding: 0.5em 0;
    background: lightgreen;
    border-bottom: 1px solid black;
}
</style>
<body>
<form>
    <label for="firstchoice">
        <p><input type="radio" name="choice" id="firstchoice">This is the first 

choice</p>
    </label>
    <label for="secondchoice">
        <p><input type="radio" name="choice" id="secondchoice">This is the second 

choice</p>
    </label>
</form>
</body>
</html>

The radio buttons can also be easily hidden while retaining form functionality by setting their opacity to 0:

input[type="radio"] {
    opacity: 0;
}

Wow, good tip about opacity.

However, when I render the radio buttons invisible, then choose the correct answers, the scoring mechanism doesn’t work.

Since I’m not literally checking the radio buttons, I wonder if I have to change the following code…

$("input[type='radio']").attr("checked", false);

to something like this:

$("input[type='label']").attr("checked", false);

No, the label element doesn’t normally work in that way.

If you supplied us with enough information to put together a working example, or supplied a demo page, then better information and advice can be given that’s more in keeping with what you’re wanting to achieve.

Good idea. I’m going to clean up my code and get it online. Thanks.

Sorry it took so long; I just discovered my database isn’t working because of some CPanel bug.

Anyway, I put a static example of my quiz online at http://www.govwa.org/test/one.php

As you can see, I’ve styled the answers to look like buttons, so I can zap the radio buttons.

If you select the correct answers to questions #1 and #3 (A and C) clicking the radio buttons, when you click the Submit button it should tell you you got two questions right.

If you refresh the page and choose those same two answers, this time clicking the “button” outside the radio button, each answer will be correctly styled, but when you click the Submit button it won’t give you the correct score.

So I’m just trying to figure out a way to make it work without selecting radio buttons. Someone suggested wrapping the answers in links with onclick functions, but I don’t understand exactly how that’s supposed to work. I added links to the answers to questions 4-10, just to play with it.

The answer key is stored at http://www.govwa.org/test/json/key.php. (You can’t get more than 8 right, though, because Question #3 is fill-in-the-blank, which I haven’t figured out how implement yet, and I have to fix another answer. ;))

<li class="4-B">
          <div>
            <label> B. <a href="http://g1/test/gw-intro-1#" id="B" onclick="getAnswer()">
              <input type="radio" name="q4">
              star cluster </a></label>
          </div>
        </li>

The problem is that the label is not connected to the inputs.

Give the input a unique identifier, and associate the label with that input using the for attribute.

<label for="q1a">
    <input type="radio" name="q4" id="q1a">
    ...
</label>

For things to work without JavaScript, forms need to have form elements. But with JavaScript, any element can be assigned an event handler.

I don’t see the link suggestion in this topic (cross-posting ? ) so I’m not sure what they had in mind, but that sounds doable too.

Wow, that’s good to know, even if it isn’t working for me at the moment.

I modified my code so the first four questions look like this:

<div id="quiz" rel="key">
  <ol>
    <li id="q1" class="Question"><span class="Q2">1. No one knows if there&#8217;s just one universe or a series of universes, sometimes referred to as a:</span>
      <ol>
        <li class="1-A">
          <div>
            <label for "1A"> A. <input type="radio" name="q1" id="1A">multiverse</label>
          </div>
        </li>
        <li class="1-B">
          <div>
            <label for="1B"> B. <input type="radio" name="q1" id="1B">parallel universe</label>
          </div>
        </li>
        <li class="1-C">
          <div>
            <label for="1C"> C. <input type="radio" name="q1" id="1C">constellation</label>
          </div>
        </li>
        <li class="1-D">
          <div>
            <label for="1D"> D. <input type="radio" name="q1" id="1D">black hole</label>
          </div>
        </li>
        <li class="Feedback1">Feedback</li>
      </ol>
    </li>

I haven’t been able to publish it online yet (problems with my server or something), but it works just like before on my laptop. But I suspect the problem is with the associated JavaScript file @ http://www.govwa.org/test/js/json.js

For example, I should probably replace type='radio" with type=‘label’ or something like that, right?

$("input[type='radio']").attr("disabled", false);
$("input[type='radio']").attr("checked", false);

At any rate, it sounds like I’m finally on the right track. I was feeling totally lost for a while. :wink:

Interesting… This is where I got my quiz code from, but I didn’t even realize they had a more refined version – http://www.meredithdodge.com/demos/quiz-plugin/

It works if you click outside the radio button. The only problem is the correct answers are assigned the class “correct”, so a user could easily cheat by looking at the source code.

But I wonder if it would work if you used a database and jQuery to attach classes AFTER a user selects some answers and clicks the Submit button.

I’ll play with it tonight.

You will then find that people access the information in other ways to try and get around the system.

The only way to not unintentionally reveal the answers is to only accept their responses and send them to separate answers-processing code on the server side, using PHP or some-such. That can be done all at once, or piecemeal.

The big problem with code being on the client side is that it cannot be secure. The server-side is the best place if you want to ensure security.

Yes, I’m beginning to see what you mean. It’s really hard to tweak this thing and make it work without inserting some giveaway in the code.

So is there a term for the process I need to use to process answers on the server side? I want to try and figure out how to modify this code to make it do that.

Thanks.

The easiest way is to submit the form to the php script and have that script show a new page with the results.

<form action="showResults.php">
   ...
</form>

showResults.php

<?php
    $answers = getAnswers();
    $solutions = getSolutions();
    $html = quizResults($answers, $solutions);
    echo $html;
?>

The above is simplified of course, but that’s the basic structure.

OK, I’ll work on that. I originally canned that idea because I wanted to display the original questions and answers (styled to indicated correct/incorrect answers) on the same page. But I can modify it so they display on a second page.

Thanks!

DIsplaying them on the same page is a second step after getting the above working.

How things progress is that instead of submitting the form to the php page, the form data is submitted to the same php page using AJAX. When the PHP page responds with its output, that data is given to the JavaScript callback-handler that’s waiting for the response. You can then use that data to update the page.

$("form").on('submit', function (event) {
    event.preventDefault();
    var form = this,
        formData = $(this).serialize();

    jQuery.get('results.php', formData, function success(data) {
        $('#result').html(data);
    });
});

None of that though can work until the PHP script is set up to properly do its job, which is achieved as mentioned in the previous post.

The serialize() and jQuery.get() documentation pages have some good examples of how this can work.

I see. Now that I have a traditional form working (and it’s working great), I can use AJAX to eliminate the results page. I’m going to investigate that tonight.

In the meantime, I came up with another idea that requires a second results page, but I think it would be relatively easy. First, imagine three files:

index.php
results.php
score.php

index.php is a dynamic page that displays at a different URL for each quiz (e.g. mysite/test/gw-intro-1). results.php is a static page that all quiz takers are forwarded to (mysite/test/results.php).

Score is essentially a copy of index.php that’s included in results.php. In other words, it’s set up to display quiz questions and answers (similar to index.php), but it’s styled to highlight both correct and incorrect answers. It also displays feedback.

The database query on score.php includes a variable - $MyURL - that associates it with various quizzes. For example, if you take a quiz at mysite/test/gw-intro-1 then the value for $MyURL should be the URL, ‘gw-intro-1’.

So, is there a way to modify the main test page - test/index.php - so that when someone visits mysite/test/gw-intro-1, answers the questions, then clicks the Submit button, the URL - ‘gw-intro-1’ - will be captured and forwarded with the user to results.php?

I’d like to try doing it both ways - using AJAX to display the correct answers and feedback on the same page and my scheme to display them on the results page. Then I can study each one and decide which way to go - or maybe I’ll use both methods in various scenarios.

But is my scheme workable?

Thanks.

That isn’t the only way. It is possible to have the correct answer marked in the JavaScript in such a way that it would take someone who knows JavaScript a reasonable amount of time to figure out the correct answer from the code.

Some years ago I created a number of JavaScript only quiz scripts where each question had two number fields associated with it. A formula built into the script that used those two numbers would identify which of the answers was correct. To be able to identify the correct answer by viewing the source you’d need to locate the code that does the calculation from the two numbers and manually perform that calculation using the numbers. The typical user answering the quiz wouldn’t have been able to figure out that the two numbers identified the correct answer and so the JavaScript only quiz was sufficiently protected from people viewing the source for the types of quiz it was intended to work with.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.