I am currently using angular ng-repeat.
When a user clicks a button that says "Next 15", I would like to show next 15 items.
I don't want to pop items from array, I would just like to hide first 15, and limit show to just the next 15.
Also, when the user clicks "Prev 15", I would like to show just the previous 15 items.
Here is what I have so far:
HTML:
<div ng-controller="ctrlIndex as vm">
<ul ng-repeat=" item in vm.items | limitTo: 15 * vm.page
| limitTo: 15 * vm.page < count ? limitTo: 15 * vm.page : 15 - (15 * vm.page - count)"/>
<li>{{ item }}</li>
</ul>
<div><button ng-click="vm.next()">Next 15</button></div>
<div><button ng-click="vm.back()">Prev 15</button></div>
Javascript:
var app = angular.module('app', []);
3app.controller('ctrlIndex', function(){
var vm = this;
vm.numRecords = 15;
vm.page = 1;
vm.items = []
for (var i = 0; i < 1000000; ++i) {
vm.items.push('item : ' + i);
}
vm.next = function(){
vm.page = vm.page + 1;
};
vm.back = function(){
vm.page = vm.page - 1;
};
});
Here you go - Plunker
Markup
<body ng-app="app">
<div ng-controller="ctrlIndex as vm">
<ul ng-repeat="item in vm.items track by $index"
ng-show="(($index < (vm.page * vm.numRecords)) && ($index >= ((vm.page - 1) * vm.numRecords)))">
<li>{{ item }}</li>
</ul>
<div><button ng-click="vm.next()">Next 15</button></div>
<div><button ng-click="vm.back()">Prev 15</button></div>
</div>
</body>
Something like the following will allow you to keep your view tidy and your logic testable:
// controller
var vm = this;
vm.numRecords = 15;
vm.page = 0;
vm.items = [];
vm.data = {};
vm.data.shownItems = [];
vm.limit = 100;
vm.maxPages = Math.floor(vm.limit / vm.numRecords);
for (var i = 0; i < vm.limit; ++i) {
vm.items.push('item : ' + i);
}
vm.data.shownItems = vm.items.slice(0, this.numRecords);
vm.next = function() {
if (vm.page >= vm.maxPages) {
return
}
vm.page += 1;
var begin = vm.page * vm.numRecords;
var end = begin + vm.numRecords;
vm.data.shownItems = vm.items.slice(begin, end);
};
vm.back = function() {
if (vm.page <= 0) {
return
}
vm.page -= 1;
var begin = vm.page * vm.numRecords;
var end = begin + vm.numRecords;
vm.data.shownItems = vm.items.slice(begin, end);
};
// view
<ul ng-repeat="item in vm.data.shownItems">
<li>{{ item }}</li>
</ul>
Plunker
Related
I am having an input type of number when the user types a number it should be displayed in indian format that is
Example: 500000 should be displayed as 50,000
Without using javascript how could i use the indian format in the html itself.
I have already used the filters to show the values in indian format which works well for viewing the data but i would like to do the same during input also but when i tried using the same filter in the model it doesn;t show anything.
Html:
<input ng-if="vm.farmer.type === 'Advance'"
type="number" maxlength="9" placeholder="{{'advamount_message' | translate}}" step=".01"
ng-model="vm.advance.amount_out" ng-change="vm.fillStarted()"
next-focus id="field1"
field-to-validate="yes"
field-value="{{vm.advance.amount_out}}" field-validation-type="num" field-name="{{'vamount_message' | translate}}">
Filter used for view:
.filter('INR', function () {
return function (input) {
if (!isNaN(input)) {
//var currencySymbol = '₹';
/*var result = input.toString().split('.');
var lastThree = result[0].substring(result[0].length - 3);
var otherNumbers = result[0].substring(0, result[0].length - 3);
if (otherNumbers !== '') {
lastThree = ',' + lastThree;
}
var output = otherNumbers.replace(/\B(?=(\d{2})+(?!\d))/g, ',') + lastThree;
// var output = otherNumbers.replace(/(\d)(?=(\d\d)+\d$)/g, ',') + lastThree;
if (result.length > 1) {
output += '.' + result[1];
}
return output;*/
var negative = input < 0;
var str = negative ? String(-input) : String(input);
var arr = [];
var i = str.indexOf('.');
if (i === -1) {
i = str.length;
} else {
for (var j = str.length - 1; j > i; j--) {
arr.push(str[j]);
}
arr.push('.');
}
i--;
for (var n = 0; i >= 0; i--, n++) {
if (n > 2 && (n % 2 === 1)) {
arr.push(',');
}
arr.push(str[i]);
}
if (negative) {
arr.push('-');
}
return arr.reverse().join('');
}
};
During view:
{{vm.farmer.balance | INR}}
Try this filter
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<div ng-app="app" ng-controller="ctrl">
{{price | INR}}
</div>
<script src="../lib/angular.js"></script>
<script>
var app = angular.module('app', []);
app.filter('INR', function () {
return function (input) {
var length = input.length;
if(input.length < 3)
{
return input;
}
else {
var input = input.split(''); //convert it to string and split it into the chars
var output = input[length - 3] + input[length - 2] + input[length - 1];
var j = 2;
for(i=input.length;i--;i>1)
{
if(j>1)
{
output = ',' + output;
j = 0;
}
else {
}
if (i != 0)
{
output = input[i - 1] + output;
j++;
}
}
return output;
}
}
});
app.controller('ctrl', function ($scope) {
$scope.price = '4665987565';
});
</script>
</body>
</html>
you can use this :-
In HTML Template Binding
{{ currency_expression | currency : symbol : fractionSize}}
In JavaScript
$filter('currency')(amount, symbol, fractionSize)
<script>
angular.module('currencyExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.amount = 1234.56;
}]);
</script>
<div ng-controller="ExampleController">
<input type="number" ng-model="amount" aria-label="amount"> <br>
default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
custom currency identifier (USD$): <span id="currency-custom">{{amount | currency:"USD$"}}</span><br>
no fractions (0): <span id="currency-no-fractions">{{amount | currency:"USD$":0}}</span>
</div>
Now with my code i see all pages, but i want to limit the number of links.
If i have 10 pages, but i want to see only five:
1 2 3 4 5,
5 6 7 8 9.
How can i do that? This is plunk demo on part of my code
This is my controller:
var booksController = function () {
function all(context) {
var size = 2,
page = +context.params['page'] || 0;
templates.get('books')
.then(function (template) {
var booksRef = firebase.database().ref('books');
booksRef = booksRef.orderByChild('timestamp');
booksRef.on('value', function (snapshot) {
this.data = [];
snapshot.forEach(function (child) {
this.data.push(child.val());
}.bind(this));
var pagesLen = Math.ceil(data.length / size),
pages = [];
for (var i = 0; i < pagesLen; i+= 1) {
pages.push({
page: i,
displayPage: i + 1
});
}
data = data.slice(page * size, (page + 1) * size);
context.$element().html(template({
books: data,
pages: pages
}));
});
});
}
return { all: all };
}();
And my hadlebars template:
<section id="primary-content">
<div class="wrapper">
<h1 class="above">Books: </h1>
{{#each books}}
<h1>{{title}}</h1>
{{/each}}
<div id="medium">
</div> {{!--end medium--}}
<ul class="pagination">
{{#pages}}
<li>
<a class="btn btn-sm btn-default" href="#/books/{{page}}">{{displayPage}}</a>
</li>
{{/pages}}
</ul>
</div>
in this code snippet you can see a little overview which displays some sample data on several table pages. The pagination and everything else works fine but if I type something into my search, the count of the results changes but the counter at the top stays the same. It also should change dynamically if I restrict the results with the search. So for example if I type "item_44" it should display 1 - 1 of 1 because there is just 1 entry.
I would be glad if someone has an idea how to fix the issue.
Here is the working example.
var myApp = angular.module('myApp', []);
myApp.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
var vm = this;
//vm.currentActive = sessionService.getState();
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.firstItem = 0;
$scope.lastItem = $scope.firstItem + $scope.pageSize;
$scope.numberOfPages = function() {
return Math.ceil($scope.data.length / $scope.pageSize);
}
for (var i = 0; i < 45; i++) {
$scope.data.push("Item " + i);
}
$scope.nextPage = function() {
if ($scope.currentPage >= $scope.data.length / $scope.pageSize - 1) {
} else {
$scope.currentPage = $scope.currentPage + 1;
$scope.firstItem = $scope.firstItem + $scope.pageSize;
if ($scope.firstItem + $scope.pageSize > $scope.data.length) {
$scope.lastItem = $scope.data.length;
} else {
$scope.lastItem = $scope.firstItem + $scope.pageSize;
}
}
}
$scope.prevPage = function() {
if ($scope.currentPage === 0) {
} else {
$scope.currentPage = $scope.currentPage - 1;
$scope.firstItem = $scope.firstItem - $scope.pageSize;
$scope.lastItem = $scope.firstItem + $scope.pageSize;
}
}
}
.name-row {
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div ng-controller="MyCtrl" class="wrapper">
<div class="view-navigation">
<span ng-click="prevPage()" id="hoverfinger"><i class="material-icons">skip_previous</i></span>
<span class="counter">{{firstItem +1}} - {{lastItem}} of {{data.length}}</span>
<span ng-click="nextPage()" id="hoverfinger"><i class="material-icons" >skip_next</i></span>
</div>
<br>
<span ng-click="nextPage()" id="hoverfinger"><i class="material-icons" >search</i></span>
<input type="text" ng-model="search" placeholder="search..." />
<table border="1">
<tr>
<th class="name-row">Name</th>
<th class="info-row">Info</th>
</tr>
<tr ng-repeat="item in data | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize">
<td>{{item}}</td>
<td>more info...
</td>
</tr>
</table>
</div>
Somehow the snippet doesn't work in the StackOverflow site.
Try this , its working.
HTML
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div ng-controller="MyCtrl">
<div class="view-navigation">
<span ng-disabled="currentPage == 0" ng-click="back()" id="hoverfinger"><i class="material-icons">skip_previous</i></span>
<span class="counter">{{currentPage+1}} - {{numberOfPages()}} von {{getDataLength()}}</span>
<span ng-disabled="currentPage >= getData().length/pageSize - 1" ng-click="forward()" id="hoverfinger"><i class="material-icons" >skip_next</i></span>
</div>
<br>
<span ng-click="nextPage()" id="hoverfinger"><i class="material-icons" >skip_next</i></span><input type="text" ng-model="q" placeholder="search..."/>
<table border="1">
<tr>
<th>Status</th>
<th>Name</th>
<th>Info</th>
</tr>
<tr ng-repeat="item in s=( data | filter:q | startFrom:currentPage*pageSize | limitTo:pageSize)">
<td><span><i class="material-icons" style="color: #8AC65B">check_circle</i></span></td>
<td>{{item}}</td>
<td>more info...</td>
</tr>
</table>
</div>
javascript
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ['$scope', '$filter', function ($scope, $filter) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.q = '';
$scope.getData = function () {
return $filter('filter')($scope.data, $scope.q)
}
$scope.getDataLength = function () {
var arr = [];
arr = $filter('filter')($scope.data, $scope.q)
return arr.length;
}
$scope.numberOfPages=function(){
return Math.ceil($scope.getData().length/$scope.pageSize);
}
$scope.back = function(){
if($scope.currentPage == 0){return}else{
$scope.currentPage=$scope.currentPage-1;}
}
$scope.forward = function(){
var val = $scope.numberOfPages();
if(val == ($scope.currentPage+1)){
alert('val');
}
else {
$scope.currentPage+=1;}
}
for (var i=0; i<45; i++) {
$scope.data.push("Item "+i);
}
}]);
myApp.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
I am sure Please Change below code according in your code working fine.
var myApp = angular.module('myApp',[]);
myApp.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
var vm = this;
//vm.currentActive = sessionService.getState();
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.data = [];
$scope.firstItem = 0;
$scope.lastItem = $scope.firstItem + $scope.pageSize;
$scope.numberOfPages=function(){
return Math.ceil($scope.data.length/$scope.pageSize);
}
for (var i=0; i<45; i++) {
$scope.data.push("Item "+i);
}
$scope.nextPage = function(){
if($scope.currentPage >= $scope.data.length/$scope.pageSize - 1){
}
else{
$scope.currentPage = $scope.currentPage + 1;
$scope.firstItem = $scope.firstItem + $scope.pageSize;
if($scope.firstItem + $scope.pageSize > $scope.data.length){
$scope.lastItem = $scope.data.length;
}
else{
$scope.lastItem = $scope.firstItem + $scope.pageSize;
}
}
}
$scope.prevPage = function(){
if($scope.currentPage === 0){
}
else{
$scope.currentPage = $scope.currentPage - 1;
$scope.firstItem = $scope.firstItem - $scope.pageSize;
$scope.lastItem = $scope.firstItem + $scope.pageSize;
}
}
}
<html ng-app='myApp'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head><body ng-controller="MyCtrl" >
<div class="wrapper">
<div class="view-navigation">
<span ng-click="prevPage()" id="hoverfinger"><i class="material-icons">skip_previous</i></span>
<span class="counter">{{firstItem +1}} - {{griddata.length}} of {{data.length}}</span>
<span ng-click="nextPage()" id="hoverfinger"><i class="material-icons" >skip_next</i></span>
</div>
<br>
<span><i class="material-icons" >search</i></span><input type="text" ng-model="search" placeholder="search..."/>
<table border="1">
<tr>
<th class="name-row">Name</th>
<th class="info-row">Info</th>
</tr>
<tr ng-repeat="item in griddata=(data | filter:search | startFrom:currentPage*pageSize | limitTo:pageSize)">
<td>{{item}}</td>
<td>more info...</td>
</tr>
</table>
</div>
</body>
</html>
So I've got the beginnings of an animation script here:
<div id="card5">
<h4 class="y">Let me be your guide.</h4>
<h1>Here's what I've got:</h1>
<div id="a">
<h4 id="aa">Creativity</h4>
</div>
<div id="b">
<h4 id="bb">Know-how</h4>
</div>
<div id="c">
<h4 id="cc">Familiarity</h4>
</div>
</div>
<script type="text/javascript">
var aa = document.getElementById("aa");
var bb = document.getElementById("bb");
var cc = document.getElementById("cc");
var aamargin = style.aa.marginTop | 30;
var bbmargin = style.bb.marginTop | 30;
var ccmargin = style.cc.marginTop | 30;
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementsByTagName("c");
var aadown = true;
var bbdown = true;
var ccdown = true;
a.onmouseover = amove;
b.onmouseover = bmove;
c.onmouseover = cmove;
function amove() {
window.alert("Herro!");
if (aadown) {
aaup();
aadown = false;
}
}
function aaup() {
if (aamargin > 0) {
aamargin -= 1;
style.aa.marginTop = aamargin + "%";
requestAnimationFrame(aaup);
}
}
</script>
And when I mouse over the first div ("a"), of course, nothing happens. I put an alert box in to see if the amove() function was being triggered, and it wasn't. The alert never fired. No idea why. It's probably just a typo somewhere...
the error is here:
var aamargin = style.aa.marginTop | 30;
var bbmargin = style.bb.marginTop | 30;
var ccmargin = style.cc.marginTop | 30;
I think you mean aa.style instead of style.aa?
Two errors with style.aa.marginTop | 30;:
| is a bitwise operator, if you want logical OR, you need ||, like this: style.aa.marginTop || 30;
style is not defined, you need aa.style, like this: aa.style.marginTop || 30;
Last thing: bmove and cmove are not defined.
See the patched example here:
<div id="card5">
<h4 class="y">Let me be your guide.</h4>
<h1>Here's what I've got:</h1>
<div id="a">
<h4 id="aa">Creativity</h4>
</div>
<div id="b">
<h4 id="bb">Know-how</h4>
</div>
<div id="c">
<h4 id="cc">Familiarity</h4>
</div>
</div>
<script type="text/javascript">
var aa = document.getElementById("aa");
var bb = document.getElementById("bb");
var cc = document.getElementById("cc");
var aamargin = aa.style.marginTop || 30;
var bbmargin = bb.style.marginTop || 30;
var ccmargin = cc.style.marginTop || 30;
var a = document.getElementById("a");
var b = document.getElementById("b");
var c = document.getElementsByTagName("c");
var aadown = true;
var bbdown = true;
var ccdown = true;
bmove = cmove = amove; // just a quickfix
a.onmouseover = amove;
b.onmouseover = bmove;
c.onmouseover = cmove;
function amove() {
window.alert("Herro!");
if (aadown) {
aaup();
aadown = false;
}
}
function aaup() {
if (aamargin > 0) {
aamargin -= 1;
aa.style.marginTop = aamargin + "%";
requestAnimationFrame(aaup);
}
}
</script>
Im building an pagination in backbone. The problem is that the amount of pages has grown and are now that many that it ruins the layout of the site. So i want to implement a functionality where i can render lets say the first 10 pages and then with a next/prev button control which page numbers should be shown. But always only show 10 pages like so:
< 1 2 3 4 5 6 7 8 9 10 >
< 2 3 4 5 6 7 8 9 10 11 >
So now i append this to my pagination (its all pages)
updateTotal: function () {
var self = this;
self.totalModel.fetch({
success:function(model,response) {
var total = response.data; //all iems
var p = total/self.perPage;
var r = total-Math.round(p)
self.pagination = _.template($("#pagination_template").html(), {
pages:Math.ceil(p)
});
self.render();
}
});
},
This is how i print it out in html (underscore.js)
<script type="text/template" id="pagination_template">
<section class="pagination">
<ul>
<% for (var i = 0; i < pages; i++) { %>
<li>
<a href="#" data-offset="<%= i*9 %>" data-page="<%= i+1 %>">
<%= i+1 %>
</a>
</li>
<% } %>
</ul>
<div class="paging prev">◄</div>
<div class="paging next">►</div>
</section>
</script>
I have a variable the represents the current page and i know the total amount of pages. But i dont know how to implement this that i describes as my problem.
Anyone knows how to do this and can come with an example? Would be very appreciated!
You can do it like this :
updateTotal: function () {
var self = this;
self.totalModel.fetch({
success:function(model,response) {
var total = response.data; //all iems
var p = total/self.perPage;
var r = total-Math.round(p);
var c = ... // current page
self.pagination = _.template($("#pagination_template").html(), {
pages:Math.ceil(p),
current: c
});
self.render();
}
});
},
And the html
<script type="text/template" id="pagination_template">
<section class="pagination">
<ul>
<%
var renderPage;
for (var i = 1; i <= pages; i++) {
renderPage = false;
if (pages < 10) {
renderPage = true;
} else {
if (current <= 5) {
if (i < 10) {
renderPage = true;
}
} else if (current <= pages - 5) {
if ((current - 5) < i || (current + 5) > i) {
renderPage = true;
}
} else {
if ((pages - 9) < i) {
renderPage = true;
}
}
};
if (renderPage) { %>
<li>
<a href="#" data-offset="<%= i*9 %>" data-page="<%= i %>">
<%= i %>
</a>
</li>
<% }
} %>
</ul>
<div class="paging prev">◄</div>
<div class="paging next">►</div>
</section>
</script>
That will print the current page and the 4 pages before and after.