Skip to content

Instantly share code, notes, and snippets.

@kritzikratzi
Created November 19, 2011 18:58
Show Gist options
  • Save kritzikratzi/1379217 to your computer and use it in GitHub Desktop.
Save kritzikratzi/1379217 to your computer and use it in GitHub Desktop.
Play pagination
class ExampleController{
public static void search( String query, String someParam, int page ){
// get search results ...
// usually you end up with this:
int total = ... // total number of results
List<Item> results, = ... // subset of results
// now create pagination info
PaginationInfo paginationInfo = new PaginationInfo(
"ExampleController.search", // action
page, // current page
15, // items per page
total, // total number of results
new String[]{ "query", "someParam" } // query params to be included in the links
);
render( total, results, paginationInfo );
}
bla bla bla... include your main template, etc.
*{add top pagination }*
#{pagination paginationInfo /}
*{list items }*
#{list ... }
*{add bottom pagination }*
#{pagination paginationInfo /}
package utils;
import java.util.LinkedList;
import java.util.List;
/**
* Helps a bit with the paging.
* This class (as the name suggests) doesn't generate any html,
* but just holds information about the paging.
*
* @author hansi
*/
public class PaginationInfo implements Cloneable{
// what's the current page? (starting at 1)
public int page;
// what's the action url (e.g. Application.listSomething)
public String action;
// what params from the current request should be included in the links?
// e.g. if you're paging over a search and your textfield is named "q",
// then you should call: paginationInfo.addParams( "q" ).
// this will take the current value from the request parameters and includ it
// in the link, so it's point to /application/listSomething?q=the_value&page=3
public LinkedList<String> params = new LinkedList<String>();
// number of items per page, i think 15 is an awsome default
public int perPage = 15;
// number of result items
public int numItems;
public PaginationInfo(){
}
public PaginationInfo( String action, int page, int perPage, int numItems, String ... params ){
action( action ).page( page ).perPage( perPage ).numItems( numItems ).addParams( params );
}
/**
* Set the action (url, e.g. Application.doSomething)
* Allows method chaining
*/
public PaginationInfo action( String action ){
this.action = action;
return this;
}
/**
* Set the current page
* Allows method chaining
*/
public PaginationInfo page( int page ){
this.page = page;
return this;
}
/**
* Set the number of items visible per page
* Allows method chaining
*/
public PaginationInfo perPage( int perPage ){
this.perPage = perPage;
return this;
}
/**
* Set total number of result items
* Allows method chaining
*/
public PaginationInfo numItems( int numItems ){
this.numItems = numItems;
return this;
}
/**
* Add query parameters' names which should be included in links
* Allows method chaining
*/
public PaginationInfo addParams( String ... params ){
for( String param : params ){
this.params.add( param );
}
return this;
}
/**
* Add query parameters' names which should be included in links
* Allows method chaining
*/
public PaginationInfo addParams( List<String> params ){
this.params.addAll( params );
return this;
}
/**
* Validates and returns the current page.
* This requires numItems and perPage to be set to function correctly.
* @return
*/
public int getPage(){
return Math.max( 1, Math.min( page, getNumPages() ) );
}
/**
* Calculates and returns the total number of pages.
* This requires numItems and perPage to be set to function correctly.
* @return
*/
public int getNumPages(){
return 1 + (int)Math.floor( ( numItems - 1 )/(float)perPage );
}
@Override
protected PaginationInfo clone() throws CloneNotSupportedException {
return new PaginationInfo( action, page, perPage, numItems ).addParams( params );
}
}
*{
Pagination thingie,
based on http://groups.google.com/group/play-framework/browse_thread/thread/32f9e6f5ff6152a6?pli=1
The main argument needs to be a paginationinfo object,
use like #{pagination paginationInfo /}
Look at that class to see how it's members affect this output.
Optional arguments:
- id: [] an id for the div wrapped around
- first: [<<] label for the "first" link
- last: [>>] label for the "last" link
- previous: [<] label for the "previous" link
- next: [>] label for the "next" link
- radius: [4] how many pages to display left/right of the current page
- clazz: [] additional css class for outer div, the "pagination" class is always added.
}*
<div class="pagination ${_clazz}" id="${_id}">
%{
def page = {
args = new java.util.HashMap<String, Object>()
args.put('page', it)
//args.put('zip', params.get( "zip" ) )
_arg.params.each{ p -> args.put( p, params.get( p ) ) }
play.mvc.Router.getFullUrl(_arg.action, args)
}
pageCount = _arg.getNumPages()-1;
first = (_first == null || _first == '') ? '&laquo;' : _first;
previous = (_previous == null || _previous == '') ? '&lsaquo;' : _previous;
next = (_next == null || _next == '') ? '&rsaquo;' : _next;
last = (_last == null || _last == '') ? '&raquo;' : _last;
radius = (_radius == null )? 4 : _radius;
if (_arg.page != 1) {
out.println('<a class="first" rel="1" href="' + page(1) +'">' + first + '</a>');
out.println('<a class="previous" rel="' + (_arg.page-1) + '" href="' + page(_arg.page - 1) + '">' + previous + '</a>');
}
for (int i = Math.max( 1, _arg.getPage() - radius ); i <= Math.min( pageCount, _arg.getPage() + radius ); i++) {
if (i != _arg.getPage() ){
out.println('<a rel="' + i + '" href="' + page(i) + '">' + i + '</a>' );
}
else {
out.println('<span class="current">' + i + '</span>');
}
}
if (_arg.page != pageCount) {
out.println('<a class="next" rel="' + i + '" href="' + page(_arg.getPage() + 1) + '">' + next + '</a>');
out.println('<a class="last" rel="' + i + '" href="' + page(pageCount) + '">' + last +'</a>');
}
}%
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment