Created
August 30, 2019 06:20
-
-
Save kevintanhongann/0d912951c66e1240a8859fcea4fdab0e to your computer and use it in GitHub Desktop.
Paginate taglib that is themed with Bootstrap 3/4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import grails.util.TypeConvertingMap | |
import grails.web.mapping.UrlMapping | |
import org.springframework.web.servlet.support.RequestContextUtils | |
class BootstrapTagLib { | |
static namespace = "boots" | |
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">${link(attrs, body)}</li>""" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment