Creating a Polling Application Using AngularJS and Laravel Part 1

Creating a Polling Application Using AngularJS and Laravel Part 1

Polling Application Screenshots

In this tutorial, we will build a single page polling web application using AngularJS and Laravel. Our application will allow the users to select one of the listed polls and submit their choice. The users will also be able to view the stats of the polls in a graphical form.

We will build the application’s front end using AngularJS, and for the data persistence, we will utilize a RESTful API which we will create using Laravel. The tutorial assumes that you have a basic understanding of AngularJS workings and familiar with concepts like: two-way data binding, scopes, directives etc.

Requirements

Application Directory Structure

Let us first go through the directory structure of the application which is shown in the following screenshot:

Creating a Polling Application Using AngularJS and Laravel Part 1

Polls Application Directory Structure Screenshot

All the JavaScript files will reside inside the js directory. I have also created a dedicated lib directory to hold the libraries: angluar.js, bootstrap.js, d3.js etc. The partials directory will be used to hold the application’s partial views. Here is the markup of the index.html that glues all these assets together and sets up the AngularJS environment upon load:

<!doctype html>
<html lang="en" ng-app="pollsApp">
<head>
    <meta charset="utf-8">
    <title>AngularJS and Laravel Tutorial</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/app.css">
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 center-block content" style="float: none">
            <div ng-view></div>
        </div>
    </div>
</div>
<script src="js/lib/bootstrap/jquery.js"></script>
<script src="js/lib/angular/angular.js"></script>
<script src="js/lib/angular/angular-route.js"></script>
<script src="js/lib/d3/d3.js"></script>
<script src="js/lib/chart/angular-charts.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/directives.js"></script>
</body>
</html>

In the above markup, the ng-app directive is applied to the html element of the page to tell the Angular that the whole document should be considered as an AngularJS application. The name of the application’s module pollApp is also specified. The inner most div element contains the ng-view directive, so, all the partial views will be injected here.

Modules and Dependency Injection in AngularJS

Modules in Angular provide us with an easy way to manage application dependencies and group the functionalities under the namespaces for the better organization of the application structure. In particular, modules are containers that automate the process of dependency resolution. This way dependencies can be injected using a cleaner and declarative syntax.

The dependencies, are the reusable components of an application. These components are called services and usually provide specific functionalities. By using Dependency Injection these services can be used when required. Angular provides us with various services out of the box like: $http for communication with remote servers, $location for URL manipulations, $q for creating deferred objects, $filter for data formatting and a lot more. Angular also provides us with an API for creating our own custom services. We will create a custom service later in this tutorial.

We use angular.module method to create a module. Here is the code snippet that creates pollsApp module:

// file: js/app.js
var pollsApp = angular.module('pollsApp', ['ngRoute','angularCharts']);

In the above code, the first argument of the module method specifies the name of the module and the second argument contains an array of the module dependencies. The following code snippet demonstrates the dependency injection:

var myModule = angular.module('myModule', ['someModule']);
myModule.controller('SimpleController',function($someService) {

}

In the first line we are specifying the module dependency as someModule which defines the $someService. In the second line, $someService is declared as a parameter of the controller function. In the previous paragraph, I have mentioned that Angular allows us to inject the dependencies using declarations and cleaner syntax. Thus, Angular will inject this dependency into the controller function automatically by using the definition of $someService provided in the someModule.

Routing and Partial Views

A single page application requires only one full HTML page load, the subsequent user interactions are handled using DOM manipulations and the views are presented dynamically based on the routing maps. In AngularJS we use ngRoute module to utilize the routing related services and directives like, ng-view.

Here is the code that defines the routing configurations for our polling application:

// file: js/app.js

function pollsAppRouteConfig($routeProvider) {
    $routeProvider.
        when('/', {
            controller: 'IndexController',
            templateUrl: 'partials/list.html'
        }).
        when('/view/:id', {
            controller: 'PollController',
            templateUrl: 'partials/poll.html'
        }).
        when('/view/:id/stats', {
            controller: 'StatsController',
            templateUrl: 'partials/stats.html'
        }).
        otherwise({
            redirectTo: '/'
        });
}
pollsApp.config(pollsAppRouteConfig);

We define an application route by calling the when method on $routeProvider service. The first argument of the method specifies a route pattern and the second argument requires an object containing other route related configurations e.g, template, templateUrl, controller etc.

In the above code, each partial view has an associated controller. So, whenever a partial view will be loaded its scope will be associated with the corresponding controller. The last line of the code registers the route configurations to the pollsApp module by using the config method.

Partial Views

The markup for the partials/list.html:

<h1>Polls</h1>
<poll-alert show-alert="alert.showAlert" alert-class="alert.alertClass" alert-message="alert.msg"></poll-alert>
<div class="list-group">
    <a class="list-group-item" ng-repeat="poll in polls" ng-href="#/view/{{poll.id}}">{{poll.question}}</a>
    <a class="btn btn-success btn-block" ng-show="dataAvailable" ng-click="loadPolls()">Load more polls</a>
    <div class="alert alert-danger" ng-hide="dataAvailable">
        <p>No More Data to Load :(</p>
    </div>
</div>

Note:
The scope of this view will be associated with the IndexController. For now, we are assuming that the models used in this view ( alert, polls ) contain the required data.

The element poll-alert is a custom Angular directive which will show the different type of alerts by using the alert model. I will discuss the code of this directive later in this tutorial. In the div element we are iterating through the polls model of the IndexController to show a list of the available polls by using ng-repeat directive. The function loadPolls will be triggered every time the user will click the Load more polls button.

The markup for the partial/poll.html:

<div>
    <h1>{{poll.question}}</h1>
    <poll-alert show-alert="alert.showAlert" alert-class="alert.alertClass" alert-message="alert.msg"></poll-alert>
    <form ng-submit="save()">
        <ul class="list-group">
            <li ng-repeat="value in poll.options" class="list-group-item">
                <input type="radio" id="option{{$index}}" value="{{value}}" name="option" ng-model="poll.option">
                <label for="option{{$index}}">{{value}}</label>
            </li>
        </ul>
        <div class="text-center">
            <a class="btn btn-danger" ng-href="#/"><span class="glyphicon glyphicon-arrow-left"> Back</span></a>
            <button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-save"> Save</span></button>
            <a class="btn btn-info" ng-href="#/view/{{poll.id}}/stats"><span class="glyphicon glyphicon-stats"> Stats</span></span></a>
        </div>
    </form>
</div>

This view contains a simple form with radio button choices. The ng-submit directive is used to specify the form submission handler: save(). Inside the ul element radio buttons are created dynamically based on the number of poll options. ng-model binds the value of each radio button with the poll.option property. In our PollController we will use this property to submit the user’s choice to the server.

The markup for the partial/stats.html:

<h1>Poll Stats</h1>
<poll-alert show-alert="alert.showAlert" alert-class="alert.alertClass" alert-message="alert.msg"></poll-alert>
<div class='charts'>
    <div ac-chart="chartType" ac-data="data" ac-config="config" id='chart' class='chart'></div>
</div>
<div class="text-right">
    <a class="btn btn-danger" ng-href="#/view/{{id}}"><span class="glyphicon glyphicon-arrow-left"> Back</span></a>
</div>

The directive ac-chart is used here to show the stats in a graphical form. This directive is defined inside angularCharts module. You can refer to the documentation by visiting the link given in the requirements section.

In the next part of this tutorial we will cover the controllers and services. Regards!


3 thoughts on “Creating a Polling Application Using AngularJS and Laravel Part 1

  1. Pingback: Creating a Polling Application Using AngularJS ...

  2. hansen Reply

    great tut – when comes part 2 ?

    cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Time limit is exhausted. Please reload CAPTCHA.