Last active
August 29, 2015 14:09
-
-
Save chrisege/9debb9dfe8ae6c8bfb1b to your computer and use it in GitHub Desktop.
Sports Quiz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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