Grails pagination is not working properly in index page - grails

I am working with Grails 2.4.2. I have a view page named distGameList where I am showing the distributed game list. So when the list is over than 10 it should place other values in next page. But It's not doing it. In-fact It is creating 2 pages. I have 12 rows in that table. Now in view page 2 page is showing that's OK. But 12 rows is showing each pages although it should show 10 rows at first page and 2 rows in second page. Here are my steps below ::
in my controller ::
def distGameList(){
def distributedGameList = AndroidGameDist.getAll()
[distributedGameListInstance : distributedGameList, androidDistGameInstanceCount: AndroidGameDist.count()]
}
and in my view where paginate tag after ending table tag ::
<div class="pagination">
<g:paginate total="${androidDistGameInstanceCount ?: 0}" />
</div>

Use list for pagination and pass params in it.
def distributedGameList = AndroidGameDist.list(params)
or
Use this for more readable code:
def distributedGameList = AndroidGameDist.list(max: params.max ?: 10, offset: params.offset ?: 0)

Related

Pagination : First page displays all the result

I want to display the results of a queries on several pages, so I use the tag pagination.
I have correct outputs (I want 5 result per page) in all the pages but the first one.
In the first page, all results are displayed.
Controller :
def questions(){
def questions = Question.list(params)
[questions: questions, total: Question.count()?:0, tags: Tags.list(), params: params]
}
View
<g:each in="${questions}" var="question">
<div class="row">
${question?.body }
</div>
</g:each>
<div class=pagination>
<g:paginate controller="Question" action="list" total="${total}" max="5" params="${params}"/>
</div>
Why do I have all results in the first page ?
This happens because params has no max value.
setting params.max = 10 and then invoking questions() would result in 10 items for the first page.
// will result in Question.list(max: 10)
def questions = Question.list(params)
But, make sure if same action is called again for subsequent pages then params.max has to be set to 5 or totally removed because max from <g:paginate> would take care of the rest.
You can add following line at the beginning of your controller action:
params.max = params.max ?: 5
If no max parameter is given the default value will be 5.

How do I render a map in Grails view

Lets say I have a map like this ( which is returning from a controller)
a= [a:[1,2,3,4],b:[5,6,7,8],c:[9,10]]
[a] //returning [a] from controller to the view
Now in Grails view, how should I render them so that they look something like this in my browser :
a
-- 1
-- 2
-- 3
-- 4
b
-- 5
-- 6
-- 7
-- 8
//so on..
Edit:
I did something like this on a particular case of displaying the details(with hint got from the answer given by Antoine) :
<html>
<head>
<title>
All Tasks.
</title>
<meta name ="layout" content="main" />
</head>
<body>
<h2>All the task</h2>
<g:each in="${tasksByDate}" var ="tasks">
<h4>${tasks.key}</h4>
<g:each in="${tasksByDate.value}" var="content" >
<div id = "todayswork">
${content}
</div>
<hr/>
</g:each>
<br />
</g:each>
</body>
</html>
But when I render it in my browser, I'm getting only the heading in my browser. Like this :
All the task
//other contents missing. . .
And I'm sure that from the controller alltasks the value is passing to the view, with the name tasksByDate. As it is printing it on my console like this :
[2011-12-19 14:21:35.949:[Belongs to Schedule Finish task A], 2011-12-21 14:21:35.897:[Belongs to Schedule Finish task A], 2011-12-23 14:21:35.907:[Belongs to Schedule Finish task A], 2011-12-19 14:21:36.051:[Belongs to Schedule Finish task A], 2011-12-17 14:21:36.048:[Belongs to Schedule Finish task A]]
Here is my controller code :
def alltasks = {
def allTasks = DaySchedule.findAllByTaskIsNotNull()
def tasksByDate = [:]
tasksByDate.putAll(
allTasks.groupBy {
it.Todaysdate
}
)
println tasksByDate
[tasksByDate]
}
Where I'm making mistake?
Thanks in advance.
You can iterate over a map elements using g:each. The key method of a map element will return the key (a, b, c in your example) and the value method will return the associated value (in your case, a list of integers). In turn you can use g:each on this list.
Here is what I would do in GSP:
<ul>
<g:each var="mapElement" in="${a}">
<li>$mapElement.key
<ul>
<g:each in="${mapElement.value}" var="number">
<li>$number</li>
</g:each>
</ul>
</li>
</g:each>
</ul>
Based on your formatting I deduced that you want to present your map as a list of lists, hence the nested <ul> elements.
In your controller, replace the last line of the allTasks action :
[tasksByDate]
... by ...
[tasksByDate : tasksByDate]
The return of a controller action (as far as I know) should be a map, not a list. The key is the name of the variable that you will retrieve in the GSP, the value is the contents of that variable.
See http://grails.org/doc/latest/guide/single.html#controllers, chapter 6.1.3 Models and Views

.NET MVC - List and Detail Views

