I want to display all games under a certain category in pagination (10/page)
This is my controller
def listGame(){
def category = GameCategory.list()
def platform = Platform.list()
def currentCategory = params.categoryName
def myCategory=GameCategory.findByCategoryName(currentCategory)
def games = myCategory.games
[currentCategory:currentCategory, category:category, games:games, platforms:platform, gameCount:Game.count(), chosenPlatform:params.platform]
}
and this is my pagination code in my view
<g:each in="${games}" status="i" var="game">
${game.gameTitle}
</g:each>
<div class="pagination">
<g:paginate action="listGame" total="${gameCount}" />
</div>
When I have 9 games in the current category the page 12 showed up wherein it shouldn't
When I have 11 games in the current category all 11 games are displayed in page 1 and clicking page 2 will result in this error
There are a couple of things to address.
- Make sure
categoryName
is not coming into the controller as null
.
- Make use of the
max
and offset
parameters that the paginator is providing to select the appropriate Game
s.
The category name
Because the paginator is creating the URL that calls into the controller, and your controller needs the category name, the paginator must add the category name to the params it calls the controller action with. You can achieve this with the tag's params
attribute:
<g:paginate action="listGame" total="${gameCount}" params="${[categoryName: currentCategory]}"/>
Max & offset
The controller needs to use max
and offset
parameters to know what subset of the Game
s to retrieve from the database and render in the view. However, in some cases, such as when visiting the URL http://blah/someController/listGame, there would be no max
and offset
params. This is something your controller action must be able to handle. It goes something like this:
def max = params.max ?: 10
def offset = params.offset ?: 0
So the max
and offset
params will be used if they are available. Otherwise they'll use default values.
Finally, you need to use these parameters to select the Game
s. For that you can use a where query:
def games = Game.where {
categories.categoryName == currentCategory
}.list(max: max, offset: offset)
Something interesting about the returned games
object: It acts like a list, but it's actually a grails.gorm.PagedResultList
. That's a good thing because it contains the total number of records in the result (ignoring max and offset). In other words, it's your new gameCount
.
You can read more about where queries in the Grails documentation. I also have a series of articles which cover where, criteria and HQL queries in more detail.
Putting it all together, listGame()
would look like this:
def listGame(){
def category = GameCategory.list()
def platform = Platform.list()
def currentCategory = params.categoryName
def max = params.max ?: 10
def offset = params.offset ?: 0
def games = Game.where {
categories.categoryName == currentCategory
}.list(max: max, offset: offset)
[currentCategory:currentCategory, category:category, games:games, platforms:platform, gameCount:games.totalCount, chosenPlatform:params.platform]
}
Looks like you haven't done your homework. Please go through grails doc and other tutorials, to understand how pagination works.
Just to give you a hint. You are doing two things wrong here.
- You are not getting a paginated list at the first place from controller
- You are not sending back all the required data back to the controller, from the pagination link. And that's the reason you are getting the error!