user3052485
user3052485

Reputation: 71

Integrating a JSON file into html with Mustache

I think im fairly close, I have looked at a fair few examples of integrating an external JSON file into html with mustache, but at the moment it isnt working. The JSON file is full of trivia questions, here is a sample question that I am trying to link:

{
  "jsonquestions": [
    {
      "id":1,
      "q_category_id":0,
      "q_text":"Which of the following is regar-ded as the real founder of portugese power in India",
      "q_options_1":"Pedro Cabral",
      "q_options_2":"Almeida",
      "q_options_3":"Vasco da Gama",
      "q_options_4":"Alfonso de Albuquerque",
      "q_correct_option":4,
      "q_difficulty_level":2,
      "q_date_added":"2013-06-10T04:00:00.000Z"
    }
  ]
}

The file is named questions.json, I am trying to link it into this html table:

<!DOCTYPE html>

<html class="no-js" lang="">
<head>
    <link rel="stylesheet" href="index.css">
    <meta charset="utf-8">
    <meta content="ie=edge" http-equiv="x-ua-compatible">

    <title>Quiz</title>
    <meta content="" name="description">
    <meta content="width=device-width, initial-scale=1" name="viewport">
</head>

<body>

    <hr>

    <div id="control">
    <h1>Questions</h1>Data generated from <a href=
    "https://market.mashape.com/pareshchouhan/trivia">
    https://market.mashape.com/pareshchouhan/trivia</a>
    <br><br>

        Search questions:
        <input type="text" id="searchText">
        <button id="search">Search Questions</button>
        <select id="sortquestions">
            <option id="idascend">Ascending ID</option>
            <option id="iddescend">Descending ID</option>
            <option id="alphabetascend">Ascending Alphabetical</option>
            <option id="alphabetdescend">Descending Alphabetical</option>
            <option id="diffascend">Ascending Difficulty</option>
            <option id="diffdescend">Descending Difficulty</option>
        </select>
        <button id ="sort">Sort</button>
    <br><br>

        Filter by difficulty:
        <input type="radio" name="difficulty" id="1" value="1" checked> 1
        <input type="radio" name="difficulty" id="2" value="2"> 2
        <button id="difficultybutton">Filter</button>
        <button id="random">Randomise</button>
        <button id="quiz">Begin Quiz!</button>
    <br><br>
    </div>  

    <table id="anchor"></ul>

    <script id="questions-template" type="text/template">  
    {{#jsonquestions}}
    <table id="questions">
        <thead>
            <tr>
                <th>ID</th>

                <th>Question</th>

                <th>Answer 1</th>

                <th>Answer 2</th>

                <th>Answer 3</th>

                <th>Answer 4</th>

                <th>Correct Answer</th>

                <th>Difficulty</th>
            </tr>
            <tr>
                <td>{{id}}</td>

                <td>{{q_text}}</td>

                <td>{{q_options_1}}</td>

                <td>{{q_options_2}}</td>

                <td>{{q_options_3}}</td>

                <td>{{q_options_4}}</td>

                <td>{{q_correct_option}}</td>

                <td>{{q_difficulty_level}}</td>
            </tr>
        </thead>

        <tbody>
        </tbody>
    </table>
    {{/jsonquestions}}
    </script>

    <script> 
    $(function() {
        $.getJSON('js/questions.json', function(data) {
            var template = $('#jsonquestions-template').html();
            var info = Mustache.to_html(template, data);
            $('#anchor').html(info);
        });
    });
    </script>

    </br></br>
    <div id="answers" style="display:none";>
        <input type="radio" name="answer" value="1" id="answer1" checked><label id="answerlabel1"></label></br>
        <input type="radio" name="answer" value="2" id="answer2"><label id="answerlabel2"></label></br>
        <input type="radio" name="answer" value="3" id="answer3"><label id="answerlabel3"></label></br>
        <input type="radio" name="answer" value="4" id="answer4"><label id="answerlabel4"></label></br>
        </br>
        <button id="giveanswer">Answer</button>
        </br></br>
        <label id="answerresult"></label>
        </br></br>
        <label id="score"></label>
    </div>

    <script src="js/jquery.min.js"></script> 
    <script src="js/mustache.min.js"></script>
    <script src="js/trivia.js"></script>
    <script src="js/search.js"></script>
    <script src="js/difficulty.js"></script>
    <script src="js/random.js"></script>
    <script src="js/quiz.js"></script>
    <script src="js/sort.js"></script>
</body>
</html>

Is there something I am missing? Thanks.

Upvotes: 2

Views: 1488

Answers (1)

Shanimal
Shanimal

Reputation: 11718

It looks like you're missing the "render" function call Mustache.render(template, data); (to_html has essentially been deprecated) I built a partial Plunker to show it working and it's embedded below. Im hosting the json at https://api.myjson.com/bins/2oxsm

// Code goes here

	$(function(){
        var data;
        $.getJSON("https://api.myjson.com/bins/2oxsm")
            .done(function(dat) {
                data = dat;
                console.log("success",dat)
                render();
            })
            .fail(function() {
                console.log( "error",arguments);
            })
            .always(function() {
                console.log( "complete" );
            });
            function render(){
                // mustache
                var tmpl = $('#questions-template').html();
                var html = Mustache.render(tmpl, data);
                $('#questions').find('tbody').html(html);
            }  
	});
    // lets make them clickable
    $(function(){
    
        var choices = [];
        $(document).on("click","td.choice",updateAnswers)
        
        function updateAnswers(e){
            
            var $t = $(this),
                $p = $t.parents('tr'),
                $answer = $p.find('.answer'),
                correct = $answer.data('value'),
                good = $t.data('value') === correct;

            $p.find('td')
                .toggleClass("checked",false)
                .toggleClass("correct",false);
            $t.addClass("checked");
            $answer.toggleClass("correct",good);
            $t.toggleClass("correct",good);
            $("#choices").html('');
            $('td.checked').each(show);
        }
        
        function show(i,v){
            // send this data to the backend?
            var $v = $(v),
                $p = $v.parents('tr'),
                div = $("<div/>").html($p.index()+1 + ":" + $v.html());
            $("#choices").append(div);
            div.toggleClass('correct',$v.is(".correct"))
        }
        
    })
    	
/* Styles go here */
* {
  font: 0.95em arial; }

#choices {
  color: white;
  background-color: #F00; }
  #choices div {
    padding: 1em; }
    #choices div.correct {
      background-color: green; }

