what I'm I doing wrong here? I'm trying to render a table using angular but the table shows empty, with {{ place.id}} , {{ place.name}} and {{ place.social}} where the data should be.
<head>
<title>Angular JS </title>
<script src="http://code.angularjs.org/1.4.8/angular.js"></script>
<script src="http://code.angularjs.org/1.4.8/angular-resource.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
<script>
var app = angular.module('MyForm', ['ui.bootstrap', 'ngResource']);
app.controller('myCtrl', function ($scope, $http) {
$http.get('http://passarola.pt/api/places').success(function(data) {
$scope.predicate = 'id';
$scope.reverse = true;
$scope.currentPage = 1;
};
$scope.order = function (predicate) {
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
$scope.predicate = predicate;
};
$scope.totalItems = $scope.places.length;
$scope.numPerPage = 5;
$scope.paginate = function (value) {
var begin, end, index;
begin = ($scope.currentPage - 1) * $scope.numPerPage;
end = begin + $scope.numPerPage;
index = $scope.places.indexOf(value);
return (begin <= index && index < end);
};
});
</script>
</head>
<body ng-app="MyForm">
<div ng-controller="myCtrl">
<div class="container-fluid">
<pre>Passarola Beer</pre>
<hr />
<table class="table table-striped">
<thead>
<tr>
<th class="media_gone">
ID
</th>
<th> Name </th>
<th>Social Media </th>
</tr>
</thead>
<tbody>
<tr>
<td class="media_gone2"> <input type="text" ng-model="search.id" /></td>
<td> <input type="text" ng-model="search.name" /> </td>
</tr>
<tr ng-repeat="place in places | orderBy:predicate:reverse | filter:paginate| filter:search" ng-class-odd="'odd'">
<td>{{ place.id}}</td>
<td>{{ place.name}}</td>
<td class="gender_gone">{{ place.social}}</td>
</tr>
</tbody>
</table>
<pagination total-items="totalItems" ng-model="currentPage"
max-size="5" boundary-links="true"
items-per-page="numPerPage" class="pagination-sm">
</pagination>
</div>
</div>
</body>
</html>
Example code:
var app = angular.module('MyForm', ['ui.bootstrap', 'ngResource']);
app.controller('myCtrl', function ($scope, $timeout) {
$scope.predicate = 'id';
$scope.reverse = true;
$scope.currentPage = 1;
$scope.order = function (predicate) {
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
$scope.predicate = predicate;
};
$scope.places = [
{ id: 'Kevin', name: 25, social: 'boy' },
{ id: 'John', name: 30, social: 'girl' },
{ id: 'Laura', name: 28, social: 'girl' },
{ id: 'Joy', name: 15, social: 'girl' },
{ id: 'Mary', name: 28, social: 'girl' },
{ id: 'Peter', name: 95, social: 'boy' },
{ id: 'Bob', name: 50, social: 'boy' },
{ id: 'Erika', name: 27, social: 'girl' },
{ id: 'Patrick', name: 40, social: 'boy' },
{ id: 'Tery', name: 60, social: 'girl' }
];
$scope.totalItems = $scope.places.length;
$scope.numPerPage = 5;
$scope.paginate = function (value) {
var begin, end, index;
begin = ($scope.currentPage - 1) * $scope.numPerPage;
end = begin + $scope.numPerPage;
index = $scope.places.indexOf(value);
return (begin <= index && index < end);
};
Use this controller code.
app.controller('myCtrl', function ($scope, $http) {
$scope.places = [];
$http.get('http://passarola.pt/api/places').success(function(data) {
$scope.places = data.data;
$scope.totalItems = $scope.places.length;
$scope.predicate = 'id';
$scope.reverse = true;
$scope.currentPage = 1;
};
$scope.order = function (predicate) {
$scope.reverse = ($scope.predicate === predicate) ? !$scope.reverse : false;
$scope.predicate = predicate;
};
$scope.numPerPage = 5;
$scope.paginate = function (value) {
var begin, end, index;
begin = ($scope.currentPage - 1) * $scope.numPerPage;
end = begin + $scope.numPerPage;
index = $scope.places.indexOf(value);
return (begin <= index && index < end);
};
});
Related
I'm using angularjs order by filter for sorting a json. As per the order of preference, lower case followed by the upper case but it is not working for single character. Can any one help in this to find out?
$scope.friends = [
{name: 'A'},
{name: 'a'},
{name: 'B'},
{name: 'b'},
{name: 'C'},
{name: 'c'}
];
<table class="friends">
<tr>
<th>Name</th>
</tr>
<tr ng-repeat="friend in friends | orderBy:'name'">
<td>{{friend.name}}</td>
</tr>
</table>
The result :
Name
====
A
a
B
b
C
c
Try this solution only for single characters:
angular.module('app', []).controller('MyController', ['$scope', function($scope) {
$scope.friends = [
{name: 'A'},
{name: 'a'},
{name: 'B'},
{name: 'b'},
{name: 'C'},
{name: 'c'}
];
}]).filter('customOrderBy', function(){
return function(input, name)
{
var result = []
for(var item of input)
{
var prop = item[name];
var toUpper = prop.toUpperCase().charCodeAt(0);
result.push({item, code: toUpper + (prop.toLowerCase() == prop ? 0 : 1)});
}
return result.sort(function(a, b){return a.code > b.code ? 1 : (a.code == b.code ? 0 : -1);}).map(function(x) { return x.item; });
}
})
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<body ng-app="app">
<div ng-controller="MyController">
<table class="friends">
<tr>
<th>Name</th>
</tr>
<tr ng-repeat="friend in friends | customOrderBy: 'name'">
<td>{{friend.name}}</td>
</tr>
</table>
</div>
</body>
can you try this custom filter as like below?
<body ng-app="MyApp">
<div ng-controller="MyCtrl">
<table class="friends">
<tr>
<th>Name</th>
</tr>
<tr ng-repeat="friend in friends | localeOrderBy:'name'">
<td>{{friend.name}}</td>
</tr>
</table>
</div>
</body>
app.filter("localeOrderBy", [function () {
return function (array, sortPredicate, reverseOrder) {
if (!Array.isArray(array)) return array;
if (!sortPredicate) return array;
var isString = function (value) {
return (typeof value === "string");
};
var isNumber = function (value) {
return (typeof value === "number");
};
var isBoolean = function (value) {
return (typeof value === "boolean");
};
var arrayCopy = [];
angular.forEach(array, function (item) {
arrayCopy.push(item);
});
arrayCopy.sort(function (a, b) {
var valueA = a[sortPredicate];
var valueB = b[sortPredicate];
if (isString(valueA))
return !reverseOrder ? valueA.localeCompare(valueB) : valueB.localeCompare(valueA);
if (isNumber(valueA) || isBoolean(valueA))
return !reverseOrder ? valueA - valueB : valueB - valueA;
return 0;
});
return arrayCopy;
}
}]);
I have pulled data from json file. Now its displayed over DOM.
On HTML Page, I have three option 1) Edit Data 2) Delete Particular Data & 3) Add New Data.
How to perform this using AngularJS Code? i.e. on editing name, it should update my JSON object. On Deleting row, it should delete that row in JSON data. and also If I click on Add New, then entered data will be added to JSON.
My Code is as below.
Importing data through json file and displaying on DOM
.controller('MainCtrl', function ($scope, $http) {
$http.get('data/home.json').
success(function(data, status, headers, config) {
$scope.details = data;
}).
error(function(data, status, headers, config) {
// log error
});
});
Output of this code is correct as below image.
JSON Object as below.
{
"status":"success",
"adformat":[
{
"adformat_id":1,
"name":"Format 1",
"size":"300x250"
},
{
"adformat_id":2,
"name":"Format 2",
"size":"320x250"
},
{
"adformat_id":3,
"name":"Format 3",
"size":"320x480"
}
]
}
I would do it like this:
MainCtrl.js
(function () {
'use strict';
angular
.module('app')
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', 'MainFactory'];
function MainCtrl($scope, MainFactory) {
$scope.details = MainFactory.details;
function init() {
MainFactory.get();
}
init();
$scope.detailsModel = {
"adformat_id": 1,
"name": "Format 1",
"size": "300x250"
};
$scope.add = function () {
$scope.details.push($scope.detailsModel);
};
$scope.delete = function (index) {
$scope.details.splice(index, 1);
};
$scope.edited = -1;
$scope.editedModel = {
"adformat_id": 0,
"name": "",
"size": ""
};
$scope.edit = function (index) {
$scope.edited = index;
};
$scope.finishEdit = function (index) {
$scope.details[index] = $scope.editedModel;
$scope.edited = -1;
};
}
})();
MainFactory.js
(function () {
'use strict';
angular
.module('app')
.factory('MainFactory', MainFactory);
MainFactory.$inject = [];
function MainFactory() {
var self = this;
self.details = [];
self.get = $http.get('data/home.json')
.then(function (response) {
self.details = response.data;
}).catch(function (error) {
// log error
});
return self;
}
})();
index.html
<div ng-app="app">
<div ng-controller="MainCtrl">
<table>
<tbody>
<tr ng-repeat="details in detail">
<!-- show-->
<td ng-hide="edited === $index">{{detail.adformat_id}}</td>
<td ng-hide="edited === $index">{{detail.name}}</td>
<td ng-hide="edited === $index">{{detail.size}}</td>
<td ng-hide="edited === $index">
<button ng-click="edit($index)">Edit</button>
<button ng-click="delete($index)">Detele</button>
</td>
<!-- Edit-->
<td ng-show="edited === $index">{{detail.adformat_id}}</td>
<td ng-show="edited === $index"><input type="text" ng-model="editedModel.name"></td>
<td ng-show="edited === $index"><input type="number" ng-model="editedModel.size"></td>
<td ng-show="edited === $index">
<button ng-click="finishEdit($index, editedModel)">Save</button>
<button ng-click="delete($index)">Detele</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
<button ng-click="add()">Add</button>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
It is just prototype, not tested, but it should help you to understand idea o two way binding in angular.
Here is my approach to this requirement. Let me know if any further improvement can be added. The entire code can be found at the below URL:
Angular Save, Update and Delete
The sample screenshots from the code can be found here...
controller:
'use strict';
function MainController($scope, SharedService, ngDialog) {
$scope.account_type_selected = "Savings";
$scope.sharedService = SharedService;
$scope.savingsMain = [];
$scope.checkingsMain = [];
$scope.addToCheckingsAccounts = {};
$scope.addToSavingsAccounts = {};
$scope.setAccountType = function (type) {
if (type === "allAccounts") {
$scope.showSavings = true;
$scope.showCheckings = true;
} else if (type === "savingsAccounts") {
$scope.showSavings = true;
$scope.showCheckings = false;
} else if (type === "checkingAccounts") {
$scope.showSavings = false;
$scope.showCheckings = true;
}
$scope.account_type_selected = type;
};
$scope.$watch('savingsMain', function ($scope) {
return $scope.savingsMain;
});
$scope.selectedAccountType = function (showAccount) {
console.log(showAccount);
if (showAccount === "Savings") {
$scope.sharedService.accountType = "Savings";
} else {
$scope.sharedService.accountType = "Checkings";
}
};
$scope.saveAccounts = function () {
if ($scope.sharedService.accountType === "Savings") {
$scope.addToSavingsAccounts = {
"account_type": $scope.sharedService.accountType,
"amount": $scope.sharedService.amount,
"date": $scope.sharedService.date,
"maturity": $scope.sharedService.maturity
};
$scope.showSavings = true;
$scope.savingsMain.push($scope.addToSavingsAccounts);
} else {
$scope.addToCheckingsAccounts = {
"account_type": $scope.sharedService.accountType,
"amount": $scope.sharedService.amount,
"bic": $scope.sharedService.BIC,
"iban": $scope.sharedService.IBAN
};
$scope.showCheckings = true;
$scope.checkingsMain.push($scope.addToCheckingsAccounts);
}
ngDialog.close();
};
$scope.deleteDataFromSharedService = function (accountType, item) {
if (accountType === "Savings") {
$scope.savingsMain = _.without($scope.savingsMain, _.findWhere($scope.savingsMain, { date: item }));
} else if (accountType === "Checkings") {
$scope.checkingsMain = _.without($scope.checkingsMain, _.findWhere($scope.checkingsMain, { bic: item }));
}
};
$scope.closeDialog = function () {
ngDialog.close();
};
$scope.accountTypeModel = [];
$scope.prop = {
"type": "select",
"name": "account_type",
"value": $scope.sharedService.accountType,
"accountTypeData": ["Savings", "Checkings"]
};
}
<form ng-controller="MainController">
<div class="page-header">
<h1>Angular-Save-Update-Delete</h1>
</div>
<div class="content-wrapper">
<div class="sidebar">
<table>
<tbody>
<tr>
<td>
<button ng-click="setAccountType('allAccounts')" ng-model="allAccounts" class="ng-pristine ng-untouched ng-valid ng-empty">All</button>
</td>
</tr>
<tr>
<td>
<button ng-click="setAccountType('savingsAccounts')" ng-model="savingsMain" class="ng-pristine ng-valid ng-not-empty ng-touched">Savings</button>
</td>
</tr>
<tr>
<td>
<button ng-click="setAccountType('checkingAccounts')" ng-model="checkingsMain" class="ng-pristine ng-untouched ng-valid ng-not-empty">Checkings</button>
</td>
</tr>
<tr>
<td>
<button class="create-account-btn-class"
type="button"
ng-dialog="app/views/create-account-template.html"
ng-dialog-data=""
ng-dialog-class="ngdialog-theme-default"
ng-dialog-scope="this"
plain=false
showClose=true
closeByDocument=true
closeByEscape=true
ng-dialog-show-close="false">New Account</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="right-content">
<div id="savingsTemplate" templateurl="app/views/savings.html" ng-show="showSavings" include-template=""></div>
<div id="checkingsTemplate" templateurl="app/views/checkings.html" ng-show="showCheckings" include-template=""></div>
</div>
</div>
</form>
I 'm a beginner in AngularJS. I have created a page that retrieves records from database along with total records using an Ajax call. After populating the grid with the records, I wanted to refresh the pager control based on values received from the Ajax call such as the total records and the current page number as 1. I'm seeing the pager but is not refreshed. Can you please verify and let me know what I'm missing here?
var angularPersonModule = angular.module("angularPersonModule", ['ui.bootstrap']);
angularPersonModule.controller("AngularPersonController", AngularPersonController);
angularPersonModule.controller("PaginationController", PaginationController);
angularPersonModule.factory("PaginationService", PaginationService);
PaginationController.$inject = ['$scope', '$timeout', '$rootScope', 'PaginationService'];
function PaginationController($scope, $timeout, $rootScope, PaginationService) {
$scope.setPage = function(pageNo) {
if ($scope.currentPage === pageNo) {
return;
}
$scope.currentPage = pageNo;
$rootScope.$broadcast("personPageChanged", $scope.currentPage);
alert("call from setPage");
};
$scope.pageChanged = function() {
var i = 0;
};
$scope.$on('personRefreshPagerControls', function(event, args) {
//the solution:
setTimeout(function() {
//setTimeout is a deffered call (after 1000 miliseconds)
$timeout(function() {
$scope.totalItems = PaginationService.getTotalRecords();
$scope.currentPage = PaginationService.getPageNumber();
$scope.itemsPerPage = PaginationService.getPageSize();
$scope.numPages = PaginationService.getPageCount();
alert("totalItems = " + $scope.totalItems);
alert("currentPage = " + $scope.currentPage);
alert("itemsPerPage = " + $scope.itemsPerPage);
alert("pageCount = " + $scope.numPages);
});
}, 900);
});
}
AngularPersonController.$inject = ['$scope', '$rootScope', 'AngularPersonService', 'PaginationService'];
function AngularPersonController($scope, $rootScope, AngularPersonService, PaginationService) {
$scope.getAll = function() {
$scope.persons = AngularPersonService.search();
PaginationService.setTotalRecords(3);
PaginationService.setPageNumber(1);
PaginationService.setPageSize(2);
PaginationService.setPageCount(2);
$rootScope.$broadcast("personRefreshPagerControls", 3);
}
$scope.$on('personPageChanged', function(event, args) {
alert("pageChanged Event fired");
alert("Received args = " + args);
$scope.getAll();
});
$scope.getAll();
}
function PaginationService() {
var currentPage = 1;
var pageCount = 2;
var pageSize = 2;
var totalRecords = 3;
return {
getPageNumber: function() {
return currentPage;
},
setPageNumber: function(pageNumber) {
currentPage = pageNumber;
},
getPageSize: function() {
return pageSize;
},
setPageSize: function(newPageSize) {
pageSize = newPageSize;
},
getTotalRecords: function() {
return totalRecords;
},
setTotalRecords: function(newTotalRecords) {
totalRecords = newTotalRecords;
},
getPageCount: function() {
return pageCount;
},
setPageCount: function(newPageCount) {
pageCount = newPageCount;
}
}
}
angularPersonModule.factory("AngularPersonService", function($http) {
return {
search: function() {
return [{
"Name": "Hemant"
}, {
"Name": "Ashok"
}, {
"Name": "Murugan"
}];
}
}
});
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-resource.min.js"></script>
<script src="https://raw.github.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-0.14.3.js"></script>
<script src="https://raw.githubusercontent.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-0.14.3.js"></script>
<div ng-app="angularPersonModule">
<div class="panel panel-default">
<div class="panel-body" ng-controller="AngularPersonController">
<table class="table table-striped table-hover">
<thead>
<tr>
<th class="col-md-3">
Name
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in persons">
<td>
<span>{{person.Name}}</span>
</td>
</tbody>
</table>
</div>
</div>
<div ng-controller="PaginationController">
<uib-pagination total-items="totalItems" ng-model="currentPage" ng-change="pageChanged()"></uib-pagination>
</div>
</div>
Update
Now I have updated the snippet so that you can execute and see the result manually.
In my angular js project factory is not providing values to the controller as needed. I always get empty result in view. When i logged in browser using console.log() all i can see in console is :
[object Object],[object Object],[object Object]. I am stuck at this. Tried many things but nothing worked.
This is my controller code:
var controllers = {};
controllers.ProductController = function ($scope, $route, $routeParams, $location, ProductFactory) {
$scope.products = [];
var init = function () {
$scope.products = ProductFactory.getProducts();
console.log('got products in controller');
console.log($scope.products)
};
var initProductEdit = function () {
var code = $routeParams.code;
if (code = undefined) {
$scope.currentProduct = {};
}
else
{
$scope.currentProduct = ProductFactory.loadProductByCode(code);
}
};
$scope.$on('$viewContentLoaded', function () {
var templateUrl = $route.current.templateUrl;
if (templateUrl == '/Partials/ProductEdit.html') {
initProductEdit();
}
else if (templateUrl == '/Partials/ProductList.html')
{
var code = $routeParams.code;
if(code!=undefined)
{
$scope.deleteProduct(code);
}
}
});
init();
$scope.saveProduct = function () {
ProductFactory.saveProduct($scope.currentProduct);
$location.search('code', null);
$location.path('/');
};
$scope.deleteProduct = function (code) {
ProductFactory.deleteProduct(code);
$location.search('code', null);
$location.path('/');
};
};
angSPA.controller(controllers);
This is my factory code:
angSPA.factory('ProductFactory', function () {
var products = [
{ code: 1, name: 'Game of Thrones', description: 'Series' }
{ code: 2, name: 'DmC', description: 'Game' },
{ code: 3, name: 'Matrix', description: 'Movie' },
{ code: 4, name: 'Linkin Park', description: 'Music Band' }];
var factory = {};
console.log('initializing factory');
factory.getProducts = function () {
console.log('factory now providing products');
return products;
};
factory.loadProductByCode = function (code) {
var product;
for (var i = 0; i < products.length; i++) {
if (products[i].code == code) {
product = products[i];
return product;
}
}
};
factory.saveProduct = function (product) {
products.push(product);
console.log('factory saved product');
};
factory.deleteProduct = function (code) {
var product = factory.loadProductByCode(code);
if (product != null) {
products.remove(product);
console.log('factory deleted product');
}
};
console.log('returning factory');
return factory;
});
This is my view:
<div class="container">
<h2 class="page-title">Product Listing</h2>
<div class="searchbar">
<ul class="entity-tabular-fields">
<li>
<label>Search: </label>
<span class="field-control">
<input type="text" data-ng-model="filter.productName" />
</span>
<label></label>
</li>
</ul>
</div>
<h2>Add New Product</h2>
<table class="items-listing">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td data-ng-repeat="product in products|filter:filter.productName"></td>
<td>{{product.code}}</td>
<td>{{product.name}}</td>
<td>{{product.description}}</td>
<td>Delete</td>
</tr>
</tbody>
</table>
</div>
My routing function:
angSPA.config(function ($routeProvider) {
$routeProvider
.when(
'/',
{
controller: 'ProductController',
templateUrl: 'Partials/ProductList.html'
})
.when(
'/ProductEdit',
{
controller: 'ProductController',
templateUrl: 'Partials/ProductEdit.html'
})
.otherwise({
redirectTo: '/'
});
console.log('routing done');
});
Change your htmt given
var angSPA = angular.module('angSPA', []);
angSPA.controller("ProductController", function($scope, ProductFactory) {
$scope.products = [];
var init = function() {
$scope.products = ProductFactory.getProducts();
console.log('got products in controller');
console.log($scope.products + "")
};
init();
});
angSPA.factory('ProductFactory', function() {
var products = [
{code: 1, name: 'Game of Thrones', description: 'Series'},
{code: 2, name: 'DmC', description: 'Game'},
{code: 3, name: 'Matrix', description: 'Movie'},
{code: 4, name: 'Linkin Park', description: 'Music Band'}];
var factory = {};
console.log('initializing factory');
factory.getProducts = function() {
console.log('factory now providing products');
return products;
};
factory.loadProductByCode = function(code) {
var product;
for (var i = 0; i < products.length; i++) {
if (products[i].code == code) {
product = products[i];
return product;
}
}
};
factory.saveProduct = function(product) {
products.push(product);
console.log('factory saved product');
};
factory.deleteProduct = function(code) {
var product = factory.loadProductByCode(code);
if (product != null) {
products.remove(product);
console.log('factory deleted product');
}
};
console.log('returning factory');
return factory;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>
<body ng-app="angSPA" ng-controller="ProductController">
<div class="container">
<h2 class="page-title">Product Listing</h2>
<div class="searchbar">
<ul class="entity-tabular-fields">
<li>
<label>Search: </label>
<span class="field-control">
<input type="text" data-ng-model="filter.productName" />
</span>
<label></label>
</li>
</ul>
</div>
<h2>Add New Product</h2>
<table class="items-listing">
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="prod in products|filter:filter.productName">
<td ></td>
<td>{{prod.code}}</td>
<td>{{prod.name}}</td>
<td>{{prod.description}}</td>
<td>Delete</td>
</tr>
</tbody>
</table>
</div>
Your ng-repeat directive should be on the tr element and not the td.
<tr data-ng-repeat="product in products|filter:filter.productName">
Not the cause of your problem, but to log in a service or controller, you can use the $log service and stringify to serialize your objects.
$log.debug(JSON.stringify($scope.products));
Looking at your code, you do $scope.products = [] right at the beginning. This will make angular watch the empty array.
In your init function you assign the products array to $scope.products. But as angular is still watching the initial array it will not be aware of the change.
The solution is to delete the initial assignment $scope.products = [] and make sure to alter the original array but never set it to a new array.
BTW: you could do console.log(JSON.stringify($scope.products)) to get better log information.
HTML Code
<body ng-app="MyApp">
<div ng-controller="PaginationCtrl">
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in pagedItems">
<td>{{item.id}}</td>
<td>{{item.name}}</td>
<td>{{item.description}}</td>
</tr>
</tbody>
<tfoot>
<td colspan="3">
<div class="pagination">
<ul>
<li ng-class="prevPageDisabled()">
<a href ng-click="prevPage()">« Prev</a>
</li>
<li ng-repeat="n in range()" ng-class="{active: n == currentPage}" ng-click="setPage(n)">
{{n+1}}
</li>
<li ng-class="nextPageDisabled()">
<a href ng-click="nextPage()">Next »</a>
</li>
</ul>
</div>
</td>
</tfoot>
</table>
</div>
</body>
Javascript
var app = angular.module("MyApp", []);
app.factory("Item", function() {
var items = [];
for (var i=0; i<50; i++) {
items.push({ id: i, name: "name "+ i, description: "description " + i });
}
return {
get: function(offset, limit) {
return items.slice(offset, offset+limit);
},
total: function() {
return items.length;
}
};
});
app.controller("PaginationCtrl", function($scope, Item) {
$scope.itemsPerPage = 20;
$scope.currentPage = 0;
$scope.range = function() {
var rangeSize = 5;
var ret = [];
var start;
start = $scope.currentPage;
if ( start > $scope.pageCount()-rangeSize ) {
start = $scope.pageCount()-rangeSize;
}
for (var i=start; i<start+rangeSize; i++) {
ret.push(i);
}
return ret;
};
$scope.prevPage = function() {
if ($scope.currentPage > 0) {
$scope.currentPage--;
}
};
$scope.prevPageDisabled = function() {
return $scope.currentPage === 0 ? "disabled" : "";
};
$scope.nextPage = function() {
if ($scope.currentPage < $scope.pageCount() - 1) {
$scope.currentPage++;
}
};
$scope.nextPageDisabled = function() {
return $scope.currentPage === $scope.pageCount() - 1 ? "disabled" : "";
};
$scope.pageCount = function() {
return Math.ceil($scope.total/$scope.itemsPerPage);
};
$scope.setPage = function(n) {
if (n > 0 && n < $scope.pageCount()) {
$scope.currentPage = n;
}
};
$scope.$watch("currentPage", function(newValue, oldValue) {
$scope.pagedItems = Item.get(newValue*$scope.itemsPerPage, $scope.itemsPerPage);
$scope.total = Item.total();
});
});
Heres the fiddle.
http://jsfiddle.net/go14nac5/
When the itemsPerPage is 5 or 10 the pagination works fine but when the itemsPerPage is changed to 20 or more. The pagination has a problem, where the page numbers are displayed with negative values and zero.
Can someone help me sort this out to make a robust bootstrap pagination?
Modify range function:
$scope.range = function() {
var rangeSize = 5;
var ret = [];
var start;
start = $scope.currentPage;
if ( start > $scope.pageCount()-rangeSize ) {
start = $scope.pageCount()-rangeSize;
if (start < 0) {
start = 0;
}
}
for (var i=start; i<start+rangeSize && i < $scope.pageCount(); i++) {
ret.push(i);
}
return ret;
};