Skip to content

Instantly share code, notes, and snippets.

@halfbaked
Created December 13, 2012 15:25
Show Gist options
  • Save halfbaked/4277107 to your computer and use it in GitHub Desktop.
Save halfbaked/4277107 to your computer and use it in GitHub Desktop.
Rough description of how one might do multiPageTagLib
Closure paginate = { attrs ->
// define new prefix aware keys
def _sort = attrs.prefix? attrs.prefix +"_sort" : 'sort'
def _offset = attrs.prefix? attrs.prefix + "_offset" : "offset"
def _total = attrs.prefix? attrs.prefix + "_total" : "total"
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 ?: 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))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment