How can I show next 15 items in ng-repeat? - javascript

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

How to show the numbers in indian format in html

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>

Limit number of links to show in custom paging

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>

dynamic result counter during search

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>

JavaScript Not Triggering

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>

Backbone pagination 10 at a time

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.

Categories

Resources