Skip to content

Instantly share code, notes, and snippets.

@chrisege
Last active August 29, 2015 14:09
Show Gist options
  • Save chrisege/9debb9dfe8ae6c8bfb1b to your computer and use it in GitHub Desktop.
Save chrisege/9debb9dfe8ae6c8bfb1b to your computer and use it in GitHub Desktop.
Sports Quiz
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' type='text/css' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css'></link>
</head>
<body class="container">
<script type="text/template" id="quizTemplate">
<h1 class="title">
<%= title %>
</h1>
<h2 class="subtitle">
<%= subtitle %>
</h2>
<div class="well" id="questionBox">
<div class="row">
<div class="col-sm-10">
<!--<button class="intro startQuiz btn btn-primary">Start the quiz!</button>-->
</div>
<div class="scores col-sm-2">
<h4>Score: <span id="score"><%= score %></span> / <span id="possibleScore"><%= possibleScore %></span></h4>
</div>
</div>
<div class="question row">
</div>
</div>
</script>
<script type="text/template" id="questionTemplate">
<h3 class="title">
<%= title %>
</h3>
<div class="row">
<div class="col-sm-4 firstColumn">
<ul>
<% _.each( firstColumn, function( item ){ %>
<li><%= item %></li>
<% }); %>
</ul>
</div>
<div class="col-sm-4">
<div class="secondColumn"></div>
<div class="buttons">
<button class="checkResults btn btn-primary">Check Results</button>
<button class="nextQuestion btn btn-primary" style="display:none;">Next Question</button>
</div>
</div>
</div>
</script>
<script type="text/template" id="multiQuestionTemplate">
<h3 class="title">
<%= title %>
</h3>
<div class="col-sm-4">
<%= question %>
<div class="questionCtn">
<% _.each( options, function( option ){ %>
<div class="radio">
<label>
<input type="radio" name="options" value="<%= option %>">
<%= option %>
</label>
</div>
<% }); %>
</div>
<div class="answerCtn" style="display:none;">
<h3 class="status"></h3>
<p><%= explanation %></p>
</div>
<div class="buttons">
<button class="checkResults btn btn-primary">Check Answer</button>
<button class="nextQuestion btn btn-primary" style="display:none;">Next Question</button>
</div>
</div>
<div class="col-sm-4">
<div class="imgCtn"><img src="<%= image %>" alt="<%= image_alt %>" /></div>
</div>
</script>
<script type="text/template" id="answerTemplate">
<% _.each( shuffledItems, function( item ){ %>
<li><%= item %></li>
<% }); %>
</script>
<script type="text/template" id="finalScoreTemplate">
<h3>Your final score is:</h3>
<h1><span id="score"><%= score %></span> / <span id="possibleScore"><%= possibleScore %></span></h1>
<h2><%= quote %></h2>
<p><a href="<%= fb_link %>">Share on Facebook</a></p>
</script>
<div class="row">
<div id="quiz" class="col-sm-12">
</div>
<div id="question" class="col-sm-12">
</div>
</div>
<script src='https://code.jquery.com/jquery-1.11.1.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src="quiz.js"></script>
<script>
window.fbAsyncInit = function() {
FB.init({
appId : '120005534692936',
xfbml : true,
version : 'v2.1'
});
};
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
</body>
</html>
var quizApp = quizApp || {};
quizApp.Quiz = Backbone.Model.extend({
defaults: {
title: '',
subtitle: '',
questions: [],
score: 0,
possibleScore: 0,
currentQuestion: 0
},
incrementScores: function(score){
this.set('score', (this.get('score') + score ));
this.trigger('change');
},
prepFinalScore: function(){
var resultsRange = this.get('resultsRange'),
score = this.get('score'),
result;
_.each( _.keys(resultsRange).map(function(key){return +key}), function(key){
if (score <= key) {
result = key;
return false;
}
});
this.set('quote', resultsRange[result]);
this.setFbLink();
return this;
},
setFbLink: function(){
//https://www.facebook.com/dialog/feed?app_id=692446294161510&display=popup&link=http://www.clickhole.com/quiz/how-many-these-thoughts-have-you-had-1357&name=I got: You’re A Junior Thinker - How Many Of These Thoughts Have You Had?&description=Think you’ve thought all the thoughts? Take this quiz and find out.&image=http://chimg.onionstatic.com/5346/original/600.jpg&redirect_uri=http://www.clickhole.com/shared?s=fb-shared
var quote = this.get('quote'),
title = this.get('subtitle'),
name = "I got "+ quote + " " +title,
link;
link = 'https://www.facebook.com/dialog/feed?app_id=120005534692936&display=popup'+
'&link='+ 'http://interactive.wttw.com/where-in-chicago=' + //document.URL+
'&name='+name+
'&description='+'How well do you know Chicago? Take Geoffrey Baer\'s Where in Chicago quiz and find out!'+
'&redirect_uri='+ 'http://interactive.wttw.com/where-in-chicago/' //document.URL
this.set('fb_link', link);
}
});
quizApp.Question = Backbone.Model.extend({
defaults: {
title: "",
possibleScore: 1
}
});
quizApp.multiQuestion = Backbone.Model.extend({
defaults: {
title: "",
}
});
quizApp.Answer = Backbone.Model.extend({
defaults: {
items: [],
},
initialize: function(){
this.shuffle();
},
shuffle: function(){
this.set('shuffledItems', _.shuffle(this.get('items')));
},
score: function(){
return this.compareArrays(this.get('items'), this.get('shuffledItems'));
},
compareArrays: function(arr1, arr2){
var compared = _.map(arr1, function(value, key){
return arr2[key] == value;
});
var score = _.reduce(compared, function(memo,val){
return val == true ? memo + 1 : memo;
},0);
return {
score: score,
key: compared,
items: this.get('items')
}
},
});
quizApp.QuizView = Backbone.View.extend({
tagName: 'div',
template: $("#quizTemplate").html(),
questionIndex: 0,
questionCount: 0,
events: {
'click .startQuiz': 'startQuiz',
'click .shareFb': 'shareFb'
},
initialize: function(){
// create a question collection.
// get the questions array, and loop through it
// assign the question's array index as its id
// and add it to the collection
this.questions = new quizApp.QuestionCollection();
_.each(this.model.get('questions'), function(question, index){
question.id = index;
this.questions.add(question);
this.questionCount += 1;
}.bind(this));
this.model.set('possibleScore', this.questions.getPossibleScore());
},
render: function(){
var tmpl = _.template(this.template);
this.$el.append(tmpl(this.model.toJSON()));
this.startQuiz();
return this;
},
renderQuestion: function(){
var question = this.questions.get(this.questionIndex);
switch (question.get('type')) {
case 'match':
this.currentQuestion = new quizApp.QuestionView({
model: question,
el: this.$el.find('.question'),
});
break;
case 'multi':
this.currentQuestion = new quizApp.MultiQuestionView({
model: question,
el: this.$el.find('.question'),
});
break;
}
this.currentQuestion.model.set('parentView', this);
this.currentQuestion.model.set('parentModel', this.model);
this.currentQuestion.render();
this.listenTo(this.currentQuestion.model, 'change', this.updateScore);
this.listenTo(this.currentQuestion, 'nextQuestion', this.nextQuestion);
},
renderFinalScore: function(){
this.$el.find('.scores').remove();
this.model.prepFinalScore();
var tmpl = _.template($('#finalScoreTemplate').html());
this.$el.find('.question').html(tmpl(this.model.toJSON()));
},
startQuiz: function(){
this.$el.find('.intro').fadeOut();
this.renderQuestion();
},
updateScore: function(){
this.model.incrementScores(
this.currentQuestion.model.get('score')
);
this.$el.find('#score').html(this.model.get('score'));
this.$el.find('#possibleScore').html(this.model.get('possibleScore'));
},
nextQuestion: function(){
this.questionIndex += 1;
this.currentQuestion.close();
if (this.questionIndex >= this.questionCount) {
this.renderFinalScore();
} else {
this.renderQuestion();
}
}
});
quizApp.QuestionView = Backbone.View.extend({
tagName: 'div',
template: $("#questionTemplate").html(),
initialize: function(){
this.answerModel = new quizApp.Answer({'items': this.model.get('secondColumn')});
this.answerView = new quizApp.AnswerView({model: this.answerModel});
},
events: {
'sortupdate':'updateAnswer',
'click .checkResults': 'checkResults',
'click .nextQuestion': 'nextQuestion'
},
render: function(){
var parent = this;
var tmpl = _.template(this.template);
this.answerView.render();
this.$el.append(tmpl(this.model.toJSON()));
this.$('.secondColumn').append(this.answerView.el);
this.$('.secondColumn ul').sortable();
return this;
},
// method to be run when jQueryUI fires a sortupdate event.
// sets answerModel's shuffledItems array to whatever order
// the user has put them in.
updateAnswer: function(){
var newOrder = [];
this.$el.find('.secondColumn li').each(function(){
newOrder.push($(this).html());
});
this.answerModel.set('shuffledItems', newOrder);
},
checkResults: function(){
//run the answerModel.score() method and store value locally
var score = this.answerModel.score();
// set this.model score and possibleScore values
this.model.set({
score: score.score,
possibleScore: score.key.length
});
// mark the matching responses as true or false,
// if false, add the correct answer here
// TODO: make "correct answer" show left column value instead?
this.$el.find('.secondColumn li').each(function(index, element){
var thisScore = score.key[index].toString();
$(element).removeClass().addClass(thisScore);
if (thisScore === 'false') { $(element).append(' ('+score.items[index]+')'); }
});
// hide the check results button, show the next question button
this.$el.find('.buttons button').each(function(){
$(this).toggle();
});
},
nextQuestion: function(){
this.trigger('nextQuestion');
},
//use instead of remove() because it empties $el instead of removing it.
close: function(){
this.unbind();
this.undelegateEvents();
this.stopListening();
this.$el.empty();
},
});
quizApp.MultiQuestionView = Backbone.View.extend({
tagName: 'div',
template: $("#multiQuestionTemplate").html(),
initialize: function(){
},
events: {
'click .checkResults': 'checkResults',
'click .nextQuestion': 'nextQuestion'
},
render: function(){
var tmpl = _.template(this.template);
this.$el.append(tmpl(this.model.toJSON()));
return this;
},
checkResults: function(){
var selected = this.$el.find('input:radio:checked').val();
var score = (selected === this.model.get('answer') ? 1 : 0);
this.model.set({
score: score,
possibleScore: 1
});
this.$el.find('.questionCtn').remove();
this.$el.find('.status').html(score === 1 ? 'Correct!' : 'Incorrect!');
this.$el.find('.answerCtn').fadeIn();
this.$el.find('.buttons button').each(function(){
$(this).toggle();
});
},
nextQuestion: function(){
this.trigger('nextQuestion');
},
//use instead of remove() because it empties $el instead of removing it.
close: function(){
this.unbind();
this.undelegateEvents();
this.stopListening();
this.$el.empty();
},
});
quizApp.AnswerView = Backbone.View.extend({
tagName: 'ul',
template: $("#answerTemplate").html(),
render: function(){
var tmpl = _.template(this.template);
this.$el.append(tmpl(this.model.toJSON()));
return this;
}
});
quizApp.QuestionCollection = Backbone.Collection.extend({
model: quizApp.Question,
getPossibleScore: function(){
var possibleScore = 0;
this.each(function(model){
possibleScore += model.get('possibleScore');
});
return possibleScore;
}
});
var fullQuizMulti = {
'title': 'Test Your Knowledge',
'subtitle': 'Where in Chicago Sports Quiz',
'hideIntro': true,
'resultsRange': {
"0": "Terrible! (zero)",
"3": "Not great. (1-3)",
"5": "Acceptable. (4-5)",
"8": "Pretty good! (6-8)",
"10": "Excellent! (9-10)"
},
'questions': [
{
'type': 'multi',
'question': 'Bulls superstar Derrick Rose attended which local Chicago high school?',
'image': 'http://lorempixel.com/640/360/?1',
'image_alt': '',
'options': [
'Simeon Career Academy',
'Whitney Young Magnate High School',
'St. Ignatius College Prep',
'Martin Luther King Jr. High School'
],
'answer': 'Simeon Career Academy',
'explanation': ''
},
{
'type': 'multi',
'question': 'Yannick Noah, the father of Chicago Bulls All-Star Joakim Noah, was a decorated professional athlete in what sport? ',
'image': 'http://lorempixel.com/640/360/?2',
'image_alt': '',
'options': [
'Golf',
'Bowling',
'Tennis',
'Volleyball'
],
'answer': 'Tennis',
'explanation': ''
},
{
'type': 'multi',
'question': 'Which member of the 2005 champion Chicago White Sox was named World Series MVP?',
'image': 'http://lorempixel.com/640/360/?3',
'image_alt': '',
'options': [
'Paul Konerko',
'A.J. Pierzynski',
'Jermaine Dye',
'Mark Buehrle '
],
'answer': 'Jermaine Dye',
'explanation': ''
},
{
'type': 'multi',
'question': 'Who is the Chicago White Sox career leader in base hits?',
'image': 'http://lorempixel.com/640/360/?4',
'image_alt': '',
'options': [
'Luke Appling',
'Frank Thomas',
'Harold Baines',
'Minnie Minoso'
],
'answer': 'Luke Appling',
'explanation': ''
},
{
'type': 'multi',
'question': 'In 2009, the Chicago Cubs retired the uniform #31 in honor of two Hall of Fame players, Greg Maddux, and who else?',
'image': 'http://lorempixel.com/640/360/?5',
'image_alt': '',
'options': [
'Billy Williams',
'Ernie Banks',
'Ron Santo',
'Ferguson Jenkins'
],
'answer': 'Ferguson Jenkins',
'explanation': ''
},
{
'type': 'multi',
'question': 'In 1998, Chicago Cubs rookie pitcher Kerry Wood threw a MLB record tying 20 strikeouts against what team?',
'image': 'http://lorempixel.com/640/360/?6',
'image_alt': '',
'options': [
'San Diego Padres',
'Houston Astros',
'St. Louis Cardinals',
'New York Mets'
],
'answer': 'Houston Astros',
'explanation': ''
},
{
'type': 'multi',
'question': 'In the first round of the 2000 NFL Draft, the Chicago Bears selected Brian Urlacher from what college? ',
'image': 'http://lorempixel.com/640/360/?7',
'image_alt': '',
'options': [
'The University of Iowa',
'The University of New Mexico',
'Texas A&M University',
'Arizona State University'
],
'answer': 'The University of New Mexico',
'explanation': ''
},
{
'type': 'multi',
'question': 'In 2013, Chicago Bears quarterback Jay Cutler became the franchise’s all-time leader in passing yards, surpassing who?',
'image': 'http://lorempixel.com/640/360/?8',
'image_alt': '',
'options': [
'Jim McMahon',
'Jim Harbaugh',
'Billy Wade',
'Sid Luckman'
],
'answer': 'Sid Luckman',
'explanation': ''
},
{
'type': 'multi',
'question': 'In 2013, the Chicago Blackhawks won their second Stanley Cup in three years by defeating what team?',
'image': 'http://lorempixel.com/640/360/?9',
'image_alt': '',
'options': [
'New York Rangers',
'New Jersey Devils',
'Boston Bruins',
'Toronto Maple Leafs'
],
'answer': 'Boston Bruins',
'explanation': ''
},
{
'type': 'multi',
'question': 'Chicago Blackhawks winger Patrick Kane is a native of what North American city?',
'image': 'http://lorempixel.com/640/360/?10',
'image_alt': '',
'options': [
'Buffalo, New York',
'Detroit, Michigan',
'Montreal, Quebec',
'Calgary, Alberta'
],
'answer': 'Buffalo, New York',
'explanation': ''
},
]
}
var quiz = new quizApp.Quiz(fullQuizMulti);
var quizView = new quizApp.QuizView({model: quiz, el:$('#quiz')});
quizView.render();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment