paginate
Purpose
Creates next/previous buttons and a breadcrumb trail to allow pagination of resultsExamples
Example domain class:class Book {
String title
String author
}
Example controller:class BookController {
def list = {
[books: Book.list(params)]
}
}
Paginate code:<g:paginate controller="book" action="list" total="${Book.count()}" />
or<g:paginate next="Forward" prev="Back"
maxsteps="0" controller="book"
action="list" total="${Book.count()}" />
Description
Attributes
total
(required) - The total number of results to paginate
action
(optional) - the name of the action to use in the link, if not specified the default action will be linked
controller
(optional) - the name of the controller to use in the link, if not specified the current controller will be linked
id
(optional) - The id to use in the link
params
(optional) - A map containing request parameters
prev
(optional) - The text to display for the previous link (defaults to "Previous" as defined by default.paginate.prev property in I18n messages.properties)
next
(optional) - The text to display for the next link (defaults to "Next" as defined by default.paginate.next property in I18n messages.properties)
max
(optional) - The number of records displayed per page (defaults to 10). Used ONLY if params.max is empty
maxsteps
(optional) - The number of steps displayed for pagination (defaults to 10). Used ONLY if params.maxsteps is empty
offset
(optional) - Used ONLY if params.offset is empty
Source
Show Source
def paginate = { attrs ->
def writer = out
if (attrs.total == null) {
throwTagError("Tag [paginate] is missing required attribute [total]")
} def messageSource = grailsAttributes.messageSource
def locale = RCU.getLocale(request) def total = attrs.int('total') ?: 0
def action = (attrs.action ? attrs.action : (params.action ? params.action : "list"))
def offset = params.int('offset') ?: 0
def max = params.int('max')
def maxsteps = (attrs.int('maxsteps') ?: 10) if (!offset) offset = (attrs.int('offset') ?: 0)
if (!max) max = (attrs.int('max') ?: 10) def linkParams = [:]
if (attrs.params) linkParams.putAll(attrs.params)
linkParams.offset = offset - max
linkParams.max = max
if (params.sort) linkParams.sort = params.sort
if (params.order) linkParams.order = params.order def linkTagAttrs = [action:action]
if (attrs.controller) {
linkTagAttrs.controller = attrs.controller
}
if (attrs.id!=null) {
linkTagAttrs.id = attrs.id
}
if (attrs.fragment!=null) {
linkTagAttrs.fragment = attrs.fragment
}
linkTagAttrs.params = linkParams // determine paging variables
def steps = maxsteps > 0
int currentstep = (offset / max) + 1
int firststep = 1
int laststep = Math.round(Math.ceil(total / max)) // display previous link when not on firststep
if (currentstep > firststep) {
linkTagAttrs.class = 'prevLink'
linkParams.offset = offset - max
writer << link(linkTagAttrs.clone()) {
(attrs.prev ? attrs.prev : messageSource.getMessage('paginate.prev', null, messageSource.getMessage('default.paginate.prev', null, 'Previous', locale), locale))
}
} // display steps when steps are enabled and laststep is not firststep
if (steps && laststep > firststep) {
linkTagAttrs.class = 'step' // determine begin and endstep paging variables
int beginstep = currentstep - Math.round(maxsteps / 2) + (maxsteps % 2)
int endstep = currentstep + Math.round(maxsteps / 2) - 1 if (beginstep < firststep) {
beginstep = firststep
endstep = maxsteps
}
if (endstep > laststep) {
beginstep = laststep - maxsteps + 1
if (beginstep < firststep) {
beginstep = firststep
}
endstep = laststep
} // display firststep link when beginstep is not firststep
if (beginstep > firststep) {
linkParams.offset = 0
writer << link(linkTagAttrs.clone()) {firststep.toString()}
writer << '<span class="step">..</span>'
} // display paginate steps
(beginstep..endstep).each { i ->
if (currentstep == i) {
writer << "<span class=\"currentStep\">${i}</span>"
}
else {
linkParams.offset = (i - 1) * max
writer << link(linkTagAttrs.clone()) {i.toString()}
}
} // display laststep link when endstep is not laststep
if (endstep < laststep) {
writer << '<span class="step">..</span>'
linkParams.offset = (laststep -1) * max
writer << link(linkTagAttrs.clone()) { laststep.toString() }
}
} // display next link when not on laststep
if (currentstep < laststep) {
linkTagAttrs.class = 'nextLink'
linkParams.offset = offset + max
writer << link(linkTagAttrs.clone()) {
(attrs.next ? attrs.next : messageSource.getMessage('paginate.next', null, messageSource.getMessage('default.paginate.next', null, 'Next', locale), locale))
}
}
}