Skip to content

Instantly share code, notes, and snippets.

@ZacharyDinerstein
Created August 27, 2014 15:52
Show Gist options
  • Save ZacharyDinerstein/e4e28d1a5f50fb063510 to your computer and use it in GitHub Desktop.
Save ZacharyDinerstein/e4e28d1a5f50fb063510 to your computer and use it in GitHub Desktop.
Quiz App Code - Glamour Magazine
<div class="check-all-that-apply-quiz">
{{> _contributor}}
<p class="quiz-instructions">{{{data.main.body.text}}}</p>
<div class="selection-section">
{{#each data.main.quizData.selections}}
{{#if imageUrl}}
<div class="span2 selection-wrapper has-image">
<div class="selection-box" is_checked="false">
<img src="{{../imageUrl}}">
{{else}}
<div class="span6 selection-wrapper">
<div class="selection-box" is_checked="false">
{{/if}}
<span class="quiz-checkbox">
<span class="quiz-checkmark">✓</span>
</span>
{{#when description "===" ""}}
<div class="selection-text hidden-text">spacer</div>
{{/when}}
{{#when description "!==" ""}}
<div class="selection-text">{{{description}}}</div>
{{/when}}
</div>
</div>
{{/each}}
</div>
<div class="text-center span6">
<div class="show-result-btn btn btn-large">Show Results!</div>
</div>
{{#each data.main.quizData.results}}
<div class="row">
<div class="span6 quiz-result" num_selected_needed_to_reveal="{{numCorrect}}">
<h4 class="result-header">You selected <span class="num-selected"></span> out of <span class="total-possibilities"></span> possibilities.</h4>
<div class="row">
<p class="span3 result-text">{{{result}}}</p>
<div class="span3">
<img class="result-image" src="{{imageUrl}}">
</div>
</div>
</div>
</div>
{{/each}}
</div>
<div class="correct-answer-quiz">
{{> _contributor}}
{{#each data.main.quizData.questions}}
<div class="span6 question-wrapper" id="question_{{id}}">
<h3>{{id}}. {{{question}}}</h3>
<div class="question-image-wrapper">
<img src="{{imageUrl}}">
</div>
<div class="selection-section clearfix">
{{#each availableAnswers}}
{{#if imageUrl}}
<div class="span2 selection-wrapper has-image">
<div class="selection-box" selection_box_id="{{../../id}}_{{../id}}" question_num="{{../../id}}" correct_answer="{{../../correctAnswer}}">
<img src="{{../imageUrl}}">
{{else}}
<div class="selection-wrapper">
<div class="selection-box" selection_box_id="{{../../id}}_{{../id}}" question_num="{{../../id}}" correct_answer="{{../../correctAnswer}}">
{{/if}}
<span class="quiz-checkbox">
<span class="quiz-checkmark">✓</span>
</span>
{{#when value "===" ""}}
<!-- if a selection-box doesn't have text attached to it, the code below adds hidden text to the box. Without some text inside the selection-box, the box colapses. -->
<div class="selection-text hidden-text">spacer</div>
{{/when}}
{{#when value "!==" ""}}
<div class="selection-text">{{{value}}}</div>
{{/when}}
</div>
</div>
{{/each}}
</div>
<div class="answer-reveal">
<div class="answer-reveal-inner-wrapper">
<div class="reveal-header">
<span class="kiss-mark">✓</span>
<span class="cross-mark">X</span>
<span class="message-text"></span>
</div>
<div class="reveal-text">{{{correctAnswerText}}}</div>
</div>
</div>
</div>
{{/each}}
<div class="quiz-padding"></div>
{{#each data.main.quizData.results}}
<div class="row">
<div class="span6 quiz-result" num_correct_needed_to_reveal="{{numCorrect}}">
<h4 class="result-header">You got <span class="num-correct"></span> of <span class="total-questions"></span> right!</h4>
<div class="row">
<p class="span3 result-text">{{{result}}}</p>
<div class="span3">
<img class="result-image" src="{{imageUrl}}">
</div>
</div>
</div>
</div>
{{/each}}
</div>
@correct-answer-green: #88f078;
@wrong-answer-red: #EC9D9D;
@cross-mark-red: #E34D4D;
@answer-box-grey: #f2f2f2;
@highlight-yellow: #fff195;
@selected-blue: #bed5ed;
@subtext-grey: #999;
@quiz-border: #ddd;
@answer-reveal-background: #f9f9f9;
/* ====================================================================
=================== css related to all quizes ======================
==================================================================== */
/*=Desktop */
.quiz {
.quiz-title {
font-size: 26px;
margin: 60px 0px 11px 0px;
text-align: left;
line-height: 27px;
}
.quiz-description {
font-family: Haas roman;
font-style: italic;
font-size: 16px;
color: @subtext-grey;
margin-bottom: 16px;
}
.title-image-wrapper {
overflow: hidden;
max-height: 430px;
margin-bottom: 20px;
}
.contributor-wrapper {
margin-bottom: 5px;
img {
width: 67px;
margin: 0px 10px 10px 0px;
border-radius: 60px;
float: left;
}
.image-spacer {
width: 67px;
height: 67px;
margin-right: 10px;
float: left;
}
.contributor-type {
margin: 0px;
font-weight: 500;
}
.contributor-name {
margin-right: 10px;
font-family: Haas Bold;
}
iframe {
width: 62px;
height: 20px;
margin: 0px 10px -4px 0px;
}
a.btn-email {
position: absolute;
height: 18px;
z-index: 1;
}
.bio-blurb {
max-width: 416px;
margin-top: 5px;
font-family: Haas Italic;
font-style: italic;
color: @subtext-grey;
}
}
.quiz-instructions {
font-family: Haas roman;
font-size: 22px;
margin: 20px 0px;
}
.quiz-instructions-sub-text {
font-family: Haas roman;
font-size: 16px;
margin-bottom: 16px;
color: @subtext-grey;
}
.selection-section {
.selection-wrapper {
margin-left: 0px;
&.has-image {
margin: 0px 20px 0px 0px;
.selection-box {
padding: 6px;
img {
height: 157px;
padding-bottom: 4px;
}
.selection-text {
width: 83%;
}
.glamour-background {
height: 157px;
margin-bottom: 4px;
background-color: lightblue;
}
}
}
&:nth-child(3n+0){
margin-right: 0px;
}
}
.selection-box {
position: relative;
min-height: 20px;
margin: 10px 0px;
padding: 4px 0px 4px 7px;
background-color: @answer-box-grey;
border: 1px solid @quiz-border;
box-shadow: 1px 1px 0 #bfbfbf;
&:hover {
background-color: @highlight-yellow;
cursor: pointer;
}
&.disabled:hover {
background-color: @answer-box-grey;
cursor: default;
}
.quiz-checkbox {
display: inline-block;
position: relative;
float: left;
top: 1px;
margin: 0px 9px -2px 0px;
padding: 0px 0px 14px 14px;
background-color: #fff;
border: 1px solid @quiz-border;
box-shadow: 1px 1px 0 #bfbfbf;
.quiz-checkmark {
display: none;
position: absolute;
width: 41px;
height: 26px;
bottom: -2px;
right: -23px;
z-index: 1;
background: url("http://s3-ak.buzzfed.com/static/images/global/unified_sprite.png?v=201407141201") no-repeat -849px -12px;;
background-size: 879px 578px;
text-indent: -1000px; /*this sends the original html-generated checkmark far off screen. Since the original checkmark is placed between our span tag, it regesters as text. Therefore, we can remove just the original checkmark from view without effecting the rest of the element. */
}
}
.selection-text {
display: inline-block;
width: 92%;
word-wrap: break-word;
}
}
.lightblue-background {
background-color: @selected-blue;
&:hover {
background-color: @selected-blue !important;
}
}
}
.quiz-result {
display: none;
border-top: 1px solid @color-g-pink;
padding-top: 6px;
margin-top: 20px;
margin-bottom: 65px;
.result-header {
font-size: 21px;
line-height: 25px;
margin-bottom: 16px;
}
.result-text {
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
line-height: 25px;
}
}
.faded {
opacity: 0.6;
-moz-opacity: 0.6;
}
.quiz-padding {
margin-top: 70px;
}
.inline {
display: inline;
}
.hidden-text {
visibility: hidden;
}
.no-right-margin {
margin-right: 0px;
}
/* ====================================================================
=============== css related to correct-answer-quiz =================
==================================================================== */
.correct-answer-quiz {
.question-wrapper {
margin-bottom: 55px;
margin-left: 0px;
.question-image-wrapper {
max-height: 430px;
overflow: hidden;
img {
width: 100%;
margin-top: 12px;
}
}
.green-background {
background-color: @correct-answer-green;
.transition(background-color .1s);
.transition-delay(.25s);
&:hover {
background-color: @correct-answer-green !important;
}
}
.red-background {
background-color: @wrong-answer-red;
.transition(background-color .1s);
.transition-delay(.25s);
&:hover {
background-color: @wrong-answer-red !important;
}
}
}
.answer-reveal {
display: none;
padding: 15px 0px;
margin-top: 12px;
background-color: @answer-reveal-background;
border: 1px solid @quiz-border;
.answer-reveal-inner-wrapper {
margin: 0px 15px;
}
.reveal-header {
margin-bottom: 14px;
font-size: 25px;
.kiss-mark {
display: none;
position: relative;
float: left;
width: 50px;
height: 34px;
bottom: 8px;
right: 3px;
margin-right: 5px;
z-index: 1;
color: @correct-answer-green;
background: url("/aspen/img/lipstick-kiss-mark.png") no-repeat;
background-size: 47px 35px;
.rotate(-14deg);
text-indent: -1000px;
}
.cross-mark {
display: none;
z-index: 1;
color: @cross-mark-red;
}
}
}
}
/* ====================================================================
============ css related to check-all that apply quiz ==============
==================================================================== */
.check-all-that-apply-quiz {
.selection-section {
.row:last-child {
margin-bottom: 30px;
}
}
.show-result-btn {
margin: 35px auto 100px auto;
color: #ffffff;
background-color: #f00a71;
background-image: -moz-linear-gradient(top, #f00a71, #c464a9);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f00a71), to(#c464a9));
background-image: -webkit-linear-gradient(top, #f00a71, #c464a9);
background-image: -o-linear-gradient(top, #f00a71, #c464a9);
background-image: linear-gradient(to bottom, #f00a71, #C464A9);
background-repeat: repeat-x;
border-color: #f00a24 #f00a24 #a70719;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff00a71', endColorstr='#fff00a24', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
.buttonBackground(#f00a71, #c464a9);
}
}
/* ====================================================================
============ css related to which-one-are-you quiz ==============
==================================================================== */
.which-one-are-you-quiz {
.question-wrapper {
margin-bottom: 55px;
margin-left: 0px;
.question-image-wrapper {
max-height: 430px;
overflow: hidden;
img {
width: 100%;
margin-top: 12px;
}
}
.green-background {
background-color: @correct-answer-green;
.transition(background-color .1s);
.transition-delay(.25s);
&:hover {
background-color: @correct-answer-green !important;
}
}
.red-background {
background-color: @wrong-answer-red;
.transition(background-color .1s);
.transition-delay(.25s);
&:hover {
background-color: @wrong-answer-red !important;
}
}
}
.answer-reveal {
display: none;
padding: 15px 0px;
margin-top: 12px;
background-color: @answer-reveal-background;
border: 1px solid @quiz-border;
.answer-reveal-inner-wrapper {
margin: 0px 15px;
}
.reveal-header {
margin-bottom: 14px;
font-size: 25px;
.kiss-mark {
display: none;
position: relative;
float: left;
width: 50px;
height: 34px;
bottom: 8px;
right: 3px;
margin-right: 5px;
z-index: 1;
color: @correct-answer-green;
background: url("/aspen/img/lipstick-kiss-mark.png") no-repeat;
background-size: 47px 35px;
.rotate(-14deg);
text-indent: -1000px;
}
.cross-mark {
display: none;
z-index: 1;
color: @cross-mark-red;
}
}
}
}
}
/*=Mobile First */
@media (max-width: 641px) {
.quiz {
.question-wrapper {
.question-image-wrapper {
margin-bottom: 6px;
}
}
.selection-section {
.selection-wrapper {
&.has-image {
float: left;
width: 33%;
margin-right: 2px;
.selection-box {
margin: 2px 0px;
img {
float: left;
height: 100%;
width: 100%;
}
}
}
&:nth-child(3n+0){
margin-right: -1px;
}
.selection-text {
display: inline;
}
}
}
}
}
/*=Mobile Landscape*/
@media (min-width: 641px) and (max-width: 767px) {
.quiz {
.question-wrapper {
.question-image-wrapper {
margin-bottom: 6px;
}
}
.selection-section {
.selection-wrapper {
&.has-image {
float: left;
width: 30%;
margin-right: 2.45%;
.selection-box {
margin: 2px 0px;
img {
float: left;
height: 100%;
width: 100%;
}
}
}
&:nth-child(3n+2){
margin-left: 2.45%;
}
&:nth-child(3n+0){
margin-left: 2.45%;
margin-right: -1px;
}
.selection-text {
display: inline;
}
}
}
}
}
/*=Tablet*/
@media (min-width:768px) and (max-width: 1024px) {
.quiz {
float: none;
margin: 0px auto;
.row {
.span6 {
margin-left: 0px;
}
}
.title-image-wrapper {
img {
margin-left: 0px;
}
}
.quiz-result {
.result-text {
margin-left: 0px;
}
}
}
}
/*Desktop*/
@media (min-width:1025px) {
.quiz {
margin-left: 113px;
}
}
<div class="which-one-are-you-quiz">
{{> _contributor}}
{{#each data.main.quizData.questions}}
<div class="span6 question-wrapper" id="question_{{id}}">
<h3>{{id}}. {{{question}}}</h3>
<div class="question-image-wrapper">
<img src="{{imageUrl}}">
</div>
<div class="selection-section clearfix">
{{#each availableAnswers}}
<div class="span2 selection-wrapper has-image">
<div class="selection-box" selection_box_id="{{../id}}_{{id}}" question_num="{{../id}}" is_checked="false" personality_id="{{id}}">
{{#if imageUrl}}
<img src="{{../imageUrl}}">
{{else}}
<img src="/aspen/img/pink.png">
{{/if}}
<span class="quiz-checkbox">
<span class="quiz-checkmark">✓</span>
</span>
{{#when value "===" ""}}
<div class="selection-text hidden-text">spacer</div>
{{/when}}
{{#when value "!==" ""}}
<div class="selection-text">{{{value}}}</div>
{{/when}}
</div>
</div>
{{/each}}
</div>
</div>
{{/each}}
{{#each data.main.quizData.results}}
<div class="row">
<div class="span6 quiz-result" personality_type="{{id}}">
<h4 class="result-header">What 90s Rockstar Are You?</h4>
<div class="row">
<p class="span3 result-text">{{{result}}}</p>
<div class="span3">
<img class="result-image" src="{{imageUrl}}">
</div>
</div>
</div>
</div>
{{/each}}
</div>
<div id="main-content" class="container glamour-shadow">
<!-- Convert this to the new add call -->
{{!-- Top Mobile DFP --}}
<div class="ad-container">
<div id="topmobile320x50_frame"></div>
<script type="text/javascript">
require(['adsConfig'], function (adsConfig) {
adsConfig.set('mobiledart', {'topmobile': {sz:'320x50', kws:["top"]}});
});
</script>
</div>
<div class="style-container">
<div class="row glm">
<div class="span4 glamour-sidebar">
{{> _sidebar}}
</div>
<div class="offset1 span6 container quiz">
<div class="row">
<div class="span6">
<h2 class="quiz-title">{{{data.meta.heds.display}}}</h2>
<p class="quiz-description">{{{data.meta.description}}}</p>
<div class="row">
<div class="title-image-wrapper">
<img class="span6 title-image" src="{{data.meta.searchImage}}">
</div>
</div>
{{#when data.meta.pageType "===" "correct_answer"}}
{{> _correct_answer_quiz}}
{{/when}}
{{#when data.meta.pageType "===" "check_all_that_apply"}}
{{> _check_all_that_apply_quiz}}
{{/when}}
{{#when data.meta.pageType "===" "which_one_are_you"}}
{{> _which_one_are_you_quiz}}
{{/when}}
</div>
</div>
</div>
</div>
</div>
</div>
{{!-- CM Left FlyIn --}}
<div class="flyIn hidden-tablet hidden-phone">
<span class="close-btn">
<img src="/aspen/img/x-btn.png">
</span>
{{#addCMPlacement "AMS_GLM_GLOBAL_FLYIN"}}
{{> _cmPlacement}}
{{/addCMPlacement}}
</div>
/* global define */
define(function (require) {
'use strict';
function quiz() {
require(['jquery'], function ($) {
// ========== JavaScript code for correct-answer-quiz ==========
var questionsAnswered = 0;
var correctAnswers = 0;
var numOfQuestions = $('div.question-wrapper').length;
$('.correct-answer-quiz .selection-box').on('click', function () {
var questionDivID = $(this)
.parents('.question-wrapper')
.attr('id');
var selectionBoxID = $(this)
.attr("selection_box_id");
var questionNumber = $(this)
.attr("question_num");
var correctAnswerNumber = $(this)
.attr("correct_answer");
questionsAnswered++;
// causes all selection boxes related to the current question to become unclickable. This way, a user can't select more than one answer.
$('#' + questionDivID + ' .selection-box')
.unbind();
// removes hover-over functionality from all selection boxes that relate to the current question.
$('#' + questionDivID + ' .selection-box')
.addClass("disabled");
// displays checkmark inside of selection box that's just been clicked.
$(this).find('.quiz-checkmark').show();
if (selectionBoxID === (questionNumber + '_' + correctAnswerNumber)) {
correctAnswers++;
$(this).addClass("green-background"); // adds a green background to the correct selectionBox.
$('#' + questionDivID + ' .kiss-mark').show();
$('#' + questionDivID + ' .message-text').text("Yes!");
} else {
$(this).addClass("red-background"); // adds a red background to the incorrect answer the user just chose.
$('.selection-box[selection_box_id=\'' + questionNumber + '_' + correctAnswerNumber + '\']')
.addClass("green-background");
$('#' + questionDivID + ' .cross-mark').show();
$('#' + questionDivID + ' .message-text').text("Nope!");
}
$('#' + questionDivID + ' .answer-reveal').show();
// selects all selection-boxes that are not the correct answer, and gives their contents a faded look.
$('#' + questionDivID + ' .selection-box')
.not('.green-background')
.addClass("faded");
// if all questions have been answered, display results section.
if (questionsAnswered === numOfQuestions) {
$('.quiz-padding').hide();
$('.num-correct').text(correctAnswers);
$('.total-questions').text(numOfQuestions);
// reach into frontend, and grab the amount of correct answers needed to reveal each quiz result. Store those numbers in an array.
var numsNeededToReveal = $('.quiz-result').map(function () {
return $(this).attr("num_correct_needed_to_reveal");
}).get();
// sort array from highest number to lowest number
numsNeededToReveal.sort(function (a, b) {
return b - a;
});
// step through the array. If a user's number of correct answers is larger or equal to the array's current value, grab that value, use it to select the results div that has that value as an attribute, and fade in that div.
for (var i = 0; i < numsNeededToReveal.length; i++) {
var numNeededToReveal = numsNeededToReveal[i];
if (correctAnswers >= numNeededToReveal) {
$(".quiz-result[num_correct_needed_to_reveal=\'" + numNeededToReveal + "\']").fadeIn('slow');
break;
}
}
}
});
// ========== JavaScript code for check-all-that-apply-quiz & which-one-are-you-quiz ==========
$('.check-all-that-apply-quiz .selection-box, .which-one-are-you-quiz .selection-box').on('click', function () {
// if the box a user clicks on was already selected...
if ($(this).attr('is_checked') === 'true') {
// ...remove its checkmark,...
$(this).find('.quiz-checkmark').hide();
// ... change its 'isChecked' status to 'false', and remove its lightblue background.
$(this).attr('is_checked', 'false').removeClass("lightblue-background");
} else {
// display checkmark inside of selection-box that's just been clicked.
$(this).find('.quiz-checkmark').show();
//... change its 'isChecked' status to 'true', and give the selection box a lightblue background.
$(this).attr('is_checked', 'true').addClass("lightblue-background");
}
});
$('.show-result-btn').on('click', function () {
var boxesSelected = $(".selection-box[is_checked='true'").length;
var numOfSelectionBoxes = $('div.selection-wrapper').length;
$('.num-selected').text(boxesSelected);
$('.total-possibilities').text(numOfSelectionBoxes);
// causes all selection boxes to become unclickable. This way, a user can't select change their selections after they submit the quiz. Also removes hover-over functionality from all selection boxes, and gives them a faded look.
$('.selection-box').unbind().addClass("disabled faded");
// hides 'show results' button.
$(this).hide();
// reach into frontend, and grab the amount of selected boxes needed to reveal each quiz result. Store those numbers in an array.
var numsNeededToReveal = $('.quiz-result').map(function () {
return $(this).attr("num_selected_needed_to_reveal");
}).get();
// sort array from highest number to lowest number
numsNeededToReveal.sort(function (a, b) {
return b - a;
});
// step through the array. If a user's number of selected boxes is larger or equal to the array's current value, grab that value, use it to select the results div that has that value as an attribute, and reveal that div.
for (var i = 0; i < numsNeededToReveal.length; i++) {
var numNeededToReveal = numsNeededToReveal[i];
if (boxesSelected >= numNeededToReveal) {
$(".quiz-result[num_selected_needed_to_reveal=\'" + numNeededToReveal + "\']").fadeIn('slow');
break;
}
}
});
// ========== JavaScript code for which-one-are-you-quiz ==========
$('.which-one-are-you-quiz .selection-box').on('click', function () {
var questionDivID = $(this)
.parents('.question-wrapper')
.attr('id');
var selectionBoxID = $(this)
.attr("selection_box_id");
var questionNumber = $(this)
.attr("question_num");
questionsAnswered++;
// causes all selection boxes related to the current question to become unclickable. This way, a user can't select more than one answer. Also removes hover-over functionality from all selection boxes belonging to the current question. Finally, gives every box that wasn't selected a faded look.
$('#' + questionDivID + ' .selection-box')
.unbind()
.addClass("disabled")
.filter('[is_checked="false"]')
.addClass("faded");
// if all questions have been answered, display results section.
if (questionsAnswered === numOfQuestions) {
var numOfPersonalities = $('.quiz-result').length;
var resultsArray = [];
// creates an array containing as many indexes as there are possible personality results. Each index in resultsArray is like a container for the selection a user makes that will reveal a personality. For example, resultsArray[0] will be the container for every answer a user gives that increases the likelyhood that a user will see the results section that has id '0'. resultsArray[1] is a container for answers that will lead to a user seeing the result section with and id of '1', and so on.
for (var i = 0; i < numOfPersonalities; i++) {
resultsArray.push(0);
}
// creates an array of the all the personalityIDs that gained a point during the quiz
var selectedPersonalities = $('.selection-box[is_checked="true"]').map(function () {
return $(this).attr("personality_id");
}).get();
// loops through the selectedPersonalities array. For every personality selected, increment the corresponding index in resultsArray by 1.
for (var j = 0; j < selectedPersonalities.length; j++) {
var selectedPersonality = selectedPersonalities[j] - 1; // adjusts selectedPersonality so its numerical value will increment the correct index in resultsArray
resultsArray[selectedPersonality] += 1;
}
// find the highest value in resultsArray, and use the index of that value to reveal the correct quiz result to the user.
var result = resultsArray.indexOf(Math.max.apply(Math, resultsArray)) + 1; // adjusts numerical value so that we grab the correct quiz result.
$(".quiz-result[personality_type=\'" + result + "\']").show();
}
});
});
}
return quiz();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment