123

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

            
              <html>
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Munich Members Quiz</title>
</head>

<body class="container">
  <section ng-app="ngQuiz" ng-controller="ngQuizController" class="quiz">
    <image-preload></image-preload>
    <div class="progress" ng-if="quizProgress.inProgress && quizProgress.currentQuestion <= quizProgress.lastQuestion">
      <span ng-cloak class="counter">Frage {{quizProgress.currentQuestionFriendly}} von {{quizProgress.lastQuestion}}</span>
      <div class="progress-bar" progress-bar></div>
    </div>
    <div class="content">
      <!-- intro -->
      <section ng-cloak class="intro fade-in" ng-if="!quizProgress.loading && !quizProgress.inProgress && !quizProgress.finished">
        <div ng-cloak class="row">
          <div class="col-xs-6">
            <h1>{{::quizMetadata.title}}</h1>
            <p>{{::quizMetadata.intro}}</p>
          </div>
          <div class="col-xs-6">
            <img ng-src="{{quizMetadata.introImg}}" />
            <aside class="figure-caption text-xs-right" ng-if="quizMetadata.introImgCredit">Photo credit: {{::quizMetadata.introImgCredit}}</aside>
          </div>
        </div>
        <div class="row">
          <button class="pull-right btn btn-success" ng-click="startQuiz()">Quiz starten</button>
        </div>
      </section>

      <!-- question list -->
      <section ng-cloak class="fade-in question" ng-if="quizProgress.inProgress && quizProgress.currentQuestion <= quizProgress.lastQuestion">
        <div animate-progression>
          <div class="text-center">
            <img class="img-responsive" ng-src="{{quizQuestions[quizProgress.currentQuestion].questionImg}}" />
          </div>

          <p class="question-content">{{quizQuestions[quizProgress.currentQuestion].question}}</p>
          <div class="question-options">
            <div ng-repeat="option in quizQuestions[quizProgress.currentQuestion].options | orderBy: '-'">
              <div class="option" ng-class="{'wrong': quizQuestions[quizProgress.currentQuestion].answerChecked && option.selected && !option.correct, 'correct': option.correct && quizQuestions[quizProgress.currentQuestion].answerChecked, 'dim': quizQuestions[quizProgress.currentQuestion].answerChecked}">
                <input type="radio" name="option" id="{{$index}}" ng-click="answerQuestion({selected: option.name})" ng-disabled="quizQuestions[quizProgress.currentQuestion].answerChecked">
                <label for="{{$index}}">{{option.name}}</label>
              </div>
              <div class="row feedback" ng-if="quizQuestions[quizProgress.currentQuestion].answerChecked && option.correct">
                <span ng-bind-html="quizQuestions[quizProgress.currentQuestion].feedback"></span>
              </div>
            </div>
          </div>

          <div class="row">
            <button ng-if="quizProgress.currentQuestion === -1" class="btn btn-primary" ng-click="startQuiz()">Quiz starten</button>
            <button ng-if="quizQuestions[quizProgress.currentQuestion].answerChecked && quizProgress.currentQuestionFriendly !== quizProgress.lastQuestion" class="btn btn-primary pull-right" ng-click="nextQuestion()">Nächste Frage <i class="fa fa-arrow-right" aria-hidden="true"></i></button>
            <button ng-if="!quizQuestions[quizProgress.currentQuestion].answerChecked" ng-disabled="!quizQuestions[quizProgress.currentQuestion].answered" class="btn btn-primary pull-right" ng-click="checkAnswer()">Antwort prüfen</button>
          </div>
        </div>

        <div class="get-my-results text-center" ng-if="quizProgress.currentQuestionFriendly === quizProgress.lastQuestion && quizQuestions[quizProgress.currentQuestion].answerChecked">
          <button class="pulse btn btn-primary" ng-click="getScore()">Wie ist mein Ergebnis?</button>
        </div>
      </section>

      <section class="loading" ng-if="quizProgress.loading || quizProgress.calculatingScore">
        <div class="loader"></div>
      </section>

      <section class="fade-in" ng-if="!quizProgress.calculatingScore && !quizProgress.inProgress && quizProgress.currentQuestionFriendly === quizProgress.lastQuestion">
        <div class="results">
          <div class="text-center">
            <h1>Ergebnis</h1>
            <h2>{{score}}</h2>
          </div>
        </div>

        <div class="text-center">
          <button class="start-over btn btn-success" ng-click="startOver()"><i class="fa fa-repeat" aria-hidden="true"></i>Neuer Versuch</button>
        </div>
      </section>
  </section>
