Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Quiz Application in AngularJs

4.82/5 (117 votes)
26 Jan 2017CPOL9 min read 249.5K   11.1K  
A general purpose quiz application in angularJs that can be used anywhere

Introduction

Quiz application in one form or the other is becoming a general requirement for most of the applications these days. Be it Survey, mock test, preparation, self evaluation, gathering information, actual objective test or exam. This quiz application will help you to get through your need with minimal or no modification.

This article presents you a simplified way to create your quiz application in angular js in just few lines of code. The quiz application accepts the questions in json format. So, you can easily send the json from the server in the pre-defined format and the angular js quiz application will render the quiz at the client side. The quiz also has review and display result section. If you wish to declare the result immediately, you can simply call another json with the answers in it and simply evaluate and display the results immediately. Alternatively, if you wish to just submit the answers to the server, you can also do so at onSubmit method quizCtrl.js.

You can view the live demo of the application at: http://anuraggandhi.com/ngquiz/index.html.

Please keep watching the frequent update on github: https://github.com/softgandhi/ngQuiz

If you are looking for angular 2 version of this article, please click here.

Background

This article assumes that you have the basic knowledge of AngularJs, bootstrap and a bit of CSS. JQuery has not been used in this application. However, if you wish to implement more features using JQuery or any other JavaScript library, you can do it without any problem.

Important Note: This application may not work directly by running index.html from file system. You would require to host it manually to any web server or run it via some tool like Visual Studio. One of the easy ways to run this is: Open the index.html in Visual Studio and then, right click -> View in Browser. Visual Studio will automatically create a website for you and run your application.

Image 1

Using the Code

Using the code is simple. Just provide the json to the quiz application and it will render the quiz.

The json format should look like the following:

JavaScript
// aspnet.js
{
    "quiz": {
        "Id": 1,
        "name": "Asp.Net Quiz",
        "description": "Asp.Net Quiz (contains webform, mvc, web API, etc.)"
    },
    "questions": [{
        "Id": 1010,
        "Name": "ASP.NET webform separates the 
        HTML output from program logic using a feature named as", 
        "QuestionTypeId": 1,
        "Options": [
            { "Id": 1055, "QuestionId": 1010, 
            "Name": "Exception", "IsAnswer": false },
            { "Id": 1056, "QuestionId": 1010, 
            "Name": "Code-behind", "IsAnswer": true },
            { "Id": 1057, "QuestionId": 1010, 
            "Name": "Code-front", "IsAnswer": false },
            { "Id": 1058, "QuestionId": 1010, 
            "Name": "None of the above", "IsAnswer": false }],
        "QuestionType": { "Id": 1, 
        "Name": "Multiple Choice", "IsActive": true }
    },
    {
        "Id": 1011,
        "Name": "The feature in ASP.NET 2.0 that is used to 
        fire a normal postback to a different page in the application is called", 
        "QuestionTypeId": 1,
        "Options": [
            { "Id": 1055, "QuestionId": 1010, 
            "Name": "Theme", "IsAnswer": false },
            { "Id": 1057, "QuestionId": 1010, 
            "Name": "Code-front", "IsAnswer": false },
            { "Id": 1056, "QuestionId": 1010, 
            "Name": "Cross Page Posting", "IsAnswer": true },
            { "Id": 1058, "QuestionId": 1010, 
            "Name": "None of the above", "IsAnswer": false }],
        "QuestionType": { "Id": 1, "Name": 
        "Multiple Choice", "IsActive": true }
    },
... [For full code, please see the sample attached.]
//

You may not wish to include the IsAnswer property to the options as it might be a unsafe for a secured quiz. In such case, you can simply send the questions with IsAnswer. Once the user submits the quiz, onSubmit method in quizCtrl.js, you can call the questions with answers and evaluate the answers.

About Quiz Application

The quiz application consists of mainly 3 components/views: Quiz View, Review, Result. For the sake of simplicity, I have kept the views in the same file. If you wish to scale this application, you can very well separate these views. Apart from this, quizCtrl.js has been used as a controller for all the views and style.css has been used to apply css style to the application. Moreover, AngularJs JavaScript and bootstrap CSS has been used for the purpose of data-binding and styling respectively.

The Controller

The application has a small set of scripting part that has been handled by the controller: quizCtrl.js. First of all, the controller loads the questions by using $scope.loadQuiz('data/aspnet.js') method. The quiz questions should be provided in a pre-defined json format as mentioned in aspnet.js or other related js files. Once the questions are loaded, user can answer the questions and the events are being captured by the same controller. When user finally submits the quiz, you may submit the answers to the server in json format. Or load the questions with answers and evaluate the users answers to show the quiz result immediately. In the sample, I have provided the later approach, but the first approach is also fairly simple.

The quizCtrl.js file looks like the following:

The html for quiz view looks like the following:

JavaScript
// quizCtrl.js
...
    $scope.loadQuiz = function (file) {
        $http.get(file)
         .then(function (res) {
             $scope.quiz = res.data.quiz;
             $scope.questions = res.data.questions;
             $scope.totalItems = $scope.questions.length;
             $scope.currentPage = 1;

             $scope.$watch('currentPage + itemsPerPage', function () {
                 var begin = (($scope.currentPage - 1) * $scope.itemsPerPage),
                   end = begin + $scope.itemsPerPage;

                 $scope.filteredQuestions = $scope.questions.slice(begin, end);
             });
         });
    }
    $scope.loadQuiz('data/aspnet.js');

    $scope.isAnswered = function (index) {
        var answered = 'Not Answered';
        $scope.questions[index].Options.forEach(function (element, index, array) {
            if (element.Selected == true) {
                answered = 'Answered';
                return false;
            }
        });
        return answered;
    };

    $scope.isCorrect = function (question) {
        var result = 'correct';
        question.Options.forEach(function (option, index, array) {
            if ($scope.toBool(option.Selected) != option.IsAnswer) {
                result = 'wrong';
                return false;
            }
        });
        return result;
    };
... 
[For full code, please see the sample attached.]

For simplicity, I have used only one controller: quizCtrl.js. However, if you wish to scale this application, you may wish to separate the different views and controllers to different files.

Quiz Configuration

The quiz configuration is an optional object that should be present in your <quiz>.js file. The config section allows you to customize your quiz the way you wisth to do. The quiz application reads this configuration settings and apply these settings at the time of loading the quiz. The settings mainly consists of: shuffling the questions, showing/hiding pager, allowing back navigation, allowing auto move to next question. The details of this configuration is explained in "Quiz Features" section.

The quiz configuration looks like the following:

JavaScript
// csharp.js
...
    "config":{
        "shuffleQuestions": true,
        "showPager": false,
        "allowBack": true,
        "autoMove": true
    }
... 
[For full code, please see the sample attached.]

Services Used

For simplicity, I have used only one service in angularJs controller: $http. It is used to retrieve quiz json file.

Quiz View

The Quiz View contains the actual quiz questions, previous-next button, paging and related stuffs. I have chosen the structure of keeping one question per page but if you would like to show more than one question, you can simply change the pageSize accordingly. For buttons and pagination UI, bootstrap has been used. The UI for questions and options has been set in style.css.

The html for quiz view looks like the following:

HTML
// quiz.html
        <div ng-repeat="question in filteredQuestions">
            <div class="label label-warning">Question 
            {{currentPage}} of {{totalItems}}.</div>
            <div class="question">
                <h2>{{currentPage}}. {{question.Name}}</h2>
                <div class="options">
                    <div ng-repeat="Option in question.Options">
                        <label for="{{Option.Id}}" 
                        ng-click="onSelect(Option);">
                            <input id="{{Option.Id}}" 
                            type="checkbox" ng-model="Option.Selected" />
                            {{Option.Name}}
                        </label>
                    </div>
                </div>
            </div>
        </div>
... [For full code, please see the sample attached.]

If you know angular js, this part is simple to understand. To display the questions and options, ng-repeat has been used.

The review and result view has also been implemented similarly by iterating over the quiz questions and displaying the needed stuffs. Below is the screen shot of Review and Result View.

Image 2

Image 3

The Styling

For styling and theme, bootstrap (customized) has been used. For further styling based on the applications need, css classes has been added in style.css. All the CSS styles are self-explanatory. If you wish to change the look and feel of the application, you can easily do so by changing corresponding css class in style.css. I have made all attempts to make it responsive so that the application can be navigated easily on mobile phones and tablets too.

Quiz Features

This section acts a small documentation kind of stuff for using the features of the quiz application.

Shuffle Questions

shuffleQuestions property in config section is used to mention whether the questions should be randomized before showing or not. If true, the questions will be randomized. The default value is false.

Shuffle Options

shuffleOptions property in config section is used to mention whether the options can be randomized before showing or not. If true, the questions will be randomized. The default value is false. This feature is configurable from the quiz json file.

Show Pager

showPager property in config section indicates whether to show the pager element in quiz or not. If false, the numeric pager will not be shown. In this case, the user can still navigate via. first, prev, next and last button. The default value is true.

Auto Move

autoMove property in config section indicates whether to move to next question automatically when the question is answered. If true, you don't need to press Next button to move to next question. The default value is false.

Load Quiz Dynamically

In mock test/practice exams, user might want to change the quiz dynamically. To do so, you just need to call loadQuiz method and pass the url of the new quiz. The attached sample or the demo link illustrates this.

Html Questions

In many cases, you wish to have special characters, images, subscript, superscript, and other html elements. Adding html markup in question has been provided via angular sanitize. To add image or any HTML formatting in questions, just add corresponding html tags in question.

I will keep on documenting other features as and when they will be available here.

Future Consideration

Due to time constraint, I could not implement other interesting features which might help you more if you wish to use this quiz application. I will add them later as and when I get time. I would also appreciate if someone can provide me the pull request in github, if they have implemented any of the pending feature or existing feature in a better way. :)

Some of the features I can think of are:

  • Quiz Options: In many cases, we need to randomize questions, randomize options, or set different marks for different questions. I am planning to provide these features which will be configurable from the quiz json file.
  • Html Questions: In many cases, you wish to have special characters, subscript, superscript, and other html elements. So, in my opinion, providing html option in Quiz application would be a nice addition. This feature has been implemented.
  • Question Type: Currently, the application supports only multiple choice question. In many scenarios, it is needed to have multiple answer type question, true-false, etc. I will come up with this provision soon.
  • Timer: Timer is another important feature which every test/mock test wants to have. Timer/Stopwatch option shall also be provided as a configurable element in the quiz.
  • Image for Question: Image is also one of the most needed feature in most of the quiz. I will come up with this feature in this article very soon. Image for questions can be provided by adding Html questions.
  • Pick From Pool: In some scenarios, you might want to provide a pool of many questions as a json and want the Quiz application to randomly select n questions for the quiz. This feature will be implemented soon.
  • Optional Animation: Well, this is not an important feature but some people may want a bit of animation in his quiz application. I would, therefore, like to provide this feature as well.
  • Mobile Friendly: Even though this app is responsive and adjusts well with mobile and smaller screens, fonts and alignment needs to be adjusted according to the screen size. So, having a mobile friendly view is also a good and valid need. CSS has been optimized and css3 media query has been written to provide optimized view for mobile.
  • Tailored Questions: There are many cases when we require a tailored questions in a survey. This means that the next set of questions should come based on the option selected in current question of the survey. Based on email feedback from many users, I will give this feature a priority and will provide you as soon as I will get time for it.
  • Angular 2 version: Since Angular 2 is about to release, I would consider to re-write the application with better design and more flexibility in Angular 2.

Apart from the above features, if you feel some more feature should be added, please let me know. I will try my best to implement them.

History

  • 2015-01-04
    • First version release
  • 2015-01-11
    • Update: Add and partial implementation of configuration section
  • 2015-11-16
    • Added support for html quiz
    • Updated to Angular 1.4
    • Added repository in github
    • Bug fix and cleanup
  • 2015-11-25
    • Added media query in CSS to provide better mobile optimized view
  • 2016-09-12
    • Added feature to randomize options

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)