begriffs / angular-paginate-anything Goto Github PK
View Code? Open in Web Editor NEWÀ la carte server-side pagination
License: MIT License
À la carte server-side pagination
License: MIT License
sm
or lg
-- default is medium.
I've noticed that when I am viewing paginated results, let's say page 4, then click on any of the links to view the detail and then click on the browser Back
button, the page is reset to 1. Is there a way to keep it on the same page (i.e. page 4 in this scenario)? Thank you.
The strange error occur in our customer on Windows 8.1 + FireFox 32. and Windows 7 + Chrome 7.0.2062.120.
I can't reproduce this problem on my enviroment.
Console logs shown the following exception:
Exception" Exception { message: "", result: 2153644038, name: "", filename: "http://site.ru/scripts/vendor/angular.js", lineNumber: 8327, columnNumber: 0, inner: null, data: null }
Most likely browser reject this request by some reason.
I can't find our a root cause of the problem right now, and change request method to POST from GET(I waiting for the customer reply).
Web page is: http://goo[.]gl/T2d2oh
What do you think about this exception? May be this is a already known problem.
Hi begriffs, your module is working great. I have an improvement to suggest you.
I'm using angular-paginate-anything in a progect where I query data from a database and send a lot of custom filters. The url has growth over the 2048 url length limit, but it is still working maybe because of Chrome. Internet Explorer has limitations, so can be problems in future.
What about change the method from GET to POST in requestRange() function?
I've done and it seems ok.
Hi!
Could the range returned by the server be made available as another read-only attribute?
It would make adjusting the 0-based index in an ng-repeat much more convenient.
Thanks for a great directive!
Previous and next buttons are clickable even theres no more page to go, resulting in a incorrect navigation, eg. if you click back on the first page, the current page becomes -1
Is it possible to configure and use this directive without depending on $scope in my controllers, since I am using ControllerAs syntax?
I'm reviewing code one of my colleagues wrote to get this wired up to a ui-grid and also provide sorting (all paging and sorting done on server side). Here's what we have:
Controller:
function SubjectAreaListController($scope) {
var vm = this;
vm.page = 0;
vm.perPage = 2;
vm.clientLimit = 100;
vm.sortParams = {};
vm.gridOptions = {};
vm.gridOptions.useExternalSorting = true;
vm.gridOptions.columnDefs = [
{field: "name", displayName: "Name", cellTemplate: "<a href='#/subjectArea/edit/{{row.entity.id}}'>{{row.entity.name}}</a>"},
{field: "owners", displayName: "Owners"}
];
vm.gridOptions.onRegisterApi = onRegisterApi;
function onRegisterApi( gridApiIn ) {
vm.gridApiCore = gridApiIn.core;
vm.gridApiCore.on.sortChanged($scope, onSortChanged);
function onSortChanged(grid, sortColumns) {
if( sortColumns.length > 1) {
sortColumns[0].unsort(); // only sort on one column at a time
} else if (sortColumns.length === 1) {
vm.sortParams = { sortCol: sortColumns[0].name, sortDir: sortColumns[0].sort.direction };
}
}
}
}
Template:
<bgf-pagination
page="vm.page"
per-page="vm.perPage"
client-limit="vm.clientLimit"
url="'/api/subjectarea'"
url-params="vm.sortParams"
link-group-size="2"
collection="vm.gridOptions.data"
template-url="paginate-anything-template.html">
</bgf-pagination>
<div ui-grid="vm.gridOptions" class="grid" ui-grid-auto-resize></div>
Now that every smaller perPage preset divides any larger, we don't need two requests.
gotoPage
is generally getting called twice in a row. I think this is because it triggers a page
change and you also have that property being watched, which triggers gotoPage
.
This might cause some bugs...
is it because reload-page and gotopage are isolated scope ?
"
Pagination works great.
However i wanted to access gqs (collection) via $scope.gqs in paginationController when i click a button.
unfortunately console.log($scope.gqs) said "undefined"
I make sure that data was loaded successfully before i click button.
Any ideas?
Thanks for the great tool!
The passive copy at the bottom of my page doesn't update when url
changes or when reloadPage
is set. The active one works fine.
I tried to plunkr this, but I can't even see the passive copy on plunkr for some reason. I'll create another issue about that.
The default template location tpl/paginate-anything.html
is problematic if you install this component via bower or in a subfolder in your project.
You have to put the template manually into <project root>/tpl/
or change the url in the source and minified source or on every directive. I've a lot of directives in my app ;)
Does something speak against to put the template into the same location as the js files or just to embed the default template into the minified source?
If not i can prepare a pull request, but wanted to discuss first.
With ngResource or $http you can use an error/success callback or promise to implement error handling or logging, manipulating data, etc.
How is it done with this directive?
I was going to send a (tiny) pull request for this but I wasn't sure how to add a test or whether it makes sense to do more than emit something -- I just added an extra check for "reset content" status into my development copy of paginate-anything because sometimes the result set goes away and I want to be able to react to that condition (in my case by reloading the page).
205 Reset Content
The server has fulfilled the request and the user agent SHOULD reset the document view which caused the request to be sent.
Hi, i have started a rewrite of the ruby gem for pagination with a nodejs server, express or simple http.
https://github.com/polo2ro/node-paginate-anything
you can add a link to it from the main page if you want.
According to RFC2616 Range Headers (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.16), the Content-Range header should include the range unit at the start of the value:
Content-Range: items 21010-47021/47022
My .NET/IIS server is using Web API (not ServiceStack), and I leverage a built-in class to generate the content-range header (System.Net.Http.Headers.ContentRangeHeaderValue, https://msdn.microsoft.com/en-us/library/system.net.http.headers.contentrangeheadervalue.aspx).
When I make calls to the api and use the above class, it yields the correct headers according to the spec. However, when I look at your examples, and look at the server response you're using, the Content-Range header does not seem to include the range unit, just the from-to/total values. This is what your server is responding with:
Content-Range: 0-4/235886
The directive code that parses the header using a regex (if I remember correctly from the src) is breaking for me as it expects no range unit at the beginning of that header value. Is there something I am missing, or could this be a bug on the directive's expectations?
Here's the C# code snippet that I am using to set the appropriate headers in the response from my web api, where the from/to/count variables are set elsewhere in the code:
response.Headers.Add("Accept-Ranges", "items");
response.Headers.Add("Range-Unit", "items");
if (_totalCount > 0)
response.Content.Headers.ContentRange = new ContentRangeHeaderValue(_requestedFrom, _requestedTo, _totalCount) {Unit = "items"};
Hi, just curious, I'd like to use this method to handle pagination, but I'd also like to return a list of search facets with counts for future drilldown. How would we do that? Is there a 'RESTful' way to do that using headers?
The tag syntax <begriffs.pagination>
does not conform to the W3C HTML Markup standard for tag names which states that only the characters 0-9
, a-z
, and A-Z
can be used.
An example of the problems this can cause.... the current tag name causes a parsing error during minification by html-minifer that is used by grunt-contrib-htmlmin.
With ngResource or $http you can use a json object to handle get parameters.
Sth like the $location.search() API.
It would be very useful to have a urlParams option to pass a search object to the directive.
Maybe just pass the $http.params property?
I'm resolving some data in my route and I'd like to pass it to the directive's collection instead of the directive making a second request when the view is loaded. Is this possible?
Hi. What is the meaning and possible values for the Range-Unit
header in the request and response objects? I haven't found any explanation in the README. Thank you.
When I hit the demo link in the README, I get taken to a page that just says: "Waiting for Heroku server http://pagination.begriffs.com to wake up..." Alas, it is very sleepy, and never seems to wake up. Not a huge deal, but thought I would let you know in case it was an easy fix. Thanks for the plugin!
How can refresh the current page data?
Hello! First, thanks for the helpful directive
In your demo site, the data is not showing. The words collections are empty, my guess is because your directive tag is not properly closed. It should be presented with closing tag(?) <begriffs.pagination> </begriffs.pagination>
not <begriffs.pagination />
Thanks...
Any plans to support pagination for RFC-5988?
We're using the api-pagination gem for rails and would like to find some support for it in angular:
https://github.com/davidcelis/api-pagination
It puts the pagination links in the headers like so:
Link: http://localhost:3000/movies?page=1; rel="first",
http://localhost:3000/movies?page=173; rel="last",
http://localhost:3000/movies?page=6; rel="next",
http://localhost:3000/movies?page=4; rel="prev"
Also, RFC-5988 is the pagination method that github uses in their API:
https://developer.github.com/guides/traversing-with-pagination/
If you would like support RFC-5988, I can try my best swing at it, just point me in the right direction.
The params dont work when used with ui-router single page app,
It does not recognise the scope variables within controller when used with ui-router
http://plnkr.co/edit/007mVhenNIdjAftfMW6K?p=preview
If you take out passive="true"
it shows up correctly.
Hi,
Lets say you paginate to page 2, then click on an item and navigate away to a new page altogether.
Then click back .. how to start the page on pagination page 2 again?
I'm sure there's a few ways to go about this, what I've tinkered with and seems to work OK for me is to pass in global
object I use for session state stuff and set the page value.
I'm not sure if I explained that too well, but if you check out the code in my fork at:
https://github.com/rudijs/angular-paginate-anything/blob/master/src/paginate-anything.js
If you search for rsm
you'll see code comments where I've added in this global session state stuff.
I then use $scope.currentPage to retrieve the stored page value with loading the pagination directive (like so):
$scope.currentPage = Global.getSessionState().currentPage || 0;
Note: I might have botched my explanation of all this (not at my proper workstation when drafting this)
I might also be on the wrong track, even though it works OK for me, your thoughts here would be great.
Thanks.
Here's the error:
Error: [$compile:nonassign] Expression '[10,20,50,100]' used with directive 'paginateit' is non-assignable!
That's my per-page-presets
attribute value it's talking about. Here's the code:
(note, I changed the directive name per #41)
<paginateit
collection="logs"
url="apiURL"
per-page="perPage"
per-page-presets="[10,20,50,100]"
template-url="/assets/paginate-anything.html">
</paginateit>
Now, if I change per-page-presets to a scope var, and put the array on that, the error goes away, but then the presets aren't changed then either (I get the default presets.) However, when coded as I have it above, they work... In fact the entire directive works fine, I just get the error in the console...
What am I doing wrong? 😢
Actually this ain't an issue, I just wanted to email you but didn't know your email address. Wanted to ask you about how I would integrate this with the paging capability of ngGrid/ng-table?
As I understood from what you wrote in your README as well as the RFC article you referenced (very cryptic to me), this is more of a protocol that the server-side needs to implement by modifying it's response headers and somehow your angular module will just magically work. Is that correct?
I'd like to test that the right things happen when a user clicks the interface, but Karma and PhantomJS are not getting along and won't allow me to click things.
Your directive name "pagination" collides when in the same page is used also the module "ui.bootstrap".
The solution I adopted is to rename your directive name to "paginationbegriffs" and everything goes well.
Thank you for this good module.
It would be nice to have a minified version distributed as part of the Bower package.
Needed for display some progress bar in cases long time page data loading
I was wondering if anyone knew how to make filtering work on pages after the first one? Adding track by $index breaks the directive.
in v2.4 -> changing the URL variable in the controller does not reload the collection (afaik it was working in v2.2)
Hello,
I've been through the issues here and came across #19 which had a couple comments about collection modification. As @dnauck mentioned, sometimes there are instances where UI related components require some data manipulation prior to display.
A simple use case I've come up against recently is the requirement to calculate a duration based on a start and end time. I achieve this currently by calling out to a method on a per record basis, but it would be nice to iterate over the collection after it was loaded and extending my object with my "duration" property.
I know you mentioned the possibility of adding a "transformResponse" parameter at the bottom of #19.
Any further thoughts here? Thank you.
It would be nice to avoid coupling between the REST URL, which in some cases is referenced in a service, and not in the controller, and the directive. The directive could then be fed with the results of the REST request. Also, trying not to use the url attribute results in a cryptic $http error instead of a user friendly message.
I use bgf-pagination directive to get a users list data from a server. I want to show a loading icon when the page loads or reloads. I tried to find a parameter in the directive to drive this loading icon and the only one I found is "reload-page" but it doesn't work. Is there any flag to do that in the current directive?
This is more of a question than a bug report as I am new to Angular. I am having trouble figuring out how to specify the URL attribute dynamically.
I've tried using URLs like "http://example.com/api/{{model.id}}/items" but that only leads to a $parse:syntax error. When I change url
to "@" instead of "=" in the scope definition it sort of works, but then requestRange() fires before the interpolation completes. That is, when I try to inspect the value of url
using console.log and other mechanisms it has been interpolated. But, when paginate-anything starts up it makes a call to "http://example.com/api//items" (notice the double slash where model.id should be). Is this a bug in the directive or is there some angular trick I can use to make it wait until all the attributes on the directive have been interpolated before calling requestRange()?
if page more than 50 elements this feature is desirable
I've one page with several angular-ui-bootstrap tabs. On each tab is one paging directive. As soon as the site loads every directive starts loading its data, even when the user just want to see one tab.
An option to disable auto loading would be helpful. As soon as the tab gets active we could the use reload option to get the data.
See this thread where a developer states:
Chrome's cache will only process 206s (and return ranges as requested) if the server return ranges in bytes
This is the behavior I am seeing. It's marked "WontFix" so I've worked around it by modifying paginate-anything to pass to
and from
on the query string and my Rails app to copy those values into the request headers before returning 200
instead of 206
.
I know using the range semantics is a big part of this directive's design so I don't expect it to change, but I thought I'd leave a note here. In my application the paginated rows are expensive to load so caching is important.
Point the pagination at a server that sets various types of headers and see if the browser caches the responses. Also investigate if a 206 status affects things. Try in each of
Is there a need for the perPage
watch https://github.com/begriffs/angular-paginate-anything/blob/master/src/paginate-anything.js#L200 if I don't use the perPage dropdown in the template? If not, maybe this watch could be conditional?
This is probably a problem on my end, maybe you can point out what I'm doing wrong.
I'm using your directive inside a directive I've created. The directive lists out a log of activity for users. I put the directive in 2 places, a "general" log that lists activity for all users, and on tab in the user's profile, where it lists out the activity for just that user. My directive accepts a single parameter, the user id, which is set to -1 on the "general" log.
So here's my problem. On the user's profile, I'm passing in the user ID and have a watch setup on it in the controller to update the API URL appropriately (the URL that is passed to your directive.) The trouble is, your directive errors out if I leave the API URL blank, so I have to give it the "all user's" URL w/ the user ID set to -1, but this causes it to hit the API server twice, and for a brief moment, you can see all user activity in the user's tab.
I'll give you some code...
Here's the HTMl that includes my directive:
<admin-activity user-id="{{user._id}}"></admin-activity>
Here's the relevant parts of my directive (in CoffeeScript, I can compile to JS if you need.)
angular.module 'app'
.directive 'adminActivity', ->
templateUrl: 'components/admin-activity/admin-activity.html'
restrict: 'E'
scope: {
userId:'@',
dateTimeFormat: '@'
}
controller: ($scope, $http, $timeout, $attrs) ->
$scope.filter =
apiURL: '/api/logs?user=-1'
perPage: 20
user: $scope.userId
#delay setting up the watches for a short time to let the compiler fill in data
$timeout ->
$scope.$watch 'userId', (u) ->
if u
$scope.filter.apiURL = '/api/logs?user=' + u
$scope.filter.user = u
else
$scope.filter.apiURL = '/api/logs?user=-1'
$scope.filter.user = -1
, 250
And here is the HTML to include your directive (remember, I'm the guy that renamed it to paginateit 😉 )
<paginateit
collection="logs"
url="filter.apiURL"
per-page="filter.perPage"
auto-presets="false"
per-page-presets="[10,20,50,100]"
template-url="/assets/paginate-anything.html">
</paginateit>
So you see, your directive gets '/api/logs?user=-1' no matter what, but then, when there is a user ID, it changes the URL to '/api/logs?user=' and so your directive refreshes. I can shorten the $timeout
, but there will still be 2 hits to the api server.
Any ideas?
Hi,
Just discovered this directive (via ng-newsletter) and it's very good.
I've implemented it in development and plan to use it in production.
I'm well impressed - good job!
One thing I was wanting to do was have the directive "reload" if the url changes.
I don't think it does this? Reading the source I copied a $scope.watch and updated it to read:
$scope.$watch('url', function(newUrl, oldUrl) {
if(newUrl !== oldUrl) {
$scope.gotoPage(0);
}
});
This is just beside/above the page and perPage $scope.$watch's.
I'm not 100% this is the correct and proper but it seems to work the way I need now.
It would be great if my code could show the user some feedback during the server call.
Can the pagination directive add support for a property/event so that I can implement a "loading" indicator?
requestRange emits 'pagination:loadPage' and 'pagination:error'
but needs to emit a 'pagination:loadStart' event.
Alternatively, expose a read-only 'loading' property?
Thanks again for a great directive!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.