Paginate an AngularJS data table - javascript

I have gathered some JSON (dummy) data in a users table.
var root = 'https://jsonplaceholder.typicode.com';
// Create an Angular module named "usersApp"
var app = angular.module("usersApp", []);
// Create controller for the "usersApp" module
app.controller("usersCtrl", ["$scope", "$http", function($scope, $http) {
var url = root + "/users"
$http.get(url)
.then(function(data) {
$scope.users = data.data;
});
}]);
.search-box {
margin: 5px;
}
.panel-heading {
font-weight: bold;
}
.table-container .panel-body {
padding: 0;
}
.table-container table tr th {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="container" data-ng-app="usersApp">
<div class="panel panel-default table-container">
<div class="panel-heading">Users</div>
<div class="panel-body" data-ng-controller="usersCtrl">
<div class="row">
<div class="col-sm-12">
<div class="form-group search-box">
<input type="text" class="form-control" id="search" placeholder="Search User" data-ng-model="search">
</div>
</div>
<div class="col-sm-12">
<table class="table table-striped" id="dataTable">
<thead>
<tr>
<th>Full name</th>
<th>Email</th>
<th>City</th>
<th>Street</th>
<th>Suite</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="user in users|filter:search">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td>{{user.address.city}}</td>
<td>{{user.address.street}}</td>
<td>{{user.address.suite}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
The table has only 10 rows but, in a real-world app, there is a lot more data to manage so it needs to be paginated. The above one could have 3 rows per page (except the 4th one, which should have one).
Question(s):
Does AngularJS have a built-in, easy way to paginate such a table?
If not, what are the best alternatives?

Angularjs don't have built-in pagination feature. You have to use some third-party modules like angular-ui-grid. OR you can try this <https://codepen.io/khilnani/pen/qEWojX>

You can use ngInfiniteScroll for pagination. https://sroze.github.io/ngInfiniteScroll/

Related

Load Data from Database Without Blinking Angular Js

Am loading data from database to a table in html with angualar js. am also using interval so as to make the table reload every 10 seconds to get new data that has just been inputed by other users.
Problem:
The table blinks every time it reloads. making the page look funny like it has a glitch.
What am looking for:
Is there a way i can make the new data just slide in from the top of the table and become number one while the rest re adjust underneath it And become number two, three and so on. i was made to believe Angular Js is magical reason why i opted for it instead of using my usual AJAX
Angular Code
var supDetails = angular.module("supDetails", ['datatables']);
supDetails.controller('supportController', function($scope, $http, $interval) {
$scope.names = [];
$scope.isFirst = true;
$scope.loadData = function() {
var httpRequest = $http({
method: 'GET',
url: 'anfil.php?ins=sup'
}).success(function(data, status) {
console.log('loading..');
$scope.names = data;
if(!$scope.isFirst){
angular.forEach(data,function(key,val){
$scope.names[key] = data[key];
});
}
$scope.isFirst = false;
});
};
$scope.loadData();
// Function to replicate setInterval using $timeout service.
$interval(function () {
$scope.loadData();
}, 10000);
});
My HTML
<!-- /.col -->
<div class="col-md-9" ng-app = "supDetails" ng-controller="supportController">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">Messages</h3>
<!-- /.box-tools -->
<div class="box-tools pull-right">
<div class="has-feedback">
<button type="button" ng-click="loadData()" class="btn btn-default btn-sm"><i class="fa fa-refresh"></i></button>
</div>
</div>
</div>
<!-- /.box-header -->
<div class="box-body no-padding">
<div class="mailbox-messages">
<table datatable="ng" class="table table-hover table-striped">
<thead>
<tr>
<th>Stat</th>
<th>Name</th>
<th>Problem</th>
<th>Time</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in names">
<td class="mailbox-star"><i class="fa fa-circle text-blue"></i></td>
<td class="mailbox-name">{{x.user_id}}</td>
<td class="mailbox-subject"><b>{{x.ticket_title}}</b> - {{x.subject}}
</td>
<td class="mailbox-date">{{x.ticket_open_date}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Stat</th>
<th>Name</th>
<th>Problem</th>
<th>Time</th>
</tr>
</tfoot>
</table>
<!-- /.table -->
</div>
<!-- /.mail-box-messages -->
</div>
<!-- /.box-body -->
</div>
<!-- /. box -->
</div>
<!-- /.col -->
I think its your css problem which doesn't have a minimum height as you can see in this snippet its not blinking..
If you still want data to appear slide from up to down, You can uncomment the code in the answer, in this way it will remove row one by one from the table and replace it with the new one.
var app = angular.module('myApp', []);
function PeopleCtrl($scope, $http,$interval) {
$scope.people = [];
$scope.isFirst = true;
$scope.loadPeople = function() {
var httpRequest = $http({
method: 'GET',
url: 'https://jsonplaceholder.typicode.com/users'
}).success(function(data, status) {
console.log('loading..');
$scope.people = data;
/* if(!$scope.isFirst){
angular.forEach(data,function(val,key){
$scope.people[key] = data[key];
});
}
$scope.isFirst = false;*/
});
};
$scope.loadPeople();
$interval(function () {
$scope.loadPeople();
}, 10000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<div ng-app="myApp">
<div ng-controller="PeopleCtrl">
<table class="table">
<tr>
<th>Id</th>
<th>Name</th>
<th>UserNmae</th>
</tr>
<tr ng-repeat="person in people">
<td>{{person.id}}</td>
<td>{{person.name}}</td>
<td>{{person.username}}</td>
</tr>
</table>
</div>
</div>
There are a few ways to solve your problems:
1) Write algorithm, that load your data then compare it with existing data. If there any diffs you, should add just new records to your table.
2) Use WebSockets, they will give you ability to get from server only new records in real-time.

Why "Uncaught ReferenceError: populateDetailsForEditForm is not defined" is coming # frontend?

This code is in one of my JS file, gatewayList.js. In this file I have the following function:
function loadDetailsForEdit(data){
editGatewayDialog = BootstrapDialog.show({
title: 'Edit Gateway',
cssClass: 'modified-dialog',
closeByBackdrop: false,
closeByKeyboard: false,
onshow: function(dialog) {
populateDetailsForEditForm(data);
},
message: $('<div></div>').load(EDIT_FORM),
});
}
The above function calls populateDetailsForEditForm(data).
This function is defined in another JS file, whose name is editGateway.js
function populateDetailsForEditForm(gateway) {
$('#editForm').show();
$('#remarks').val(gateway.remarks);
}
But server can not find this editGateway.js file from gatewayList.js file. it's giving this following error in the chrome browser:
Uncaught ReferenceError: populateDetailsForEditForm is not defined
list.html
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 dataGridTitle">
Recent Gateway List
</div>
<div class="col-xs-12" style="border: 1px solid #ADADAD; padding-top:10px">
<table id="gatewayGrid" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Gateway Id</th>
<th>Gateway Name</th>
<th>Issuing Country</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
<script src="/administration/gateway/controller/editGateway.js"></sc‌​ript>
<script src="/administration/gateway/controller/gatewayList.js"></sc‌​ript>

the passed value didn't show on my popup window using angularjs and bootstrap

using angularjs and bootstrap,
I am tring to edit the table row as popup window but I couldn't pass the edite fields to the window
this is my code
controller.js
this.openUser = function(row) {
$scope.user = row;
var userInstance = $uibModal
.open({
animation : $scope.animationsEnabled,
templateUrl : './user_model',
controller : 'userModelController',
backdrop : true,
windowClass: 'monitoring-modal',
resolve : {
row: function () {
return row;
}
}
});
};
and this is my modal controller
angular.module('users').controller('userModelController', ['$scope', 'row',
function($scope ,row) {
this.row = row
} ]);
and this is my popup window html
<div class="modal-header">
<h3 class="modal-title">Users</h3>
</div>
<div class="modal-body">
<table class="table table-bordered" style="height: 350px; border-collapse:collapse;">
<thead>
<tr class="modal-body">
<th class="col-md-1" style="text-align: center; vertical-align: middle;"> {{ row }} </th>
<th class="col-md-1" style="text-align: center; vertical-align: middle;"> last name </th>
</thead>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
but what I get in my window is blank value
You have set the row on this.
Try setting the row on $scope.
$scope.row = row;
I haven't used ui-bootstrap modal lately, but I don't think it supports controllerAs syntax. At least not with your current configurations.
EDIT: Turns out, it does support controllerAs syntax: https://stackoverflow.com/a/23806963/841804
And even if it does support it, you should then be binding to <controler-as-name>.row, shouldn't you?

Angular Bootstrap UI - Only collapsing one element

I am using the angular bootstrap UI library:
https://angular-ui.github.io/bootstrap/
to create a collapsable feature on my site. The functionality itself is working, but it will expand/collapse every element I have the collapse feature on, instead of just the unique element that is clicked.
Here is my code:
var app = angular.module('someApp', ['ui.bootstrap']);
app.controller('collapseController', ['$scope', function ($scope) {
$scope.isCollapsed = true;
};
.passInfoDropdown {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 5px;
font-weight: bold;
}
.dividerLine {
background-color: #DED7CF;
height: 2px;
}
.passInfoTableCellLeft {
width: 220px;
}
<div class="dividerLine"></div>
<div class="click" ng-click="isCollapsed = !isCollapsed">
<table>
<tr>
<td class="passInfoTableCellLeft"><div class="passInfoDropdown inline">TSA Information (optional)</div></td>
<td><i class="fa fa-chevron-down inline"></i></td>
</tr>
</table>
<div collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
<div class="dividerLine"></div>
<div class="click" ng-click="isCollapsed = !isCollapsed">
<table>
<tr>
<td class="passInfoTableCellLeft"><div class="passInfoDropdown inline">Loyalty Programs (optional)</div></td>
<td><i class="fa fa-chevron-down inline"></i></td>
</tr>
</table>
<div collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
How can I make it so just the unique element i click collapses?
At the moment both isCollapsed refer to the same propertie on your $scope object. If you want those to be separed, I see two options.
Two properties in the scope
$scope.isCollapsedContent1 = true;
$scope.isCollapsedContent2 = true;
or
$scope.isCollapsed = {};
$scope.isCollapsed['content1'] = true;
$scope.isCollapsed['content2'] = true;
Two ng-model
If you do not need to know whether the content is collapsed or not in your controller, you might as well put the isCollapsed value into your html and remove the propertie of your $scope.
<div class="click" ng-click="isCollapsedContent1 = !isCollapsedContent1" ng-model="isCollapsedContent1" ng-init="isCollapsedContent1=true">
Brandon, HI there. It also looks (in the full snippet code) like you have left out these....
<html ng-app="ui.bootstrap.demo">
and
<div ng-controller="CollapseDemoCtrl">
Have a look at the working Fiddle.

Angular ng-click load controller

I'm trying to practice angular and I'm stuck this this.
How do I make ng-click load the displayController? Or am I doing this wrong way?
The Angular
var bible = angular.module('bible', []);
// Load the Books
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$http.get('books.json').success(function(data) {
$scope.books = data
});
}]);
bible.controller('displayController', function($scope) {
$scope.test = "TEST TEXT";
});
The HTML
<div class="row">
<div class="col-md-12" ng-controller="listController">
<table class="table">
<thead>
<th>Testament</th>
<th>Title</th>
<th>Chapters</th>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{book.testament}}</td>
<td>{{book.title}}</td>
<td>{{book.chapters}}</td>
</tr>
</tbody>
</table>
<div class="display-book" ng-controller="displayController">
{{test}}
</div>
</div>
</div>
You don't need the additional controller there. I guess you want to display additional infos about the clicked book.
Use a reference and ngIf
var bible = angular.module('bible', []);
// Load the Books
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$scope.selectedBook = null;
$http.get('books.json').success(function(data) {
$scope.books = data
});
}]);
And html:
<div class="row">
<div class="col-md-12" ng-controller="listController">
<!-- will be shown, as long as not book is selected -->
<table data-ng-if="selectedBook == null" class="table">
<thead>
<th>Testament</th>
<th>Title</th>
<th>Chapters</th>
</thead>
<tbody>
<tr ng-repeat="book in books">
<td>{{book.testament}}</td>
<td>{{book.title}}</td>
<td>{{book.chapters}}</td>
</tr>
</tbody>
</table>
<!-- will be shown, when a book got selected -->
<div data-ng-if="selectedBook != null" class="display-book">
<!-- display the selection table again -->
<button data-ng-click="selectedBook = null">Back</button>
{{selectedBook.title}}
</div>
</div>
</div>
Why do you want to call a separate controller cant you implement the functionality in a separate function like below ,
bible.controller('listController', ['$scope', '$http', function($scope, $http) {
$http.get('books.json').success(function(data) {
$scope.books = data
});
$scope.display = function(){
// **YOUR CODE COMES HERE**
}
}]);
<td>{{book.title}}</td>

Categories

Resources