I think there is a simple answer to this, but for some reason I am hitting a writers block today. I have an app which people can search (like any app :) ) and generate a list view. From that list view, you can view details, which will take you to a details view. No JS, just another page. But, what I would like to do is to have a back/next button within the details view so that you can parse the result set without having to go back to the list and then select the next record.
I have had two ideas on accomplishing this. Idea 1) Have a next/previous record field in my custom class. However, this wouldn't work as the search query will not necessarily return consecutive results and I would have to query the DB each time to get those next/prev listings. Idea 2) Have a list of IDs or some custom object passed in the view state for each detials view corresponding to the search results. On this one, I am not sure of the 'overhead' associated with this method.
Any suggestions from the SO community?
Thanks!
Construct the link that opens the details view so that it has next and previous parameters that contain a list of the previous/following elements as well as the id of the current element. Probably easiest to do if you iterate through the list model data by index rather than using foreach -- that way you just reference the previous/next element relative to the current element when finding their ids. Make sure to handle the first and last elements correctly.
In your controller action the next/previous parameters should be nullable -- if you don't get there from the list, you don't render the next/previous buttons. You could "post" the details view action and put the extra parameters in the form rather than the URL so the user can still bookmark the url. Note that this has it's own issues though with regards to the browser's back/forward button and refreshing.
<% for (int i = 0, len = Model.Count(); i < len; ++i)
{
Foo model = Model.ElementAt(i);
string prev = i == 0 ? null : string.Join( ",", Model.Take(i).Select( m => m.ID.ToString() ).ToArray() );
string next = i == (len - 1) ? null : string.Join( ",", Model.Skip(i).Select( m => m.ID.ToString() ).ToArray() )
%>
<% using (Html.BeginForm("Details","Bar", new { id = model.ID } )) { %>
<%= Html.AntiForgeryToken() %>
<%= Html.Hidden( "Prev", prev ) %>
<%= Html.Hidden( "Next", next ) %>
<input type="submit" value="Details" />
<% } %>
<% } %>
I would probably also use some jQuery to change the input button to a link that submits the enclosing form with a click event handler, but that's just my preference for the UI.

Grails: problem with paging and ordering in a view template

How do I structure my pages and partial templates so that Ajax will play nice with <paginate> and column sorting?
I currently have a search.gsp page with a remoteField that calls a controller to update a template. This all works fine. However, the column sorting and paging actions cause my search.gsp to be completely replaced by the template view.
From my search.gsp:
<div id="searchBox">
Enter a key or phrase: <g:remoteField name="searchBox"
update="resourceSearchResultPanel" paramName="q"
url="[controller:'resourceEntry',action:'searchForResources']"
/>
</div>
<div id="resourceSearchResultPanel" />
My controller handles the search request like so:
def searchForResources = {
params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
params.offset = params.offset ? params.offset.toInteger() : 0
log.debug "Handling search post action"
def q = params.q ?: null
log.debug "Search phrase is $q"
def searchResults
if (q) {
searchResults = [
results: ResourceEntry.search(q,[offset: params.offset, max: params.max]),
resultCount: ResourceEntry.countHits(q),
q: q.encodeAsHTML()
]
}
render(template:"resourceSearchResultPanel",model:searchResults)
}
The _resourceSearchResultPanel.gsp is just a table with this <paginate> tag:
<g:paginate action="searchForResources" total="${resultCount}" params='["q":"${q}"]' />
The problem is that when the <paginate> tag calls the controller, the entire page is refreshed with the contents of the _resourceSearchResultPanel.gsp template, while I just want the _resourceSearchResultPanel.gsp itself to be refreshed inside search.gsp.
There's no update attribute like there is in the remoteField tag...
The paginate tag doesn't support generating ajax links so you'll have to write your own verison of the tag that calls remoteLink instead of link.
cheers
Lee
I would suggest to you remote pagination plugins for Grails. This would suffice your requirement. For more details please refer to following site:-
http://www.grails.org/plugin/remote-pagination
Please feel free to revert incase of any concern.

Groovy: Sorting Columns in a view: list

I have a Groovy application. I am rendering the view list using the following statement:
render (view: 'list', model:[reportingInstanceList: reportingInstanceList, reportingInstanceTotal: i, params: params])
The list.gsp is as follows:
The view is rendered but the default sorting is not working.
<g:sortableColumn class="tabtitle" property="id" title="Id" titleKey="reporting.id" />
<g:sortableColumn class="tabtitle" property="company" title="Company" titleKey="reporting.company" />
Unfortunately the default sorting (by id, by company, etc) are not working.
Any hint why?
Thanks a lot in advance.
Luis
If you are asking about the sorting/order links at the top of the columns on the list page, the links are hrefs back to the controller and method that was originally used to populate the list. Plus the URLs include parameters for sort and order. For instance:
/tracker/bug/searchCurrentUserProject?sort=name&order=asc
The controller method will then need to handle the sort and order values from the link:
params.sort = params.sort ?: "priority"
params.order = params.order ?: "asc"
And pass them to the database query:
def bugList = Bug.createCriteria().list(
sort:params.sort,
order:params.order,
max:params.max,
offset:params.offset) {
eq "projectId", new Integer (params.projectId)
}
You can add two hidden fields in your form, set them dynamically with Javascript and send them together with your form.

Resources