table#questions {
  border-collapse: collapse; }
  table#questions thead {
    background: #000;
    color: #FFF;
    font-weight: bold; }
    table#questions thead th {
      white-space: nowrap;
      padding: 1em; }
  table#questions td {
    border: 1px solid black;
    padding: 0.5em;
    border-spacing: 1px; }
    table#questions td.choice {
      background-color: #666;
      color: white;
      cursor: pointer; }
      table#questions td.choice.checked {
        background-color: red;
        color: white; }
      table#questions td.choice.correct {
        background-color: green; }
    table#questions td.answer {
      background-color: pink; }
      table#questions td.answer.correct {
        background-color: lime; }
<script src="//cdnjs.cloudflare.com/ajax/libs/mustache.js/0.7.2/mustache.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

        <table id="questions">
        <thead>
            <tr>
                <th>ID</th>
                <th>Question</th>
                <th>Answer 1</th>
                <th>Answer 2</th>
                <th>Answer 3</th>
                <th>Answer 4</th>
                <th>Correct</th>
                <th>Difficulty</th>
            </tr>
            <tbody></tbody>
        </table>
        <div id="choices">
            
        </div>
        <script id="questions-template" type="text/template">  
            {{#jsonquestions}}
            <tr>
                <td>{{id}}</td>
                <td>{{q_text}}</td>
                <td class="choice" data-value="1">{{q_options_1}}</td>
                <td class="choice" data-value="2">{{q_options_2}}</td>
                <td class="choice" data-value="3">{{q_options_3}}</td>
                <td class="choice" data-value="4">{{q_options_4}}</td>
                <td class="answer" data-value="{{q_correct_option}}"></td>
                <td>{{q_difficulty_level}}</td>
            </tr>
            {{/jsonquestions}}
        </script>

(Also do you really want to repeat the table header for each question?)

$(function(){
    var data;
    $.getJSON("./data.json")
        .done(function(dat) {
            data = dat;
            render();
        })
        .fail(function() {
            console.error( "error",arguments);
        })
        .always(function() {
            console.info( "complete" );
        });
        function render(){
            // mustache
            var tmpl = $('#template').html();
            var html = Mustache.render(tmpl, data);
            $('#target').html(html);
        }  
});

Upvotes: 4

Related Questions