import org.springframework.validation.Errors;
import org.springframework.context.NoSuchMessageException;
import org.springframework.web.servlet.support.RequestContextUtils as RCU;
import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU
import com.opensymphony.module.sitemesh.PageParserSelector
import com.opensymphony.module.sitemesh.Factory
import org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine
import org.springframework.web.context.ServletConfigAware
import javax.servlet.ServletConfig
import org.springframework.beans.factory.InitializingBean;
import org.codehaus.groovy.grails.web.sitemesh.FactoryHolder
class DemoTagLib {
/**
* Creates next/previous links to support pagination for the current controller
*
*
*/
def remotePaginate = { attrs ->
def writer = out
if(attrs.total == null)
throwTagError("Tag [paginate] is missing required attribute [total]")
def messageSource = grailsAttributes.getApplicationContext().getBean("messageSource")
def locale = RCU.getLocale(request)
def total = attrs.total.toInteger()
def action = (attrs.action ? attrs.action : (params.action ? params.action : "search"))
def offset = params.offset?.toInteger()
def max = params.max?.toInteger()
def maxsteps = (attrs.maxsteps ? attrs.maxsteps.toInteger() : 10)
if(!offset) offset = (attrs.offset ? attrs.offset.toInteger() : 0)
if(!max) max = (attrs.max ? attrs.max.toInteger() : 10)
def linkParams = [offset:offset - max, max:max]
if(params.sort) linkParams.sort = params.sort
if(params.order) linkParams.order = params.order
if(attrs.params) linkParams.putAll(attrs.params)
if(params.searchStr) linkParams.searchStr = params.searchStr
if(params.searchDate) linkParams.searchDate = params.searchDate
if(params.searchField) linkParams.searchField = params.searchField
def linkTagAttrs = [action:action,'update':attrs.update]
if(attrs.controller) {
linkTagAttrs.controller = attrs.controller
}
if(attrs.id!=null) {
linkTagAttrs.id = attrs.id
}
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'
writer << remoteLink(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 << remoteLink(linkTagAttrs.clone()) {firststep.toString()}
writer << '..'
}
// display paginate steps
(beginstep..endstep).each { i ->
if(currentstep == i) {
writer << "${i}"
}
else {
linkParams.offset = (i - 1) * max
writer << remoteLink(linkTagAttrs.clone()) {i.toString()}
}
}
// display laststep link when endstep is not laststep
if(endstep < laststep) {
writer << '..'
linkParams.offset = (laststep -1) * max
writer << remoteLink(linkTagAttrs.clone()) { laststep.toString() }
}
}
// display next link when not on laststep
if(currentstep < laststep) {
linkTagAttrs.class = 'nextLink'
linkParams.offset = offset + max
writer << remoteLink(linkTagAttrs.clone()) {
(attrs.next ? attrs.next : messageSource.getMessage('paginate.next', null, messageSource.getMessage('default.paginate.next', null, 'Next', locale), locale))
}
}
}
/**
* Renders a sortable column to support sorting in list views
*
* Attributes:
*
* property - name of the property relating to the field
* defaultOrder (optional) - default order for the property; choose between asc (default if not provided) and desc
* title (optional*) - title caption for the column
* titleKey (optional*) - title key to use for the column, resolved against the message source
* params (optional) - a map containing request parameters
* action (optional) - the name of the action to use in the link, if not specified the list action will be linked
* Attribute title or titleKey is required. When both attributes are specified then titleKey takes precedence,
* resulting in the title caption to be resolved against the message source. In case when the message could
* not be resolved, the title will be used as title caption.
*
* Examples:
*
*