Tuesday, 11 June 2013

AngularJS Framework basics





Following is some of my work on AngularJS, which i have done during my R and D project in company. I found that, this framework is very interesting and can be very useful if you get handy on it. This framework very useful for fast development. It consist of hardcore JS concepts. Its very useful than other JS frameworks.


So basic needs to understand this blog is, you must know basic html, java script, JSON request and response handling mechanism and server side scripting language PHP which is used in this blog. (This framework is also compatible with any other server side scripting languages.)


Note: Code shared by me, is just to give working examples of AngularJS. I tried my best to give you bit information about AngularJS. I regret for any spelling or grammar mistakes from this blog.

You can find live demos of AngularJS on its official website [AngularJS API's reference]

Check out above link to see list of APIs provided by AngularJS and how it actually works.

You can also find video tutorials of AngularJS on [http://www.egghead.io/]
I have taken very simple basic AngularJS examples according to my need. you can explore more according to your need.




I have explained following topics with code.

1) Introduction and uses of AngularJS instead of other alternatives.
2) Sign in form with AngularJS.
3) Session handling with AngularJS.
4) Send mail with AngularJS.
5) Generate HTML with AngularJS.
6) Sign out functionality with AngularJS.
7) File upload with AngularJS.
8) Pagination.


    1. Uses of AngularJS over Other alternatives:

  • There are other frameworks also that provides an imperative way for manipulating the DOM but as we know HTML is not made for dynamic views.
  • AngularJS, by Google, is a well-organized, well-tested, versatile, powerful and flexible JavaScript MVC framework for building rich client-side applications.
  • We still may need to have a server-side backend, but the majority of the user-interactivity logic will be delegated to the client-side. This includes stuff like model validations, data-binding and form submissions which are handled via AJAX, Jquery.
  • AngularJS provides a much higher level of abstraction and is very opinionated on how we should develop our application.
  • As all we know HTML is made for static documents, its not meant for dynamic apps. AngularJS lets us extend our HTML vocabulary for our applications.
Note: Above i have mentioned some uses of AngularJS over other alternatives. But term 'other alternatives' means we can also complete above 8 topics using other java script frameworks like Backone JS, Ember JS. Though i have never worked on these other java script frameworks (i.e. Backbone, Ember),  But professionals found that AngularJS framework is much more flexible and efficient than other java script frameworks. 


     2. Sign in form with AngularJS:
         Begin AngularJS sign in HTML form:

        CODE 1.0:

<!DOCTYPE html>
<html ng-app>
<head>
<title>Login form with AngualrJS</title>
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="css/style.css" type="text/css" />
<script src="http://code.angularjs.org/Latest_Jquery_plug.js"></script> <script src="http://code.angularjs.org/angular-1.0.0.min.js"></script> 
<script src="controller.js"></script>
</head>
<SCRIPT LANGUAGE="javascript">
</script>
<body><div ng-controller='LoginCtrl' class='LoginCtrl'><form action="" method="POST">
<pre ng-model="validationErr" > <b> {{validationErr}} </b> 
</pre>

<p id="message"></p>
<form class='form-login'>
<h4>Employee Login: </h4>
<input type='text' ng-model='userName' class='input-userName' Placeholder='Employee ID...'>
<input type='password' ng-model='passWord' class='input-passWord' Placeholder='Password...'>
<button type="submit" class="btn" ng-click="login()">Login</button>
</form>
</div>
</body>
</html>

  • <html ng-app> The ng-app attribute represents an Angular directive, used to flag an element which Angular should consider to be the root element of our application. This give application developers the freedom to tell AngularJS if the entire html page like <html ng-app> or only a portion of it like <div ng-app> should be treated as the Angular application. 
    We can also have ng-app with module name like <html ng-app='myapp'>, its optional application module which want to load. 
  • The first line is used to activate jquery which we need later.
    Second line is used to activate AngularJS into our code.

  • <div ng-controller='LoginCtrl' class='LoginCtrl'>
    The ng-Controller directive specifies a Controller class, the class has method that typically express the business logic behind the application. In this, LoginCtrl function is defined inside controller.js, When we write above line AngularJS understand that LoginCtrl function should be called.
  • <pre ng-model="validationErr" > <b> {{validationErr}} </b> </pre>
     Is directive that tells Angular to do two way data binding. It works together with input , select, textarea. You can easily write your own directive to use ngModel as well.

  • ng-click="login()": The ng-Click allows you to specify custom behavior when element is clicked. In this situation, it calls function login, which is defined in controller.js inside LoginCtrl, there it performs all sign in functionality.

Controller.js that contains all controller for an application.

CODE 1.1: (controller.js)

function LoginCtrl($scope, $http) {
//Following function reads querystring from URL.

function getQueryVariable(variable) {
var query = window.location.search.substring(1);
//document.write(query);
var vars = query.split("&");
//document.write("<br />");
//document.write(vars);
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if (pair[0] == variable) {
return pair[1];
}
}
}
var log = getQueryVariable("logout"); //calling above function 'getQueryVariable'
//document.write(log);
if(log == 'yes')
{
$scope.validationErr = "You are successfully logged out."; //based on querystring flag appropriate message is displayed.
}
$scope.url = 'mainAPI.php'; // The url of our search

// The function that will be executed on button click (ng-click="login()")
$scope.login = function() {
// Create the http post request
// the data holds the keywords
// The request is a JSON request.

$http.post($scope.url, { "file" : "Login", "userName" : $scope.userName, "passWord" : $scope.passWord }).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
$scope.result = data; // Show result from server in our <pre></pre> element
if(data == 'admin')
{
$scope.result = 'admin';
window.location.replace("admin.html");
}
else if(data == 'wrong')
{
$scope.validationErr = "Login fileds can not be blank....Please enter employee ID / Password";
}
})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
}

Here, in above code It checks for login functionality. Http post request is sent to 'mainAPI.php' file, then it validates fields, if login is successful then 'mainAPI.php' page returns apropriate flag(in this case its 'admin'), after that redirect user to intended page else if login details are invalid then it pass error message into $scope.validationErr (in above code 1.0 , we have line <pre ng-model="validationErr" ><b> {{validationErr}} </b> </pre> this {{validationErr}} displays this error message, but we should not forget to write ng-model="validationErr" in pre tag to display message) .


    3. Session handling with AngularJS.

When user is admin user, then he is redirected to 'admin.html' page as we seen in above code, when user is getting redirected to 'admin.html' page, before redirection and JSON response from 'mainAPI.php' page to admin.html' page, mainAPI.php page creates session using

session_start();
$_SESSION['empid'] = $row['fld_empid'];

in 'mainAPI.php' page itself for valid user. When this session is created JSON response is now returned to the LoginCtrl (CODE 1.1), and then user is redirected to the 'admin.html' page.

Now, when admin.html page gets loaded at same time admin controller gets called by function AdminCtrl() (see below code) which we have defined into 'controller.js' file.

Js file comes to know about which controller should be called by this line <div ng-controller='AdminCtrl' class='AdminCtrl'>
with this line angularJS understand that AdminCtrl should be called.



CODE 2.0: (Admin.html)

<!--

To change this template, choose Tools | Templates

and open the template in the editor.

-->

<!DOCTYPE html>
<html ng-app>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="css/style.css" type="text/css" />
<script src="http://code.angularjs.org/Latest_Jquery_plug.js"></script>
<script src="http://code.angularjs.org/angular-1.0.0.min.js"></script>
<script src="controller.js"></script>
<script type="text/javascript">
function fileSelected() {
var file = document.getElementById('sel_file').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
}
}
function uploadFile() {
var fd = new FormData();
fd.append("overwrite", document.getElementById('overwrite').checked);
fd.append("sel_file", document.getElementById('sel_file').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "login.php");
xhr.send(fd);
}
function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
}

function uploadComplete(evt) {
/* This event is raised when the server send back a response */
//alert("hello");
//$(".message").message = "Login fileds can not be blank....Please enter employee ID / Password";
document.getElementById('message').innerHTML = evt.target.responseText;
alert(evt.target.responseText);
}

function uploadFailed(evt) {
alert("There was an error attempting to upload the file.");
}

function uploadCanceled(evt) {
alert("The upload has been canceled by the user or the browser dropped the connection.");
}

</script>
</head>
<body><div ng-controller='AdminCtrl' class='AdminCtrl'>
<div id="wrapper">
<div id="header">
<div id="logo"><img src="image/logo.jpg" border="0"/></div>
</div>
<div id="content">
<br clear="all" /><br clear="all" /><br clear="all" />
<div>
<br clear="all" /><br clear="all" /><br clear="all" /><br clear="all" /><br clear="all" /><br clear="all" /><br clear="all" /><br clear="all" />
<table align="center" width="50%" height="40%" class="login-bg" >
<tr><td align="center">&nbsp;&nbsp;&nbsp;&nbsp;<span></span><br/><br/><table align="center" bgcolor="" width="85%" >
<pre ng-model="message" id="message">
{{message}}
</pre>
<tr><td>
<div class="boldtext1">Hello Administrator</div><br>
<table>
<form id="form1" enctype="multipart/form-data" method="post" action="Upload.aspx">
<tr>
<td width="180">Import CSV File :</td>
<td><input type="file" name="sel_file" id="sel_file" onchange="fileSelected();"/></td>
<td><input type="checkbox" id="overwrite" name="overwrite" checked="checked" value="Yes" />Overwrite</td>
</tr>
<tr>
<td></td>
<td>
<input type="button" onclick="uploadFile()" value="Upload" />
</tr>
</form>
<tr><td>&nbsp;</td></tr>
<form class='form-sendMail' enctype="multipart/form-data">
<tr>
<td>Send email to all users </td>
<td>
<input type='button' name='sendmail' id="mail" value='Send mail' ng-click="sendmail()" class="button" /></td>
</tr>
</form>
<tr><td>&nbsp;</td></tr>
<form class='form-generateHTML' enctype="multipart/form-data">
<tr>
<td>HTML</td>
<td>
<input type='button' name='generateHTML' value='Generate HTML' ng-click="generateHTML()" class="button" /></td>
</tr>
</form>
<tr><td>&nbsp;</td></tr>
<form class='form-generateHTML' enctype="multipart/form-data">
<tr>
<td></td>
<td>
<input type='button' name='logout' value='Logout' ng-click="logout()" class="button" />
</td>
</tr>
</form>
</table><br><br>
</td></tr></table></td></tr>
</table>
</div>
</div>
</div>
</div>
</body>
</html>


CODE 2.1: (controller.js)


function AdminCtrl($scope, $http) {
$scope.url = 'mainAPI.php'; // The url of our PHP API.
// alert(JSON.stringify($scope.userName));
// Create the http post request
// the data holds the keywords
// The request is a JSON request.
$http.post($scope.url, { "file" : "checkSession"}).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
// alert(data);
$scope.result = data; // Show result from server in our <pre></pre> element
if(data === 'success')
{
// $scope.message = "Session Exits";
}
else

$scope.message = "Session dose not exit..";
window.location.replace("index.html");
}
})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
$scope.logout = function() {
// alert(JSON.stringify($scope.userName));
// Create the http post request
// the data holds the keywords
// The request is a JSON request.$http.post($scope.url, { "file" : "logout"}).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
// alert(data);
$scope.result = data; // Show result from server in our <pre></pre> element


if(data == 'logedout')
{window.location.replace("index.html?logout=yes");
//$scope.validationErr = "Logged out successfully...";
}
else

$scope.message = "Some problem in logout admin..";
}

})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
}
$scope.sendmail = function() {
// alert(JSON.stringify($scope.userName));
// Create the http post request
// the data holds the keywords
// The request is a JSON request.$http.post($scope.url, { "file" : "sendmail"}).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
// alert(data);
$scope.result = data; // Show result from server in our <pre></pre> element
if(data == 'success')
{
$scope.message = "Mail sent successfully...";
}
else

$scope.message = "Some problem in sending mail..";
}
})
.
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
//alert("hello sendmail");
}
$scope.generateHTML = function() {
// alert(JSON.stringify($scope.userName));
// Create the http post request
// the data holds the keywords
// The request is a JSON request.$http.post($scope.url, { "file" : "generateHTML"}).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
alert(data);
$scope.result = data; // Show result from server in our <pre></pre> element

if(data == 'success')
{
$scope.message = "HTML generated successfully...";
}
else

$scope.message = "Some problem in generating HTML..";
}
}).
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
}
}

