Create a “load more” widget using AngularJS, Ajax and Bootstrap 3

Prerequisite

Make sure you have basics on Bootstrap 3 Framework and AngularJS. If you are used to Boostrap 2.3.2 here is a post I wrote about what’s new in Twitter Bootstrap 3

Step 1: Getting the data ready

Before doing anything a good practice is to focus on the data format you want your API to return. Within this demo we will not focus on how to get the data (BackEnd code) but instead we will just pretend the API works and return the data we want in the way we want.
An example of the backend code using PHP and WordPress is shown on the demo.
By knowing the format, data manipulation gets easier. For my demo I want the API to return an array filled with post objects: [{},{}, ...] which is a pretty classic format.

Example

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
[
    {
        "post_title":"How to automatically checkout the latest tag of a Git repository",
        "post_content":"Now that you know how to automatically tag a Git repository an interesting command to know about is \"How to automatically checkout the latest tag of a Git repository\". Let's imagine that you want to a...",
        "post_name":"how-to-automatically-checkout-the-latest-tag-of-a-git-repository",
        "post_date":"2013-10-04 18:31:00",
        "post_img":"path/to/your/img.png",
        "ID":"1292"
    },
    {
        "post_title":"Sidr",
        "post_content":"\r\n \r\n Sidr is a jQuery plugin for creating side menus. It is the library that I use to create \"Previous\" and \"Next\" post button on my Open Sourced WordPress theme (the one you are using righ...",
        "post_name":"sidr",
        "post_date":"2013-09-24 20:16:04",
        "post_img":"path/to/your/img.png",
        "ID":"1279"
    }
]

Step 2: Creating a basic scaffolding

Insert Scripts and Style-sheets

Insert the following lines within the head section of your HTML.
1
2
3
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" type="text/css" rel="stylesheet">

Create a module

Creating a module facilitate the dependency handling. At the moment we will not have any dependencies but we will add a Factory later on.
1
2
3
<script type="text/javascript">
    angular.module('demo');
</script>
To link the module to the DOM you need to tells AngularJS to be active in a portion of the page by addingdata-ng-app attribute. In this case the entire document.
1
2
<body data-ng-app="demo">
</body>

Add a controller

AngularJS introduces the MVC (Model, View, Controller) model and dependency injection, both concepts are illustrated here. Our Controller MyCtrl can manipulate the Model $scope that was injected via MyCtrl.$inject. Those concept are extremely important to understand in order to go further.
1
2
3
4
5
6
<script type="text/javascript">
    angular.module('demo');
    function MyCtrl($scope) {}
    MyCtrl.$inject = ['$scope'];
</script>
We now have a basic AngularJS application ready.

Step 3: Creating a Factory

An elegant way communicate with the server is to create a Factory. This lets the controller focus on the behavior rather than the complexities of server access. Interaction with server-side data sources can be made through the module “ngResource” (previously included: angular-resource.min.js).
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<script type="text/javascript">
    angular.module('demo', ['demoFactory']);
    angular.module('demoFactory', ['ngResource']).factory('ResourceFactory'function($resource) {
        return $resource('?desiredPosts=:desiredPosts&start=:start', {}, {
            // Declaration of custom action that should extend the default set of resource actions
            query: {
                isArray: true,
                cache: false
            }
        });
    });
    function MyCtrl($scope, ResourceFactory,) {}
    MyCtrl.$inject = ['$scope''ResourceFactory'];
</script>
Please note that I have added the newly created demoFactory as a dependency of my module and the ResourceFactoryobject to my controller MyCtrl via MyCtrl.$inject.

Step 4: Interacting with the DOM (Document Object Model)

