简体   繁体   中英

How do I obtain data from a JSON file when a checkbox is checked using Javascript?

I'm a beginner in javascript and I'm trying to build a little flashcard game that allows users to select different libraries of flashcards when they click a checkbox and I am having some difficulty implementing this feature. What I want my code to do is change the dataset that gets displayed when someone clicks on a checkbox of their choice.

Here is a picture of the checkboxes and the flashcards:

在此处输入图片说明

This is the HTML code for the checkboxes:

<div id="flashcard_sets">
    <div id="card_group">
        <h3><u>Choose Flashcard Set</u></h3>
        <input type="checkbox" id="question_words" name="Question Words" value="Question Words" class="vocab">Question Words
        <input type="checkbox" id="verbs" name="Verbs" value="Verbs" class="vocab">Verbs
        <input type="checkbox" id="nouns" name="Nouns" value="Nouns" class="vocab">Nouns
    </div>
</div>

My data is saved in an external json file stored in this variable: var jsonUrl = "questionsAndAnswersItalian.json"; that contains this information:

{"Question Words":[{"q":"What is the word for 'where' in Italian?","a":"Dove"},
{"q":"What is the word for 'when' in Italian?","a":"Quando"},
{"q":"What is the word for 'why' in Italian?","a":"Perché"}],
"Verbs":[{"q":"What is the verb for 'I am'?","a":"Sono"},
{"q":"What is the verb for 'you are'?","a":"tu sei"},
{"q":"What is the verb for 'he is'?","a":"lui è"}],
"Nouns":[{"q":"gioco","a":"game"},
{"q":"buco","a":"hole"},
{"q":"amico","a":"friend"}]}

This is the javascript function that displays the flashcard:

var jsonUrl = "questionsAndAnswersItalian.json";
var cardIndex = 0;
var qs;
var numCards;
var maxIndex;
var isFlipped = 0;

function displayCard() {
    $("#card").fadeOut(400,function(){
        colorIndex = getRandomInteger(0,3);
        $("#card").addClass(colorClasses[colorIndex])
        isFlipped = 0;
        var newHtml = "<h2>Question Words</h2>";
        var chosen_one = $("#card_group input[type=checkbox]:checked")
        if(chosen_one){
            var selection = chosen_one.attr("name");
            newHtml += qs["selection"][cardIndex]["q"];
        }else{
            newHtml += qs["Question Words"][cardIndex]["q"];
        }
        document.getElementById("question").innerHTML = newHtml;
    }).fadeIn(400);
}

This is the code that grabs the external json data to display on the flashcard:

var jsonUrl = "questionsAndAnswersItalian.json";
var cardIndex = 0;
var qs;
var numCards;
var maxIndex;
var isFlipped = 0;

function init() {
    $.getJSON(jsonUrl, function(jsonObject) {
        qs = jsonObject;
        var chosen_one = $("#card_group input[type=checkbox]:checked")
        if(chosen_one){
            var selection = chosen_one.attr("name");
            numCards = qs["selection"].length;
        }else{
            numCards = qs["Question Words"].length;
        }
        maxIndex = numCards-1;
        displayCard();
    });
}

I know I definitely did something wrong and I've tried several solutions but now I don't really know what to do to get this working. If anyone could provide some help or advice on this, I'd greatly appreciate it.

Thanks!

Link to full code that isn't working: http://plnkr.co/edit/Uhau56byCGOLJiQxmFFg?p=preview

Link to original code without the code you wrote, and with javascript functions embedded into the HTML file. You can take a look at this to see what I want to do with my code: http://plnkr.co/edit/kxzTPX3VhYKZGNDkDoWX?p=preview

Firstly, you want to use radio buttons because you only want one to be selected.

So I've slightly re-written it to get you on the right path.

function init() {
    $.getJSON(jsonUrl, function(jsonObject) {
        qs = jsonObject;
        changeCard("Question Words");
    });
}

$('.vocab').change(function () {
  var chosen_one = $(this).val();
  changeCard(chosen_one);
});

var changeCard = function(chosen_one) {
  $("#card").fadeOut(400,function(){
      isFlipped = 0;
      var newHtml = qs[chosen_one][cardIndex]["q"];
      maxIndex = qs[chosen_one].length;
      $('#questionTitle').html(chosen_one);
      $('#question').html(newHtml);
      console.log(maxIndex);
  }).fadeIn(400);
};

HTML:

<div id="card">
  <h2 id="questionTitle"></h2>
  <div id="question"></div>
</div>

<div id="flashcard_sets">
<div id="card_group">
    <h3><u>Choose Flashcard Set</u></h3>
    <label for="question_words"><input type="radio" id="question_words" name="vocab" value="Question Words" class="vocab" checked>Question Words</label>
    <label for="verbs"><input type="radio" id="verbs" name="vocab" value="Verbs" class="vocab">Verbs</label>
    <label for="nouns"><input type="radio" id="nouns" name="vocab" value="Nouns" class="vocab">Nouns</label>
</div>

plunker: http://plnkr.co/edit/WjDKys?p=preview

    if(document.getElementsByTagName("input").checked){

This line is definitely going to be a problem. document.getElementsByTagName returns an array of Elements, and because arrays do not have a checked attribute, this statement will evaluate to undefined. Because undefined has a false truth value, anything inside of your if statement will not be executed.

Now, this does not mean that you can't search through the array of input elements yourself to find the checked box. You will have to do a for-loop to check the boxes yourself:

var chosen_one;
for (var i=0; i < document.getElementsByTagName("input").length; i++){
    var box = document.getElementsByTagName("input")[i];
    if (box.checked) {
        chosen_one = changeCardset();
        numCards = qs["chosen_one"].length;
    }
}
if (!chosen_one) numCards = qs["Question Words"].length;

You will also have to change your changeCardset function to have a similar for-loop for finding the box (if any) that is checked.

The key part that is going wrong here is that

document.getElementsByTagName("input")

is returning a NodeList. In order to look at any parameters of this list, it needs to be iterated. A more appropriate approach would be to look for the checked one.

var chosen_one = $("#card_group input[type=checkbox]:checked");

however, the problem here is that there can be up to 3 checked. Addressing this will fix the problem in your code.

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