SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Jan 2012
    Location
    Seattle, WA
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Question linking data value in HTML with array value in JS

    I'm building a site that contains several quizzes. To avoid redundant code, each quiz will have a javascript array to hold the answers - an answer key. I'm wanting to do all of this client-side with JS/JQuery. I need to link each quiz question with it's answer in it's corresponding answer key. Here's a snippet of 2 questions from one of the quizzes. (The .check-answer button is not a submit button because I don't want to submit anything to the server.)

    Code:
    <li class="group">
        <div class="question group">
            <p>What note is this?</p>
            <img src="../img/Quiz/notesOnTrebleQuiz/C5.gif" alt="3rd space from bottom" />
        </div><!-- end .question -->
        <div class="choices">
            <form data-question-id="1">
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A1" type="radio" value="A" />A
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A2" type="radio" value="B" />B
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A3" type="radio" value="C" />C
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A4" type="radio" value="D" />D
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A5" type="radio" value="E" />E
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A6" type="radio" value="F" />F
                </label>
                <label>
                    <input name="quizAnswer" id="notesOnTrebleQuiz_Q1A7" type="radio" value="G" />G
                </label>
                <a class="check-answer">check answer</a>
            </form>
        </div><!-- end .choices -->
        <div class="answer">
            <p class="correct">Correct!</p>
            <p class="incorrect">Incorrect.</p>
        </div><!-- end .answer -->
    </li>
    <li class="group">
        <div class="question group">
            <p>What note is this?</p>
            <img src="../img/Quiz/notesOnTrebleQuiz/F4.gif" alt="1st space on bottom" />
        </div><!-- end .question -->
        <div class="choices">
            <form data-question-id="2">
            <label>
                <input name="quizAnswer" type="radio" value="A" />A
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="B" />B
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="C" />C
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="D" />D
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="E" />E
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="F" />F
            </label>
            <label>
                <input name="quizAnswer" type="radio" value="G" />G
            </label>
            <a class="check-answer">check answer</a>
            </form>
        </div><!-- end .choices -->
        <div class="answer">
            <p class="correct">Correct!</p>
            <p class="incorrect">Incorrect.</p>
        </div><!-- end .answer -->
    </li>
    And here's my corresponding JS code:

    Code:
    var notesOnTrebleAnswerKey = {
                    1: 'C',
                    2: 'F',
                    3: 'D',
                    4: 'D',
                    5: 'E',
                    6: 'A',
                    7: 'G',
                    8: 'D',
                    9: 'C',
                    10: 'C',
                    11: 'B',
                    12: 'F',
                    13: 'G',
                    14: 'E',
                    15: 'F',
                    16: 'A',
                    17: 'B',
                    18: 'A',
                    19: 'G',
                    20: 'B',
                    21: 'E',
                    22: 'G'
    }
    
    //when check answer, provides response
    $('.check-answer').click(function(){
    var getResult = $(this).find('.answer');
    
    var answers = $(this).parent('.choices');
    
    var question = answers.data('question-id');//may need to separate .choices from data-question-id
    
    var answer = answers.find('input:selected').val();
    
    var correct = $('.answer').find('.correct');
    var incorrect = $('.answer').find('.incorrect');
    
    //Notes on Treble Quiz
    if(notesOnTrebleAnswerKey[question] == answer){
                    getResult.find('.correct').show();
                    getResult.find('.incorrect').hide();
                    /*
                    correct.show();
                    incorrect.hide();
                    */
    } else {
                    getResult.find('.correct').hide();
                    getResult.find('.incorrect').show();
                    /*
                    correct.hide();
                    incorrect.show();
                    */
    }
    I can't figure out why this isn't working. Can anyone help?

  2. #2
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,026
    Mentioned
    64 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mnicki_mouse View Post
    I'm building a site that contains several quizzes. To avoid redundant code, each quiz will have a javascript array to hold the answers - an answer key. I'm wanting to do all of this client-side with JS/JQuery. I need to link each quiz question with it's answer in it's corresponding answer key. Here's a snippet of 2 questions from one of the quizzes. (The .check-answer button is not a submit button because I don't want to submit anything to the server.)
    [/CODE]

    I can't figure out why this isn't working. Can anyone help?
    Unless this is a programming exercise you should not do this with javascript alone. You need to conceal the answers, and you cannot conceal your javascript code.

    You can create an array using the names of the element.

    [highlight=html]
    <input type="radio" name="answers[1]" value="1">
    <input type="radio" name="answers[1]" value="2">
    [/html]

    That will produce a server side array that looks like this in PHP

    Code php:
    array( '1' => '3'
      '2' => '1'
      '3' => '

    That said, the main reason this isn't working is 'quizAnswers' must have a different name for each question for the radio buttons to work correctly. Radio buttons only allow one to be selected for all the buttons that share the same name.

  3. #3
    SitePoint Addict sdleihssirhc's Avatar
    Join Date
    Feb 2009
    Posts
    387
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)
    The errors I found all had to do with a misunderstanding of how jQuery searches the DOM, so let's go through it one step at a time...

    Which element do you start with?

    Here's your code:

    Code JavaScript:
    $('.check-answer').click(function(){
        // ...
    });

    It's waiting for an element with a class of "check-answer" to be clicked. That's what "this" will refer to in the function. But your first line in the function is...

    Code JavaScript:
    var getResult = $(this).find('.answer');

    The find function searches child nodes, but "this" refers to an <a> element... It has no child nodes*, much less the .answer <div>.

    *no child element nodes, anyway

    Instead, a good starting point would be the <div> that has the "choices" class, so let's start there:

    Code JavaScript:
    var answers = $(this).parents('.choice');

    Note that I used .parents, not .parent. The former searches all of the ancestors, while the latter only looks at the immediate parent.

    How do you get the question ID?

    Again, here's your code first:

    Code JavaScript:
    var answers = $(this).parent('.choices');
    var question = answers.data('question-id');

    Even if we change the first line so that it uses .parents instead of .parent, there's still a mistake: The data-question-id attribute isn't on the .choices <div>, it's on the <form>, which is a child of the <div>. So the quick fix is to just look for it:

    Code JavaScript:
    var question = answers.find('form').data('question-id');

    How do you get the answer that's currently selected?

    This is a simple change:

    Code JavaScript:
    // you had this...
    var answer = answers.find('input:selected').val();
     
    // but "selected" is incorrect
    // these are radio buttons, so we need "checked"
    var answer = answers.find('input:checked').val();

    Put it all together, and what do you get...

    Here's the kind-of-slimmed-down event listener after making these changes:

    Code JavaScript:
    $('.check-answer').click(function() {
        var answers = $(this).parents('.choices');
        var getResult = answers.siblings('.answer'); // <-- used the .siblings method instead
     
        var question = answers.find('form').data('question-id');
        var answer = answers.find('input:checked').val();
     
        //Notes on Treble Quiz
        if (notesOnTrebleAnswerKey[question] == answer) {
            getResult.find('.correct').show();
            getResult.find('.incorrect').hide();
        } else {
            getResult.find('.correct').hide();
            getResult.find('.incorrect').show();
        }
    });

    You're awesome.

    Thanks.
    I'm the web overlord for Graphic Business Systems

  4. #4
    SitePoint Member
    Join Date
    Jan 2012
    Location
    Seattle, WA
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the response. I just started learning JS, so this is kind of a test to see if I could figure out how to do it with JS.

    I agree that it would be better to have the answers concealed by using PHP, but I also want the users to have immediate feedback after answering each question. Plus, I'm not storing any of the data (yet), so I figured the easiest thing to do was to write it in JS.

    Is there a way to do this with PHP that would still allow users immediate feedback - maybe store the array in PHP but load and access it somehow with JS? Obviously, I'm new at this. Your help is much appreciated.

  5. #5
    SitePoint Member
    Join Date
    Jan 2012
    Location
    Seattle, WA
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Lightbulb

    Thank you so much for explaining this! Yes, I am new with JS. You helped me learn instead of just giving me an answer. Plus, it works! Thank you, sdleihssirhc!


Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •