Skip to content

Instantly share code, notes, and snippets.

@OsaSoft
Last active January 9, 2018 07:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OsaSoft/b01bf54dc70a75c0d980bbbf13d7c360 to your computer and use it in GitHub Desktop.
Save OsaSoft/b01bf54dc70a75c0d980bbbf13d7c360 to your computer and use it in GitHub Desktop.
Grails 3 using g:paginate with Twitter Bootstrap
import grails.util.TypeConvertingMap
import grails.web.mapping.UrlMapping
import org.grails.plugins.web.taglib.UrlMappingTagLib
import org.springframework.web.servlet.support.RequestContextUtils
class BootstrapTagLib extends UrlMappingTagLib {
Closure paginate = { Map attrsMap ->
TypeConvertingMap attrs = (TypeConvertingMap)attrsMap
def writer = out
if (attrs.total == null) {
throwTagError("Tag [paginate] is missing required attribute [total]")
}
def messageSource = grailsAttributes.messageSource
def locale = RequestContextUtils.getLocale(request)
def total = attrs.int('total') ?: 0
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)
Map linkParams = [:]
if (attrs.params instanceof Map) linkParams.putAll((Map)attrs.params)
linkParams.offset = offset - max
linkParams.max = max
if (params.sort) linkParams.sort = params.sort
if (params.order) linkParams.order = params.order
Map linkTagAttrs = [:]
def action
if (attrs.containsKey('mapping')) {
linkTagAttrs.mapping = attrs.mapping
action = attrs.action
} else {
action = attrs.action ?: params.action
}
if (action) {
linkTagAttrs.action = action
}
if (attrs.controller) {
linkTagAttrs.controller = attrs.controller
}
if (attrs.containsKey(UrlMapping.PLUGIN)) {
linkTagAttrs.put(UrlMapping.PLUGIN, attrs.get(UrlMapping.PLUGIN))
}
if (attrs.containsKey(UrlMapping.NAMESPACE)) {
linkTagAttrs.put(UrlMapping.NAMESPACE, attrs.get(UrlMapping.NAMESPACE))
}
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) as int) + 1
int firststep = 1
int laststep = Math.round(Math.ceil(total / max)) as int
writer << """<div class="dataTables_paginate paging_simple_numbers" id="dataTable_paginate"><ul class="pagination">"""
// display previous link when not on firststep unless omitPrev is true
if (currentstep > firststep && !attrs.boolean('omitPrev')) {
linkTagAttrs.put('class', 'prevLink')
linkParams.offset = offset - max
writer << createPaginationLink((Map)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) {
// determine begin and endstep paging variables
int beginstep = currentstep - (Math.round(maxsteps / 2.0d) as int) + (maxsteps % 2)
int endstep = currentstep + (Math.round(maxsteps / 2.0d) as int) - 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 && !attrs.boolean('omitFirst')) {
linkParams.offset = 0
writer << createPaginationLink((Map)linkTagAttrs.clone()) {firststep.toString()}
}
//show a gap if beginstep isn't immediately after firststep, and if were not omitting first or rev
if (beginstep > firststep+1 && (!attrs.boolean('omitFirst') || !attrs.boolean('omitPrev')) ) {
writer << """<li class="paginate_button page-item"><span class="page-link"><i class="fa fa-ellipsis-h"></i></span></li>"""
}
// display paginate steps
(beginstep..endstep).each { int i ->
if (currentstep == i) {
writer << """<li class="paginate_button page-item active"><span class="page-link">$i</span></li>"""
}
else {
linkParams.offset = (i - 1) * max
writer << createPaginationLink((Map)linkTagAttrs.clone()) {i.toString()}
}
}
//show a gap if beginstep isn't immediately before firststep, and if were not omitting first or rev
if (endstep+1 < laststep && (!attrs.boolean('omitLast') || !attrs.boolean('omitNext'))) {
writer << """<li class="paginate_button page-item"><span class="page-link"><i class="fa fa-ellipsis-h"></i></span></li>"""
}
// display laststep link when endstep is not laststep
if (endstep < laststep && !attrs.boolean('omitLast')) {
linkParams.offset = (laststep - 1) * max
writer << createPaginationLink((Map)linkTagAttrs.clone()) { laststep.toString() }
}
}
// display next link when not on laststep unless omitNext is true
if (currentstep < laststep && !attrs.boolean('omitNext')) {
linkTagAttrs.put('class', 'next')
linkParams.offset = offset + max
writer << createPaginationLink((Map)linkTagAttrs.clone()) {
(attrs.next ? attrs.next : messageSource.getMessage('paginate.next', null, messageSource.getMessage('default.paginate.next', null, 'Next', locale), locale))
}
}
writer << "</ul></div>"
}
private createPaginationLink(Map attrs, Object body) {
def cls = attrs.remove("class") ?: ""
attrs["class"] = "page-link"
"""<li class="paginate_button page-item $cls">${callLink(attrs, body)}</li>"""
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment