How can i make pagination through AngularJS? - html

Recently I create a AngularJs App . Thats code are below
HTML :
<div ng-app="" ng-controller="Hello">
<ul>
<li ng-repeat="x in greeting">
{{ x.user_name }}
</li>
</ul>
</div>
And my JS code is:
function Hello($scope, $http) {
$http.get('http://localhost/google/cibl/dashboard/get_all_user').
success(function(data) {
$scope.greeting = data;
});
}
Its working fine. This http service give me 2000 row now i want to paginate this by AngularJs. How can I do that ?

In your controller
app.controller('Hello', function($scope){
$scope.pageSize = 10;
$scope.currentPage = 0;
$scope.changePage = function(page){
$scope.currentPage = page;
}
})
In your mark up, you should have
<div ng-app="" ng-controller="Hello">
<ul>
<li ng-repeat="x in greeting | startFrom: currentPage * pageSize | limitTo: pageSize">
{{ x.user_name }}
</li>
</ul>
</div>
We're missing the startFrom filter so lets create that
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
Now all thats left is the paginating panel, I'll leave it up to you to pretty it with css
<ul class="pagination" >
<li ng-repeat="page in pagination" ng-class="{'active':currentPage == page}"><a ng-click="changePage(page)">{{page + 1}}</a></li>
</ul>
Notes:
The reason why we use changePage() instead of currentPage = page is due to ng-repeat which could break some of the variables
In your anchor () tag, instead of ng-click, you can use a href to mark the page and in your controller, watch the page ref and change based on the queries. The benefits to this is that when you decide to do SEO for your website, it will be ready for that!
href="#!/partialname?page={{page}}"

You can do this way:
Pagination Example: http://jsfiddle.net/2ZzZB/56/
Found it in this question:
Pagination on a list using ng-repeat

At least I got a solution and its work properly :
HTML :
<div ng-controller="userController" class="jumbotron">
<h2>User List</h2>
<table class="table table-striped">
<thead>
<tr>
<th>User </th>
<th>Group</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="u in users | itemsPerPage : 5">
<td>{{u.user_name}}</td>
<td>{{u.user_type}}</td>
</tr>
</tbody>
</table>
<dir-pagination-controls on-page-change="pageChanged(current)" template-url="<?php echo base_url(); ?>js/dirPagination.tpl.html"></dir-pagination-controls>
</div>
and JS :
Here i use AngularJs pagination directive
function userController($scope, $http) {
$scope.users = [];
$scope.total = 0;
$scope.perPage = 25; // this should match however many results your API puts on one page
getUsers(1);
$scope.pagination = {
current: 1
};
$scope.pageChanged = function (newPage) {
getUsers(newPage);
};
function getUsers(pageNumber) {
// this is just an example, in reality this stuff should be in a service
$http.get(app.baseUrl + 'dashboard/get_all_user/' + pageNumber)
.success(function (data) {
console.log(data);
$scope.users = data.users;
$scope.total = data.total;
})
.error(function (data) {
console.log(data);
alert("There was a problem. Please try again later.");
});
}
};
var myApp = angular.module('myApp', ['angularUtils.directives.dirPagination']);
var app = app || {};
app.baseUrl = '<?= base_url() ?>';
myApp.controller('userController', userController);

Related

DOM element in mdTab not updated with angular .css method

I got progress bar in my table where I show how many hours has been spend on project. When I click on some tab, currentTab method is fired to get data from database and after I promise is resolved my TimeService function is fired also to calculate hours for progress bar, but when angular .css() is reached it doesnt update my progress bar at all and I dont know why since it definitely 100% working code. Is there some feature in mdTabs which prevent this?
HTML code below, I deleted plenty of stuff to make it more readable
<md-tab label="Testing" md-on-select="currentTab('Testing')">
<md-content class="md-padding">
<table id="projects-active" class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Estimated time</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="project in projects.Data">
<td>{{project.Id}}</td>
<td>{{project.Name}}</td>
<td>{{project.Description}}</td>
<td>
<div class="progress-group">
<div class="progress sm">
<div class="progress-bar progress-bar-success progress-bar-striped" id="progress-bar-pId-{{project.Id}}">
</div>
</div>
</div>
</td>
<td>{{project.Status}}</td>
</tr>
</tbody>
</table>
<div class="box-footer clearfix">
<ul uib-pagination total-items="totalItems"
items-per-page="maxSize"
ng-model="currentPage"
max-size="maxSize"
class="pagination-sm"
boundary-links="true"
num-pages="pages"
ng-change="setPage(currentPage, 'Testing')"></ul>
</div>
</md-content>
Here is my function in TimeService modul
projectProgressArray: function (array) {
var items = array.Data;
angular.forEach(items, function (key, value) {
var id = key.Id;
var maxTime = key.EstimatedTime;
var currentTime = key.TimeSpend;
var percentageComplete = Math.round(((currentTime / maxTime) * PERCENTAGE) * 100) / 100;
if (!("#progress-bar-pId-" + id).length == 0) {
angular.element("#progress-bar-pId-" + id).css("width", percentageComplete + "%");
if (percentageComplete > 100) {
angular.element("#progress-bar-pId-" + id).removeClass("progress-bar-success");
angular.element("#progress-bar-pId-" + id).addClass("progress-bar-danger");
}
}
});
Here is my controller function where I fetch data to my data tables
var MAX_SIZE_PER_PAGE = 5;
$scope.currentPage = 1;
$scope.maxSize = MAX_SIZE_PER_PAGE;
$scope.pages = 0;
$scope.totalItems = 0;
$scope.setPage = function (pageNo, status) {
$scope.currentPage = pageNo;
$scope.projects = ProjectService.queryPaged({ pageSize: $scope.maxSize, pageNumber: $scope.currentPage, status: status });
$scope.projects.$promise.then(function (data) {
setTimeout(function () {
TimeService.projectProgressArray($scope.projects);
}, 0);
});
};
$scope.currentTab = function (status) {
$scope.projects = ProjectService.queryPaged({ pageSize: $scope.maxSize, pageNumber: 1, status: status });
$scope.projects.$promise.then(function (data) {
$scope.totalItems = data.TotalCount;
setTimeout(function () {
TimeService.projectProgressArray($scope.projects);
}, 0);
});
}
UPDATE: I added image where i copy progress bars outside of md-tab to show its working outside of md-tabs but not inside it.
So after some time of I found out that I cannot manipulate with css in Angular material using angular.element().css() method. I had to edit my TimeService method where I created array filled with information about single progress bar per project and send it back to my controller and use ng-style
to manipulate with my css inside ng-material DOM
projectProgressArray: function (array) {
var progressBarArray = [];
var items = array.Data;
angular.forEach(items, function (key, value) {
var progressBar = {
projectId: null,
percentage: null,
barClass: null
}
var id = key.Id;
var maxTime = key.EstimatedTime;
var currentTime = key.TimeSpend;
var percentageComplete = Math.round(((currentTime / maxTime) * PERCENTAGE) * 100) / 100;
progressBar.projectId = id;
progressBar.percentage = percentageComplete + "%";
if (!("#progress-bar-pId-" + id).length == 0) {
if (percentageComplete > 100) {
progressBar.barClass = "progress-bar-danger";
}
else {
progressBar.barClass = "progress-bar-success";
}
}
progressBarArray.push(progressBar);
});
return progressBarArray;
Reworked HTML binding
<div class="progress-group">
<div class="progress sm" ng-repeat="item in progressBars" ng-hide="item.projectId != project.Id">
<div ng-class="{'progress-bar-success': item.barClass == 'progress-bar-success',
'progress-bar-danger': item.barClass == 'progress-bar-danger' }"
class="progress-bar progress-bar-success progress-bar-striped" id="progress-bar-pId-{{project.Id}}"
ng-style="{'width':item.percentage}">
</div>
</div>

How to implement ng-show as toggle in multi-level ng-repeat

1. level1
-lvl1A
--lvl1A1
--lvl1A2
---lvl1A2X
---lvl1A2Y
-lvl2A
--lvl2A1
--lvl2A2
2. level2
this is just the sample of multilevel ng-repeat ul li element.
on click of any level only next level data will show or hide not the entire data.
kindly give me some solution to this scenario.
Thanks in Advance.
I have done this in some of my spare time.. it might not be the best way to do it.
angular.module("myApp", []).
controller("TreeController", ['$scope',
function($scope) {
$scope.delete = function(data) {
data.nodes = [];
return false;
};
$scope.add = function(data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
var showSub = false;
data.nodes.push({
name: newName,
showSub: showSub,
nodes: []
});
return false;
};
$scope.tree = [{
name: "Node",
showSub: false,
nodes: []
}];
}
]);
<script type="text/ng-template" id="tree_item_renderer.html">
{{data.name}}
<button ng-click="add(data); $event.stopPropagation();">Add node</button>
<button ng-click="delete(data); $event.stopPropagation();" ng-show="data.nodes.length > 0">Delete nodes</button>
<ul ng-show="data.showSub">
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="data.showSub = !data.showSub; $event.stopPropagation();"></li>
</ul>
</script>
<ul ng-app="Application" ng-controller="TreeController">
<li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'" ng-click="data.showSub = !data.showSub"></li>
</ul>
jsFiddle

JSON Media Type for for request with AngularJS

This is the backend Java Side with Jersey in an embedded Jetty.
#GET
#Path("/jason")
#Produces({MediaType.APPLICATION_JSON})
public MyJaxBean getMyBean() {
MyJaxBean myJB = new MyJaxBean();
myJB.add("Hello", 1);
myJB.add("World", 2);
return myJB;
}
checking that with curl brings back this text
{"person":[{"name":"Hello","age":1},{"name":"World","age":2}]}
Using that in an HTML Page
<p id="demo"></p>
<button onclick="doRequest()">REQUEST !</button>
<script>
"use strict";
function doRequest(){
var xmlhttp = new XMLHttpRequest();
var url = "http://localhost:8080/api/entry-point/jason";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
var myHTML = iterateObject(myArr);
document.getElementById("demo").innerHTML = myHTML
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function iterateObject(myArr) {
var out = '';
myArr.person.forEach(function(p) {
out+= p.name + ',' + p.age + '<br>';
});
return out;
}
</script>
brings back
Hello,1
World,2
However this try with AngularJS does not show anthing from the Jason Call
<!DOCTYPE html>
<html>
<script src= "http://localhost:8080/ressources/angular.js"></script>
<body>
<h2>AngularJS doing a JSON HTTP Request</h2>
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="p in persons">
{{ p.name + ', ' + p.age }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://localhost:8080/api/entry-point/jason")
.success(function (response) {$scope.persons = response.records;});
});
</script>
</body>
</html>
Replacing the http.get with
$scope.persons = [{name:"Hello", age:1},{name:"World",age:2}]
does work.
Any Idea what is wrong with the Media Type or the AngularJS Example ?
Thanks for any help here
Change <li ng-repeat="p in names"> to <li ng-repeat="p in persons">. You are setting the value in persons object but using names in the view.
DEMO http://plnkr.co/edit/0aNUfTwyBJYjQjCsP1UU?p=preview

document.write a json vector to a table

Firstly I get orders:
app.controller('customersController', ['$scope', '$http', function($scope,$http) {
$http.get("http://18ff2f50.tunnel.mobi/yii2-basic/tests/Customers_JSON.json")
.success(function (response)
{
console.log("debug",response);
$scope.orders = response;
});
In an order I have a detail:
<div class="row" ng-repeat="x in orders|orderBy:'order_id'">
....
<div class="col right">
<button ng-click="viewOrderDetails(x.detail)">订单详情</button>
</div>
I have a json vector (which is returned from the server) stored in "detail" like this:
"detail":
"{\"4\":
{\"num\":2,
\"id\":\"4\",
\"name\":\"\\u86cb\\u7092\\u996d\",
\"price\":\"10.00\",\"total\":20},
\"6\":
{\"num\":1,
\"id\":\"6\",
\"name\":\"\\u626c\\u5dde\\u7092\\u996d\",
\"price\":\"10.00\",\"total\":\"10.00\"},
\"5\":
{\"num\":1,
\"id\":\"5\",
\"name\":\"\\u51b0\\u6dc7\\u51cc\",
\"price\":\"8.00\",\"total\":\"8.00\"
}}"
$scope.viewOrderDetails = function viewOrderDetails(detail) {
var newWin = open('orderdetails.html','windowName','height=300,width=300');
newWin.document.write('html to write...\n');
newWin.document.write(detail);
newWin.document.write('<input type="button" value="Close this window" onclick="window.close()">');
}
I want it displayed in a new window like this:
how should I do the document.write? Thanks.
You can use $compile service to compile template to write into new window:
app.controller('customersController', function($scope, $http, $compile) {
$http.get("order.json").success(function(response) {
$scope.x = response;
});
$scope.viewOrderDetails = function viewOrderDetails(order) {
var newWin = open('', 'windowName', 'height=300,width=300');
var template =
'<div>' +
'<table>' +
'<tr ng-repeat="(key, value) in order">' +
'<td>{{value.name}}</td>' +
'<td>{{value.id}}</td>' +
'<td>{{value.price}}</td>' +
'<td>{{value.total}}</td>' +
'</tr>' +
'</table>' +
'<input type="button" value="Close this window" onclick="window.close()">' +
'</div>';
$scope.order = order;
var table = $compile(template)($scope);
newWin.document.body.appendChild(table[0]);
}
});
Demo: http://plnkr.co/edit/pMCClUYMkpeyMiFwphrj?p=preview
Please take a look the code below, If you don't want to use jQuery, and want to use document.write() way. Use this code in your orderdetails.html file
<table>
<thead>
<tr>
<th>ID</th><th>Name</th><th>Price</th><th>Total</th>
</tr>
</thead>
<tbody>
<script>
var detail = window.opener.detail;
for(key in detail) {
document.write("<tr><td>"+ detail[key]["num"] +"</td><td>"+ detail[key]["name"] +"</td><td>"+ detail[key]["price"] +"</td><td>"+ detail[key]["total"] +"</td></tr>");
}
</script>
</tbody>
</table>
Please let me know if it is not working.

Angularjs does not update the data retrieved from the $http service

I'm trying to retrieve some data from a service using Angularjs. Initially, I want to just show the first 10 elements. Then, when the user clicks on a button (with ng-click="next()"), I want the same function to be triggered again in order to get the next 10 elements.
Here's my controller:
Admin.controller('orders', function ($scope, $http) {
var startIndex = 0;
const count = 10;
function retrieveData(startIndex, count) {
$http({
method: 'POST',
url: '/Admin/order/GetOrders',
data: { "startIndex": startIndex, "count": count }
})
.success(function (data) {
$scope.orders = data;
startIndex = startIndex + count;
$scope.$apply();
});
};
retrieveData(startIndex, count);
$scope.next = retrieveData(startIndex, count);
};
Now, what happens is that the function retrieveData() works perfectly the first time, but when I click the button nothing happens. I know for sure that the "click" event triggers the function, because I tried to replace the code with an alert, but I don't understand why the function retrieveData() itself only works the first time.
What am I missing?
<div class="container admin" ng-controller="orders">
<table class="table">
<tbody>
<tr ng-repeat="order in orders| filter:{OrderStatus: 'Hto'} | filter:query | filter:'!'+showCancelled | orderBy:predicate:reverse">
<td>
{{order.UserName}}
</td>
<td>
<span ng-class="{ 'label label-danger' : isLate }">
{{order.OrderDate}}
</span>
</td>
<td>
{{order.Country}}
</td>
<td>
<span ng-class="{ 'label label-warning' : order.OrderStatus == 'HtoPreAuth' || order.OrderStatus == 'SalePreAuth'}">
{{order.OrderStatus}}
</span>
</td>
</tr>
</tbody>
</table>
<a href="" ng-click="retrieveData()">
next
</a>
</div>
You are supposed to make the changes inside the $apply method:
Admin.controller('orders', function ($scope, $http) {
var startIndex = 0;
const count = 10;
$scope.retrieveData() { // No parameters
$http({
method: 'POST',
url: '/Admin/order/GetOrders',
data: { "startIndex": startIndex, "count": count }
})
.success(function (data) {
startIndex = startIndex + count;
$scope.orders = data;
if(!$scope.$$phase) {
$scope.$digest();
}
});
}
$scope.retrieveData();
};
// And the view
<a ng-click="retrieveData()"></a>
Edit:
Remove the parameters from the $scope.retrieveData function since they will be undefined
if you call the function with ng-click="retrieveData()"