Session:
In above code, we sent http post request to 'mainAPI.php' page to check for sessions using $http.post($scope.url, { "file" : "checkSession"}) it will then return appropriate response flag for this request. If session exits it return success else user will be redircted to 'index.html' page.




   4. Send mail functionality with AngularJS:

In this, when admin clicks on send mail button, all respected mails must be sent to all respected email ids whos records exists into database. Mail must sent with all proper salary constraints calculations to employees. So when admin clicks on to sendMail button,$scope.sendmail = function()  (CODE 2.1) gets triggered and http post request is sent using $http.post($scope.url, { "file" : "sendmail"}) , so mainAPI.php page receives this post request and perform all calculations and send mails to all employees whos details exits into database.
Appropriate message is displayed based on response from mainAPI.php using

if(data == 'success')
{
    $scope.message = "Mail sent successfully...";
}
else
{
    $scope.message = "Some problem in sending mail..";
}

Note that we have line <pre ng-model="message" id="message"> {{message}} </pre> in 'admin.html' page to display this message.


   5. Generate HTML functionality with AngularJS:

In this, when admin clicks on generate HTML button, 'mainAPI.php' page will then generate all html reports for employees. For this, when admin clicks on generateHTML button$scope.generateHTML = function() gets triggered. and http post request is sent using $http.post($scope.url, { "file" : "generateHTML"}) , and based on response from 'mainAPI.php' page apropriate message will be displayed.


   6. Sign out functionality with AngularJS:

When user clicks on logout link, function $scope.logout = function()  gets called and $http.post($scope.url, { "file" : "logout"}). request is sent to 'mainAPI.php' page then it performs logout operation for admin using following code.

CODE 2.2: mainAPI.php

session_start(); $data = file_get_contents("php://input");
$objData = json_decode($data);
if ($objData->file == "logout") {
$_SESSION['empid']='';
session_destroy(); // destroy session data in storage
session_unset();
echo "logedout";
}

When admin is logged out, then I will return response "logedout" to $scope.logout = function()and then following codes gets executed.

if(data == 'logedout')
{
window.location.replace("index.html?logout=yes");
}
else
{
$scope.message = "Some problem in logout admin.."; 

}

Note that in above code, we have sent querystring to 'index.html' page using window.location.replace("index.html?logout=yes"); while redirection, this is done to show logged out success message on to 'index.html' page. In 'controller.js' file, we have written small javascript into login controller which gets called when 'index.html' page gets loaded.

//Following function reads querystring from URL. function getQueryVariable(variable) { 
var query = window.location.search.substring(1); 
var vars = query.split("&"); 
for (var i=0;i<vars.length;i++) { 
var pair = vars[i].split("="); 
if (pair[0] == variable) { 
return pair[1]; 
}


var log = getQueryVariable("logout"); //calling above function 'getQueryVariable'
if(log == 'yes')
{
$scope.validationErr = "You are successfully logged out."; //based on querystring flag appropriate message is displayed.
}


This functions reads querystring from url, and when it receives 'yes' after reading from url then message is displayed on to 'index.html' page saying 'You are successfully logged out.


  7. File upload functionality with AngularJS.

<script type="text/javascript"> function fileSelected() { 
var file = document.getElementById('sel_file').files[0]; 
if (file) { 
var fileSize = 0; 
if (file.size > 1024 * 1024) 
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB'; 
else 
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB'; 
document.getElementById('fileName').innerHTML = 'Name: ' + file.name; 
document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize; 
document.getElementById('fileType').innerHTML = 'Type: ' + file.type; 


function uploadFile() { 
var fd = new FormData(); 
fd.append("overwrite", document.getElementById('overwrite').checked); 
fd.append("sel_file", document.getElementById('sel_file').files[0]); 
var xhr = new XMLHttpRequest(); 
xhr.upload.addEventListener("progress", uploadProgress, false); 
xhr.addEventListener("load", uploadComplete, false); 
xhr.addEventListener("error", uploadFailed, false); 
xhr.addEventListener("abort", uploadCanceled, false); 
xhr.open("POST", "login.php"); 
xhr.send(fd); 

function uploadProgress(evt) { 
if (evt.lengthComputable) { 
var percentComplete = Math.round(evt.loaded * 100 / evt.total); 
document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%'; 

else { 
document.getElementById('progressNumber').innerHTML = 'unable to compute'; 




function uploadComplete(evt) { 
/* This event is raised when the server send back a response */ 
//alert("hello"); 
document.getElementById('message').innerHTML = evt.target.responseText; 
alert(evt.target.responseText); 

function uploadFailed(evt) { 
alert("There was an error attempting to upload the file."); 


function uploadCanceled(evt) { 
alert("The upload has been canceled by the user or the browser dropped the connection."); 

</script>
<form id="form1" enctype="multipart/form-data" method="post" action="Upload.aspx"> 
Import CSV File : 
<input type="file" name="sel_file" id="sel_file" onchange="fileSelected();"/> 
<input type="checkbox" id="overwrite" name="overwrite" checked="checked" value="Yes" />Overwrite 
<input type="button" onclick="uploadFile()" value="Upload" /> 
</form>


when user click on upload button uploadFile() javascript function gets called which performs functions for file uploading by creating XMLHttpRequest object and then sending post request to 'mainAPI.phppage, where file gets uploaded and apropriate message is returned and function uploadComplete(evt) displays this message see below code.

function uploadComplete(evt) { /* This event is raised when the server send back a response */ 
//alert("hello"); 
document.getElementById('message').innerHTML = evt.target.responseText; 
alert(evt.target.responseText); 
}



  8. Pagination.

             I have implemented pagination using twitter bootstrap code. Though we can implement our own css, I have used there css. Please see below HTML code to understand pagination properly. See yellow labels..

Code 3.0:

<html xmlns:ng="http://angularjs.org" ng-app="myApp" lang="en">
<head>
<meta charset="utf-8">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.no-icons.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/2.0/css/font-awesome.css" rel="stylesheet">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="http://code.angularjs.org/1.1.0/angular.min.js"></script>
<script src="cntrl.js"></script>
</head>
<body>
<script type="text/javascript">
var sortingOrder = 'fld_useremail';
</script>
</div>
<style>
.ctrlRead{
margin-left:auto;
margin-right:auto;
width:70%;
}
</style>
<br><br>
<div ng-controller="ctrlRead" class="ctrlRead">
<div class="input-append">Search:
<input type="text" ng-model="query" ng-change="search()" class="input-large search-query" placeholder="Search">
</div>
<table class="table table-striped table-condensed table-hover">
<thead>
<tr>
<th class="fld_id"><a ng-click="orderBy = 'fld_id'; sort_by('fld_id'); reverse=!reverse">Id <i class="icon-sort"></i></a></th>
<th class="fld_useremail"><a ng-click="orderBy = 'fld_useremail'; sort_by('fld_useremail'); reverse=!reverse">Email<i class="icon-sort"></i></a></th>
<th class="fld_password"><a ng-click="orderBy = 'fld_password'; sort_by('fld_password'); reverse=!reverse">Password<i class="icon-sort"></i></a></th>
<th class="fld_first_name"><a ng-click="orderBy = 'fld_first_name'; sort_by('fld_first_name'); reverse=!reverse">First name<i class="icon-sort"></i></a></th>
<th class="fld_last_name"><a ng-click="orderBy = 'fld_last_name'; sort_by('fld_last_name'); reverse=!reverse">Last name<i class="icon-sort"></i></a></th>
<th class="fld_type"><a ng-click="orderBy = 'fld_type'; sort_by('fld_type'); reverse=!reverse">Type<i class="icon-sort"></i></a></th>
</tr>
</thead>
<tfoot>
<td colspan="6">
<div class="pagination pull-right">
<ul>
<li ng-class="{disabled: currentPage == 0}">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li ng-repeat="n in range(pagedItems.length)"
ng-class="{active: n == currentPage}"
ng-click="setPage()">
<a href ng-bind="n + 1">1</a>
</li>
<li ng-class="{disabled: currentPage == pagedItems.length - 1}">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>
</td>
</tfoot>
<tbody>
<tr ng-repeat="item in filteredItems | orderBy:orderBy:reverse | startFrom:currentPage*pageSize | limitTo:pageSize"> 
<td>{{item.fld_id}}</td>
<td>{{item.fld_useremail}}</td>
<td>{{item.fld_password}}</td>
<td>{{item.fld_first_name}}</td>
<td>{{item.fld_last_name}}</td>
<td>{{item.fld_type}}</td>
</tr>
</tr>
</tbody>
</table>
</div>
</body>
</html>

      Code:
<input type="text" ng-model="query" ng-change="search()" class="input-large search-query" placeholder="Search"> 

Explanation:
see input 'text' for search, we have given model name 'query' for this search box using ng-model='query' , whenever user makes any change to this text box ng-change='search()' will cause call to search function which is defined inside 'cntrl.js' file.


      Code:
<th class="fld_id"><a ng-click="orderBy = 'fld_id'; sort_by('fld_id'); reverse=!reverse">Id <i class="icon-sort"></i></a></th>

       Explanation:
Above is table header, whever user clicks on this table header, its below column can be get sorted in both way ascending and descending.
When user clicks on this column header, ng-click is triggered, which pass current column name to 'orderBy' attribute. [ orderBy = 'fld_id'; ]
Also sortby() function is triggered, this function is defined inside 'cntrl.js' . This function displays appropriate icons(ascending,descending) near appropriate table header name. It accepts column name, to display icons near to it. [ sort_by('fld_id'); ]
Always set reverse attribute of table header column to false, all this values are used inside controller.[ reverse=!reverse" ]

Code:
<tr ng-repeat="item in filteredItems | orderBy:orderBy:reverse | startFrom:currentPage*pageSize | limitTo:pageSize">

Explanation:
ng-repeat will repeat this row until size of filtereditmes, item variable from ng-repeat="item in filteredItems take values from filtereditmes array, and then it display it using
<td>{{item.fld_id}}</td>
<td>{{item.fld_useremail}}</td>
<td>{{item.fld_password}}</td>
<td>{{item.fld_first_name}}</td>
<td>{{item.fld_last_name}}</td>
<td>{{item.fld_type}}</td>

This filtereditems is obtained from cntrl.js , where it is fetched from datbase and then returned using json response object.

| orderBy:orderBy:reverse | : In this , we are passing reverse parameter to orderBy, which is set and assigned dynamically while sorting.

| startFrom:currentPage*pageSize | limitTo:pageSize" :  This indicates, pagination start point to pagination end point. (Note that, currentPage, pageSize will be obtained from 'cntrl.js' file)

Code:


<div class="pagination pull-right">
<ul>
<li ng-class="{disabled: currentPage == 0}">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li ng-repeat="n in range(pagedItems.length)"
ng-class="{active: n == currentPage}"
ng-click="setPage()">
<a href ng-bind="n + 1">1</a>
</li>
<li ng-class="{disabled: currentPage == pagedItems.length - 1}">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>

Explanation:
Above code displays page number along with next and previos buttons.
Now, we will see cntrl.js file:

Code 3.1: cntrl.js

var app=angular.module('myApp', []);
function ctrlRead($scope, $http ,$filter) {
// init
$scope.sortingOrder = sortingOrder;
$scope.reverse = false;
$scope.filteredItems = [];
$scope.groupedItems = [];
$scope.itemsPerPage = 5;
$scope.pagedItems = [];
$scope.currentPage = 0;
$scope.pageSize = 0;
$scope.contentData = [];

$scope.url = 'content.php'; // The url of our search
$http.get("content.php").success( function( data ) {
$scope.items = data;
var searchMatch = function (haystack, needle) {
if (!needle) {
return true;
}
return haystack.toLowerCase().indexOf(needle.toLowerCase()) !== -1;
};
// init the filtered items
$scope.search = function () {
$scope.filteredItems = $filter('filter')($scope.items, function (item) {
for(var attr in item) {
if (searchMatch(item[attr], $scope.query))
return true;
}
return false;
});
// take care of the sorting order
if ($scope.sortingOrder !== '') {
$scope.filteredItems = $filter('orderBy')($scope.filteredItems, $scope.sortingOrder, $scope.reverse);
}
$scope.currentPage = 0;
// now group by pages
$scope.groupToPages();
};
// calculate page in place
$scope.groupToPages = function () {
$scope.pagedItems = [];
for (var i = 0; i < $scope.filteredItems.length; i++) {
if (i % $scope.itemsPerPage === 0) {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)] = [ $scope.filteredItems[i] ];
} else {
$scope.pagedItems[Math.floor(i / $scope.itemsPerPage)].push($scope.filteredItems[i]);
}
}
$scope.pageSize = $scope.pagedItems.length;
};
$scope.range = function (start, end) {
var ret = [];
if (!end) {
end = start;
start = 0;
}
for (var i = start; i < end; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function () {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.nextPage = function () {
if ($scope.currentPage < $scope.pagedItems.length - 1) {
$scope.currentPage++;
}
;
$scope.setPage = function () {
$scope.currentPage = this.n;
};
// functions have been describe process the data for display
$scope.search();
// change sorting order
$scope.sort_by = function(newSortingOrder) {
// icon setup 
$('th i').each(function(){
// icon reset
$(this).removeClass().addClass('icon-sort');
});
if ($scope.reverse)
{
$('th.'+newSortingOrder+' i').removeClass().addClass('icon-chevron-up');
}
else
{
$('th.'+newSortingOrder+' i').removeClass().addClass('icon-chevron-down');
}
};
});
};
//ctrlRead.$inject = ['$scope', '$http','$filter'];
app.filter('startFrom', function() {
return function(input, start) {
//alert('shri'+input+"start"+start);
start = +start; //parse to int
return input.slice(start);
}
});

Explanation:
Here, we have namespaced module name using

var app=angular.module('myApp', []);

This 'myapp' name, we already written inside (Code 3.0) in line
<html xmlns:ng="http://angularjs.org" ng-app="myApp" lang="en">

This line, <div ng-controller="ctrlRead" class="ctrlRead"> , tells which controller to be loaded so when this page gets called function ctrlRead($scope, $http ,$filter) starts execution, and $http.get("content.php").success( function( data ) request is sent to retrive data from database. As this request is asynchronous (i.e. code dose not wait for request to get complete and starts executing code below it.) , I was always getting null response due to value(null) was getting displayed before http request gets completed.
So to make it synchronous, I am used pagination logic after response from server (i.e. content.php page.)

In above Code 3.1, you can see all pagination logic exists between thes two lines

$http.get("content.php").success( function( data ) {
///Some code....
}

It displays data upto given given limit ( i.e. $scope.itemsPerPage = 5; // 5 itmes per page )
when ever user clicks on next or previous buttons, appropriate functions gets called i.e.

$scope.prevPage = function () { //some code..}
$scope.nextPage = function () { //some code..}
$scope.setPage = function () { //some code..}

And this $scope.sort_by = function(newSortingOrder) { //some code..} gets called when user clicks on column header to display apropriate ascending and descending icons.
Whenever user makes any change to search text box, function $scope.search = function () { //some code} gets called, then it finds given keywords from an array and displays result on browser.
$scope.groupToPages = function () { //some code } gets called from search function, it is used to group pages and count total pages(pageSize).
$scope.range = function (start, end) { //some code } This function gets called from html Code 3.0 to display page numbers on browser.





...................................................END.................................................................





7 comments:

  1. Replies
    1. Ganesh thanks...i hope it will help you.

      Delete
  2. Nice article for Newbie.........

    ReplyDelete
    Replies
    1. Hey thanks hari...i was waiting to here from you..thanks

      Delete
  3. HI,
    nice post.can you help me how to do server side pagination using angularjs

    ReplyDelete
  4. Hi Hemant, sorry for late reply.
    Example, which i have explained above contains sever side pagination only ( i.e. data returned by server-side after calling service). This data you can collect in JSON object and then using "ng-repeat" directive, you can iterate and play with any element of that object.

    ReplyDelete
  5. Elevate your online presence with our cutting-edge Australian data center! Enjoy reliable hosting services for your business needs.

    ReplyDelete