Last active
August 29, 2015 14:09
-
-
Save chrisege/27f800bbb12aae6766bc to your computer and use it in GitHub Desktop.
Wildcard 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 Wildcard 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': 'What did Elisha Gray of Highland Park invent?', | |
'image': 'http://lorempixel.com/640/360/?1', | |
'image_alt': '', | |
'options': [ | |
'Lincoln Logs', | |
'The telephone', | |
'The zipper', | |
'The electric eye' | |
], | |
'answer': 'The telephone', | |
'explanation': 'The telephone. Unfortunately he invented it at exactly the same time as Alexander Graham Bell. Their applications arrived at the patent office on the same day, and you know whose envelope was opened first. But don’t feel too sorry for him. He went on to co-found Western Electric Company.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'The world’s first Weber Grill was made by modifying what?', | |
'image': 'http://lorempixel.com/640/360/?2', | |
'image_alt': '', | |
'options': [ | |
'A spherical metal buoy', | |
'A garden planter', | |
'The spare tire cover on a 1957 Chrysler ', | |
'A primitive satellite dish' | |
], | |
'answer': 'A spherical metal buoy', | |
'explanation': 'Mount Prospect metalworker and frustrated backyard griller George Stephens had a job welding buoys together at Weber Brothers Metal Works in Chicago, and realized this shape might be the key to more successful grilling. It was such a hit that by the late 1950s, Stephens had bought out his former employer and the company was making nothing but barbecue grills.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'The Chicago Water Tower is made from Joliet limestone, which is famous for its yellowish cast. What gives it that color?', | |
'image': 'http://lorempixel.com/640/360/?3', | |
'image_alt': '', | |
'options': [ | |
'It’s full of fossils from yellowish sea creatures.', | |
'It contains iron, which rusts.', | |
'It was dyed yellow to give it a distinctive look.', | |
'It contains the yellow gemstone Citrine.' | |
], | |
'answer': 'It contains iron, which rusts.', | |
'explanation': '' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'Where did the Viking ship in Geneva, Illinois come from?', | |
'image': 'http://lorempixel.com/640/360/?4', | |
'image_alt': '', | |
'options': [ | |
'An archeological dig in Norway', | |
'The Chicago World’s Fair of 1893', | |
'A movie about Vikings shot partly on Lake Michigan', | |
'A defunct amusement park in nearby St. Charles' | |
], | |
'answer': 'The Chicago World’s Fair of 1893', | |
'explanation': 'The World’s Fair. This ship was sailed to Chicago from Norway in 1893. It’s the type of ship they many believe explorer Leif Eriksson sailed to America some 500 years before Christopher Columbus’s voyage. The Scandinavian boat builders were snubbing their noses at Chicago’s World’s Columbian Exposition commemorating the 400th anniversary of Columbus’s “discovery” of the New World.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'The sleek Burlington Zephyr train set a record in 1934 traveling dawn to dusk from Denver, arriving at the World’s Fair on Chicago’s Lakefront in 13 hours and 5 minutes, half the time of a typical steam train. What was the TOTAL cost of fuel for that 1,015 mile trip?', | |
'image': 'http://lorempixel.com/640/360/?5', | |
'image_alt': '', | |
'options': [ | |
'$14.64', | |
'$955.37', | |
'$8,644.15', | |
'$15,550.21' | |
], | |
'answer': '$14.64', | |
'explanation': 'The average speed was 77 MPH; peak speed was 112 MPH.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'What Chicago airport is referenced on Lithuanian money?', | |
'image': 'http://lorempixel.com/640/360/?6', | |
'image_alt': '', | |
'options': [ | |
'O’Hare', | |
'Midway', | |
'Meigs Field', | |
'Palwaukee Airport' | |
], | |
'answer': 'Palwaukee Airport', | |
'explanation': 'Palwaukee Airport (now called Chicago Executive Airport) in Wheeling. Two Lithuanian-born Chicago aviators Steponas Darius and Stasys Girenus are pictured on the 10 Lita bank note. They died trying to fly non-stop across the Atlantic to Lithuania in 1933. On Darius’s hat, you can see the insignia of Palwaukee Airport, where he worked in the U.S.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'Where will you find the grave of Andreas Von Zirngibl, one of Chicago’s first settlers?', | |
'image': 'http://lorempixel.com/640/360/?7', | |
'image_alt': '', | |
'options': [ | |
'In City Hall', | |
'On Blue Island', | |
'In Graceland Cemetery ', | |
'A scrap yard on the south side' | |
], | |
'answer': 'A scrap yard on the south side', | |
'explanation': 'As the once-remote are along the Calumet River at 92nd Street industrialized, the old settler’s grave from 1855 ended up in a scrap yard!' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'There’s a statue of Abraham Lincoln in Grant Park. Where’s the statue of President Grant in Chicago?', | |
'image': 'http://lorempixel.com/640/360/?8', | |
'image_alt': '', | |
'options': [ | |
'Lincoln Park', | |
'Grant Park', | |
'Corner of Lincoln Avenue and Grant Street', | |
'There is no statue of U.S. Grant in Chicago' | |
], | |
'answer': 'Lincoln Park', | |
'explanation': 'Lincoln Park just south of the Chicago Public Zoo. (There is no Grant Street in Chicago).' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'Ford City Mall near Midway Airport was built as what?', | |
'image': 'http://lorempixel.com/640/360/?9', | |
'image_alt': '', | |
'options': [ | |
'The world’s largest car dealership', | |
'A business college founded by Henry Ford', | |
'America’s first indoor shopping mall', | |
'A WWII bomber engine factory' | |
], | |
'answer': 'A WWII bomber engine factory', | |
'explanation': 'It was the Dodge Chicago engine plant and it was huge – 6 million square feet. Engines for B-29 bombers started rolling off the line in 1944. In all, more than 18,000 engines were made there for 3,600 planes.' | |
}, | |
{ | |
'type': 'multi', | |
'question': 'How did the Elgin Watch Company precisely calibrate its famous timepieces?', | |
'image': 'http://lorempixel.com/640/360/?10', | |
'image_alt': '', | |
'options': [ | |
'Through celestial observations at a specially built observatory in Elgin', | |
'With telegraph signals from a secure clock in the White House', | |
'The watches were timed to music piped through the factory.', | |
'Their master calibrator Johannes Stumpf was born with an ability to keep perfect time.' | |
], | |
'answer': 'Through celestial observations at a specially built observatory in Elgin', | |
'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