To understand how AngularJS manipulates the DOM let’s try to display the number of posts already loaded within our widget. To do so in our controller we initiate the post list $scope.list to an empty array (no posts loaded at the beginning) and set the $scope.count property to the list length.
1
2
3
4
function MyCtrl($scope, ResourceFactory,) {
    $scope.list = []
    $scope.count = $scope.list.length;
}
$scope contains your model data. It is the glue between the controller and the view (HTML). To access the data within the view you must declare the data binding locations using {{ }}. AngularJS will automatically update the post list and the post count whenever the $scope properties changes.
Now let’s use a Bootstrap 3 panel to create our widget. We need a header with the widget title (plus the post count) and a post body.
1
2
3
4
5
6
<body data-ng-app="demo">
    <div id="widget" class="panel panel-default" data-ng-controller="MyCtrl">
        <div class="panel-heading">Widget Title <span class="badge">{{count}}</span></div>
        <div class="panel-body"></div>
    </div>
</body>
As soon as we will load posts into our list the {{count}} property that you can see in the HTML above will be updated.

Create an empty “load more” function

Now that we know how AngularJS updates the DOM we need to populate it with fresh data. Let’s create a function “loadMore” that we will trigger on a button click event.
1
2
3
4
5
function MyCtrl($scope, ResourceFactory,) {
    $scope.list = []
    $scope.count = $scope.list.length;
    $scope.loadMore = function(e) {}
}

Bind the “load more” function to a DOM node

data-ng-click is a directive, directives are instructions that tell the AngularJS compiler to attach a given behavior to a DOM node when a certain marker appears in the DOM. Here the directive will trigger the “loadMore” function once clicked.
1
2
3
4
5
6
<body data-ng-app="demo">
    <div id="widget" class="panel panel-default" data-ng-controller="MyCtrl">
        <div class="panel-heading">Widget Title <span class="badge">{{count}}</span></div>
        <button class="more btn btn-primary btn-block" data-ng-click="loadMore($event)">More</button>
    </div>
</body>

Populate the “load more” function

To keep it simple the “load more” function will query our factory “ResourceFactory” with a start and desiredPostsparameters. The result will be stored inside $scope.list.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function MyCtrl($scope, ResourceFactory,) {
    $scope.list = []
    $scope.count = $scope.list.length;
    $scope.loadMore = function(e) {
        ResourceFactory.query({
            start: $scope.count,
            desiredPosts: 2
        }, function(data) {
            if (data.length > 0) {
                // update list
                $scope.list = $scope.list.concat(data);
            }
        });
    }
}
Now every time a user hits the “More” button an Ajax request will be sent and fresh new data will be populated inside$scope.list.

Iterate through the list

By using the data-ng-repeat directive we tell AngularJS to inject the $scope.list items within the DOM. Every time$scope.list is updated the DOM will be automatically updated.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
<body data-ng-app="demo">
    <div id="widget" class="panel panel-default" data-ng-controller="MyCtrl">
        <div class="panel-heading">Widget Title <span class="badge">{{count}}</span></div>
        <div class="content panel-body">
            <div id="item-{{item.ID}}" class="item" data-ng-repeat="item in list">
                <img class="thumbnail pull-left" src="{{item.post_img}}">
                <a href="#">
                    <h4 style="margin: 5px 0px;">{{item.post_title}}</h4>
                </a>
                <p>{{item.post_content}}</p>
                <div class="well well-sm">{{item.post_date}}</div>
            </div>
        </div>
        <button class="more btn btn-primary btn-block" data-ng-click="loadMore($event)">More</button>
    </div>
</body>
Please note that you can access items properties using {{item.yourProperty}} within the data-ng-repeat directive.
Our “Load More” widget is now finished. Go checkout the demo to see the result!


13 comments

Pretty post, I hope your site useful for many users who want to learn basics of programming to enhance their skill for getting good career in IT, thanks for taking time to discuss about fundamental programming niche.
With Regards,
Angularjs training in chennai|Angularjs course in chennai

Reply


The oracle database is capable of storing the data in two forms such as logically in the form of table spaces and physically like data files.
Oracle Training in Chennai | oracle dba training in chennai

Reply

Angularjs is the great javascript framework that has some compelling features not for developers but also for the designers. Angularjs is very essential for the web developers to know about its importance.
Angularjs Training in Chennai | angularjs course in chennai

Reply

Post a Comment