Question

I have been updating some of my controllers to use command objects and started down the road of making a PaginateCommand for other command objects to extend.

class PaginateCommand {
    String sort
    String order
    Integer max
    Integer maxsteps
    Integer offset
    Integer total
}

Sub command class

@Validateable
class MyOtherCommand extends PaginateCommand {
    ...    
}

Controller

class SomeController {

    def someService

    def index(MyOtherCommand cmd) {
        someService.loadSomeList(cmd)
        return [cmd: cmd]
    }
}

This all works great and my controllers are now nice and simple. The problem now is the paginate tag is giving me issues. This is what I originally assumed would work:

<g:paginate total="${cmd.total}" params="${cmd.properties}" />

However the paginate tag only looks at the params attached to the request for most values and not the ones passed in on the params attribute. I must manually pass these variables in as attributes like total is above.

All of the pagination variables seem to get removed from the request params when they are bound to the command object (I assume). I would like to keep these variables in the command object so I don't have to pass the request params to my services. Having the controller repopulate the params before rendering also seems counter productive.

Am I stuck having to populate every argument in the paginate tag or is there another way I am missing?

<g:paginate total="${cmd.total}" offset="${cmd.offset}" max="${cmd.max}".... /> 

P.S. I am using Grails 2.3.6

Was it helpful?

Solution

Thanks doelleri. The tag would be simple enough to implement but I ended up using the paginate tag as is. Typically only 3 attributes are needed (total, max, and offset), so I figured it wasn't a big enough issue to introduce a new custom tag. The params attribute on the paginate tag is really designed to pass back request parameters to maintain the state of filters/sorting/etc, so I suppose it makes sense that Grails would not use that to populate the other attributes in the tag.

I did end up adjusting my paginate command class because the subclass had collections and other properties that needlessly cluttered the request parameters. This is what I ended up doing.

abstract class PaginateCommand {
    String sort
    String order
    Integer max
    Integer maxsteps
    Integer offset
    Integer total

    // Properties needed to maintain pagination state
    abstract Map getFilterParams();

    public Map getPaginateParams() {
        return [sort:sort, order:order] << filterParams
    }
}

Sub command

@Validateable
class MyOtherCommand extends PaginateCommand {    
    String filter1
    String filter2
    List data

    public MyOtherCommand() {
        max = 50
        sort = "id"
        order = "desc"
    }

    Map getFilterParams() {
        [filter1: filter1, filter2: filter2]
    }
    ...
}

Controller

def index(MyOtherCommand cmd) {
    someService.loadData(cmd)
    return [cmd: cmd]
}

And in the gsp

<g:paginate total="${cmd.total}" max="${cmd.max}" maxsteps="${cmd.maxsteps}" offset="${cmd.offset}" params="${cmd.paginateParams}" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top