</body>

</html>
            
          
!
            
              /* With keyframe animations from animate.css */

@import url(https://fonts.googleapis.com/css?family=Roboto);

body {
  padding-top: 1.5em;
  font-family: 'Roboto', regular;
}

.quiz {
  margin-top: 1em;
  min-height: 60vh;
  background: #fff;
  box-shadow: -2px 0px 21px -2px rgba(0, 0, 0, 0.4);
}

.text-center {
  text-align: center;
}

.quiz .question img {
  display: block;
  margin: 0 auto;
}

.quiz button {
  margin-top: 2em;
  user-select: none;
  outline: 0!important;
  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1);
}

.quiz .btn {
  font-size: 1.6rem;
  height: 3.2em;
  transition: all .25s ease;
}

.quiz .btn-primary,
.quiz .btn-success {
  opacity: 0.9;
  background: #4c9cff;
  border-radius: 0;
  border: 0;
  padding: 0.5em 1em;
  text-align: center;
  color: #fff;
}

.quiz .btn-primary:hover {
  opacity: 1;
  background: #4c9cff;
  color: #fff
}

.quiz .btn-success {
  background: #1671a9;
}

.quiz .btn-success:hover,
.quiz .btn-success:active {
  background: #1671a9;
}

.quiz .btn-primary:disabled,
.quiz .btn-primary:disabled:hover {
  background: #ccc;
}

.quiz .content {
  color: #222;
  padding: .25em 3em 2em 3em;
  margin-bottom: 1em;
}

.quiz .intro {
  margin-top: 2em;
}

.quiz .intro p {
  font-size: 2rem;
}

.quiz aside {
  color: #777;
  font-size: 1.5rem;
  padding-top: 0.25em;
}

.quiz .question {
  margin-top: 2em;
  position: relative;
}

.quiz .question img {
  box-shadow: -2px 0px 21px -2px rgba(0, 0, 0, 0.4);
}

.quiz .question p,
.quiz .intro p {
  font-size: 1.8rem;
  line-height: 1.5;
  margin: 1em 0;
}

.quiz .intro p:last-of-type {
  padding-bottom: 0;
}

.quiz .question-content {
  min-height: 50px;
}

.quiz .question-options {
  margin-left: 1.5rem;
}

.quiz .feedback {
  padding-bottom: .75em;
  margin: -.5em 1em 0 2em;
  animation: .75s roll-in ease;
}

.quiz .progress {
  position: relative;
  margin-bottom: 0;
  background: rgb(181, 181, 181);
  border-radius: 0;
  width: 100%;
}

.quiz .progress-bar {
  background: #4c9cff;
  height: 100%;
  transition: width .4s ease;
}

.quiz .progress .counter {
  position: absolute;
  right: 5px;
  top: 0;
  font-weight: normal;
  color: #fff;
}

.quiz .get-my-results {
  font-size: 2.4rem;
  margin-bottom: 1em;
}

.quiz button .fa {
  margin-right: .5em;
}

.quiz .start-over {
  margin-top: 20%;
}

.quiz .results {
  padding: 3em;
  margin-top: 2em;
  color: #fff;
  background: #2b9eda;
}

.quiz .results h1 {
  font-size: 2.8rem;
  text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.1);
}

.quiz .results h2 {
  font-size: 2.4rem;
  text-shadow: 1px 2px 1px rgba(0, 0, 0, 0.1);
}

.quiz .dim {
  opacity: 0.5;
}

.quiz .dim [type="radio"]:checked + label,
.quiz .dim [type="radio"]:not(:checked) + label {
  cursor: initial;
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.loader,
.loader:before,
.loader:after {
  border-radius: 50%;
}

.loader:before,
.loader:after {
  position: absolute;
  content: '';
}

.loader:before {
  width: 5.2em;
  height: 10.2em;
  background: #0dc5c1;
  border-radius: 10.2em 0 0 10.2em;
  top: -0.1em;
  left: -0.1em;
  -webkit-transform-origin: 5.2em 5.1em;
  transform-origin: 5.2em 5.1em;
  -webkit-animation: load2 2s infinite ease 1.5s;
  animation: load2 2s infinite ease 1.5s;
}

.loader {
  font-size: 11px;
  text-indent: -99999em;
  margin: 55px auto;
  margin-top: 15em;
  position: relative;
  width: 10em;
  height: 10em;
  box-shadow: inset 0 0 0 1em #ffffff;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}

.loader:after {
  width: 5.2em;
  height: 10.2em;
  background: #0dc5c1;
  border-radius: 0 10.2em 10.2em 0;
  top: -0.1em;
  left: 5.1em;
  -webkit-transform-origin: 0px 5.1em;
  transform-origin: 0px 5.1em;
  -webkit-animation: load2 2s infinite ease;
  animation: load2 2s infinite ease;
}

.quiz .loading {
  margin-top: 10em;
}


/* custom radio controls */

.quiz .option {
  margin-bottom: .75em;
  transition: all .25s ease;
}

.quiz [type="radio"]:checked,
.quiz [type="radio"]:not(:checked) {
  position: absolute;
  left: -9999px;
}

.quiz [type="radio"]:checked + label,
.quiz [type="radio"]:not(:checked) + label {
  position: relative;
  font-weight: normal;
  padding-left: 28px;
  cursor: pointer;
  line-height: 20px;
  display: inline-block;
  color: #666;
}

.quiz [type="radio"]:checked + label:before,
.quiz [type="radio"]:not(:checked) + label:before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 20px;
  height: 20px;
  border: 1px solid #ddd;
  border-radius: 100%;
  background: #fff;
}

.quiz .correct [type="radio"] + label::before,
.quiz .wrong [type="radio"] + label::before {
  border: 0;
  font-size: 1.2rem;
  animation: .25s roll-in ease;
}

.quiz .correct [type="radio"] + label::after,
.quiz .wrong [type="radio"] + label::after {
  display: none;
}

.quiz .correct [type="radio"] + label:before {
  content: '\f00C';
  font-family: "FontAwesome"!important;
  color: #09b39c;
}

.quiz .wrong [type="radio"] + label:before {
  content: '\f00d';
  font-family: "FontAwesome"!important;
  color: #b05747;
}

.quiz [type="radio"]:checked + label:after,
.quiz [type="radio"]:not(:checked) + label:after {
  content: '';
  width: 12px;
  height: 12px;
  background: #ea7373;
  position: absolute;
  top: 4px;
  left: 4px;
  border-radius: 100%;
  -webkit-transition: all 0.2s ease;
  transition: all 0.2s ease;
}

.quiz [type="radio"]:not(:checked) + label:after {
  opacity: 0;
  -webkit-transform: scale(0);
  transform: scale(0);
}

.quiz [type="radio"]:checked + label:after {
  opacity: 1;
  -webkit-transform: scale(1);
  transform: scale(1);
}

@keyframes load2 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@keyframes pulse {
  from {
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
  50% {
    -webkit-transform: scale3d(1.05, 1.05, 1.05);
    transform: scale3d(1.05, 1.05, 1.05);
  }
  to {
    -webkit-transform: scale3d(1, 1, 1);
    transform: scale3d(1, 1, 1);
  }
}

@keyframes fade {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.pulse {
  -webkit-animation-name: pulse;
  animation: pulse 1s infinite;
}

.fade-in {
  animation: fade .75s ease;
}

.question-animate {
  animation: fade .7s ease;
}

.loader,
.loader:before,
.loader:after {
  border-radius: 50%;
}

.loader:before,
.loader:after {
  position: absolute;
  content: '';
}

.loader:before {
  width: 5.2em;
  height: 10.2em;
  background: #0dc5c1;
  border-radius: 10.2em 0 0 10.2em;
  top: -0.1em;
  left: -0.1em;
  -webkit-transform-origin: 5.2em 5.1em;
  transform-origin: 5.2em 5.1em;
  -webkit-animation: load2 2s infinite ease 1.5s;
  animation: load2 2s infinite ease 1.5s;
}

.loader {
  font-size: 11px;
  text-indent: -99999em;
  margin: 55px auto;
  position: relative;
  width: 10em;
  height: 10em;
  box-shadow: inset 0 0 0 1em #ffffff;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
}

.loader:after {
  width: 5.2em;
  height: 10.2em;
  background: #0dc5c1;
  border-radius: 0 10.2em 10.2em 0;
  top: -0.1em;
  left: 5.1em;
  -webkit-transform-origin: 0px 5.1em;
  transform-origin: 0px 5.1em;
  -webkit-animation: load2 2s infinite ease;
  animation: load2 2s infinite ease;
}

@keyframes load2 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

@keyframes roll-in {
  0% {
    top: 10px;
    opacity: 0;
  }
  100% {
    top: 0;
    opacity: 1;
  }
}
            
          
!
            
              angular.module('ngQuiz', ['ngSanitize'])

.controller('ngQuizController', function($scope, $timeout, quizProgress, scoreKeeper) {
  $scope.quizProgress = quizProgress;

  $scope.quizData = {
    "quizMetadata": {
      "title": "Munich Members Quiz",
      "intro": "Wie gut kennen Sie Munich Members und den Kreativstandort München? Finden Sie es jetzt heraus!",
      "introImg": "http://munich-members.com/wa_images/munich_members_logo_r_1.jpg",
     
    },
    "quizQuestions": [{
      "question": "Welchem Referat steht der Schirmherr von Munich Members, Münchens Zweiter Bürgermeister Josef Schmid, vor?",
      "questionImg": "http://munich-members.com/wa_images/muenchen4.png",
      "feedback": "Seit 2014 ist Josef Schmid Zweiter Bürgermeister der Landeshauptstadt München sowie Leiter des Referats für Arbeit und Wirtschaft.",
      "options": [{
        "name": "Kulturreferat",
        "correct": false
      }, {
        "name": "Referat für Arbeit und Wirtschaft",
        "correct": true
      }, {
        "name": "Baureferat",
        "correct": false
      }]
    }, {
      "question": "Wer gehört definitionsgemäß zur 'Kreativen Klasse'?",
      "questionImg": "http://munich-members.com/wa_images/muenchen3.png",
      "feedback": "Nach der Theorie des Wirtschaftforschers Richard Florida kommt es für die wirtschaftlich erfolgreichen Standorte der Zukunft vor allem darauf an, möglichst viele kreative und qualifizierte Menschen - die sogenannte Creative Class - anzuziehen. <br/>Zur Creative Class zählen Menschen aus allen Bereichen der Arbeitswelt, solange der Inhalt ihrer Arbeit einen kreativen Prozess in sich führt.",
      "options": [{
        "name": "Ausschließlich Personen mit künstlerischer oder handwerklicher Ausbildung gehören zur kreativen Klasse.",
        "correct": false
      }, {
        "name": "Die kreative Klasse umfasst nur sehr wenige äußerst gebildete Menschen, einige von ihnen sind Nobelpreisträger.",
        "correct": false
      }, {
        "name": "Menschen aus allen Bereichen der Arbeitswelt können der kreativen Klasse zugeordnet werden, solange der Inhalt ihrer Arbeit einen kreativen Prozess in sich führt.",
        "correct": true
      }]
    }, {
      "question": "Was ist ein vorrangiges Ziel von Munich Members?",
      "questionImg": "http://munich-members.com/wa_images/muenchen5.png",
      "feedback": "Munich Members will gemeinsam mit den Kreativpartnern sowie den Partnern aus Wirtschaft und Politik Wirtschaftsprojekte initiieren und deren erfolgreiche Implementierung unterstützen.",
      "options": [{
        "name": "Die Initiierung von Wirtschaftsprojekten.",
        "correct": true
      }, {
        "name": "Freier Eintritt in Museen.",
        "correct": false
      }, {
        "name": "Die regelmäßige Durchführung von Kreativworkshops",
        "correct": false
      }]
    }, {
      "question": "Was beabsichtigt Munich Members?",
      "questionImg": "http://munich-members.com/wa_images/muenchen6.png",
      "feedback": "Munich Members möchte den Weg ebnen für interdisziplinäre Kooperationen zwischen Kreativen, Unternehmen, Wissenschaft und Politik.",
      "options": [{
        "name": "Ausbau des Münchner Straßennetzes zur Entlastung des ÖNV.",
        "correct": false
      }, {
        "name": "Interdisziplinäre Kooperationen.",
        "correct": true
      }, {
        "name": "Münchner Wasserwege für die Binnenschifffahrt zugänglich machen",
        "correct": false
      }]
    }, {
      "question": "Welchen Umsatz erzielen die rund 140 in der Landeshauptstadt angesiedelten Verlage insgesamt pro Jahr?",
      "questionImg": "http://munich-members.com/wa_images/muenchen7.png",
      "feedback": "Mit ca. 1,2 Milliarden Euro Jahresumsatz ihrer rund 140 Verlage ist München die Verlagshauptstadt Europas!",
      "options": [{
        "name": "Rund 1,2 Milliarden Euro.",
        "correct": true
      }, {
        "name": "Rund 850 Millionen Euro.",
        "correct": false
      }, {
        "name": "Rund 450 Millionen Euro.",
        "correct": false
      }]
    }, {
      "question": "Was ist ein vorrangiges Ziel von Munich Members?",
      "questionImg": "http://munich-members.com/wa_images/muenchen1.png",
      "feedback": "Munich Members will die Marke und das Netzwerk des Kreativstandorts München stärken.",
      "options": [{
        "name": "Stärkung des Kreativstandorts München.",
        "correct": true
      }, {
        "name": "Aufbau eines exklusiven Member-Clubs.",
        "correct": false
      }, {
        "name": "Schließung von Startup-Akzeleratoren.",
        "correct": false
      }]
    }, {
      "question": "Welches Umsatzvolumen wird in der Metropolregion München pro Jahr in der Software-/Games-Industrie erwirtschaftet?",
      "questionImg": "http://munich-members.com/wa_images/muenchen2.png",
      "feedback": "Betrachtet man die Teilmärkte der Kultur- und Kreativwirtschaft in der Metropolregion München hinsichtlich ihrer Wirtschaftskraft, steht die Software- und Games-Industrie mit einem jährlichen Umsatzvolumen von über 5,1 Milliarden Euro an der absoluten Spitze.",
      "options": [{
        "name": "Rund 51 Millionen Euro",
        "correct": false
      }, {
        "name": "Rund 5,1 Milliarden Euro",
        "correct": true
      }, {
        "name": "Rund 510 Millionen Euro",
        "correct": false
      }]
    }, {
      "question": "Wieviele Erwerbstätige (Selbständige und Angestellte) der Metropolregion München sind in der Musikwirtschaft tätig?",
      "questionImg": "http://munich-members.com/wa_images/muenchen4.png",
      "feedback": "",
      "options": [{
        "name": "Weniger als 1.000",
        "correct": false
      }, {
        "name": "Rund 6.000",
        "correct": false
      }, {
        "name": "Etwas über 4.000",
        "correct": true
      }]
    }, {
      "question": "Wieviel Prozent aller in Deutschland im Kunstmarkt Beschäftigten sind in der Metropolregion München zu finden? ",
      "questionImg": "http://munich-members.com/wa_images/muenchen5.png",
      "feedback": "Zum Kunstmarkt werden in offiziellen Statistiken sowohl selbständige bildende Künstler als auch Galerien, Kunstauktionshäuser und Kunsthandel gezählt. <br/>Rund 10 Prozent aller  in Deutschland im Kunstmarkt Beschäftigten sind in der Metropolregion München zu finden.",
      "options": [{
        "name": "10 Prozent",
        "correct": true
      }, {
        "name": "5 Prozent",
        "correct": false
      }, {
        "name": "15 Prozent",
        "correct": false
      }]
    }, {
      "question": "Was möchte Munich Members initiieren?",
      "questionImg": "http://munich-members.com/wa_images/muenchen7.png",
      "feedback": "",
      "options": [{
        "name": "Förderung der schönen Künste.",
        "correct": false
      }, {
        "name": "Wirtschaftskooperationen.",
        "correct": true
      }, {
        "name": "Weltfrieden",
        "correct": false
      }]
    }]
  };

  $scope.quizQuestions = $scope.quizData.quizQuestions;
  $scope.quizMetadata = $scope.quizData.quizMetadata;
  quizProgress.lastQuestion = $scope.quizQuestions.length;
  quizProgress.loading = false;

  $scope.startQuiz = function() {
    quizProgress.inProgress = true;
    quizProgress.currentQuestion = 0;
    quizProgress.imageToPreload = 1;
  };

  $scope.nextQuestion = function() {
    if (quizProgress.currentQuestion < quizProgress.lastQuestion) {
      quizProgress.currentQuestion = quizProgress.currentQuestion + 1;
      quizProgress.currentQuestionFriendly = quizProgress.currentQuestionFriendly + 1;
      quizProgress.imageToPreload = quizProgress.imageToPreload + 1;
    }
  };

  $scope.answerQuestion = function(data) {
    $scope.quizQuestions[quizProgress.currentQuestion].answered = true;
    angular.forEach($scope.quizQuestions[quizProgress.currentQuestion].options, function(obj) {
      if (obj.name === data.selected) {
        obj.selected = true;
      } else {
        obj.selected = false;
      }
    });
  };

  $scope.checkAnswer = function() {
    $scope.quizQuestions[quizProgress.currentQuestion].answerChecked = true;

    angular.forEach($scope.quizQuestions[quizProgress.currentQuestion].options, function(obj) {
      if (obj.selected) {
        if (obj.correct) {
          $scope.quizQuestions[quizProgress.currentQuestion].answerWasRight = true;
        } else {
          $scope.quizQuestions[quizProgress.currentQuestion].answerWasRight = false;
        }
      }
    });
  };

  $scope.getScore = function() {
    quizProgress.inProgress = false;
    quizProgress.finished = true;
    quizProgress.calculatingScore = true;
    $scope.score = scoreKeeper.calculateScore($scope.quizQuestions);

    $timeout(function() {
      quizProgress.calculatingScore = false;
    }, 1500);
  };

  $scope.startOver = function() {
    angular.forEach($scope.quizQuestions, function(obj) {
      obj.answered = false;
      obj.answerWasRight = false;
      obj.answerChecked = false;

      angular.forEach(obj.options, function(option) {
        option.selected = false;
      });
    });

    quizProgress.inProgress = true;
    quizProgress.finished = false;
    quizProgress.currentQuestion = 0;
    quizProgress.currentQuestionFriendly = 1;
  };
})

.factory('quizProgress', function() {
  return {
    currentQuestion: 0,
    imageToPreload: 0,
    currentQuestionFriendly: 1,
    lastQuestion: 0,
    loading: true,
    inProgress: false,
    finished: false,
    calculatingScore: false
  };
})

.service('scoreKeeper', function() {
  this.calculateScore = function(quizQuestions) {
    var rightAnswers = 0;
    angular.forEach(quizQuestions, function(obj) {
      if (obj.answerWasRight) {
        rightAnswers += 1;
      }
    });

    return ((rightAnswers / quizQuestions.length) * 100).toFixed() + '%';
  };
})

.directive('progressBar', function(quizProgress) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      scope.$watch('quizProgress', function(newVal, oldVal) {
        if (newVal) {
          element.css('width', ((quizProgress.currentQuestionFriendly / quizProgress.lastQuestion) * 100 + '%'));
        }
      }, true);
    }
  };
})

.directive('imagePreload', function(quizProgress) {
  return {
    restrict: 'EA',
    template: "<img style='display:none;' ng-src='{{quizQuestions[quizProgress.imageToPreload].questionImg}}'/>"
  };
})

.directive('animateProgression', function(quizProgress, $timeout) {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
      scope.$watch('quizProgress.currentQuestion', function(newVal, oldVal) {
        if (newVal) {
          element.addClass('question-animate');
          $timeout(function() {
            element.removeClass('question-animate');
          }, 1500);
        }
      });
    }
  };
});
            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.

Console