Friday, November 13, 2009

Counting Items in GSP with hidden div(s) and g:each

I recently ran into a little problem. I wanted to show a list of books in a list, but also count how many of the books where fiction, and non-fiction. I first thought that should be easy I can pass the information from the controller. I can go through the list count how many of each type of book and pass that to the view.

The problem I had was that the books where sorted in the controller before passing them into the view. So that means I would have to go through the list twice, once to sort and once to count the books. Actually it is another time because the view is showing the entire list. (No pagination - small app ;) )

It dawned on me that I am already iterating over the list in the view. I can count fiction and non-fiction in the <each>tag. But that would mean that I have the counts at the bottom of the page. I wanted the counts at the top of the page. Then I came up with a simple way of putting the count anywhere. I basically put the counts in a <div>at the bottom of the page and then inject the html from the hidden div into a div at the top of the page. Here is an example:

<g:javascript >

$(document).ready (function() {

$("#stats").html($j("#hiddenCalculatedStats").html());

});

</g:javascript>


 

<div id="stats"></div>

<% def counts = [:] %>


 

<g:def var="theList" value="${Book.getSortedList()}" />

<table width="100%" id="whoList">

<tbody>


 

<g:each in="${theList}" status="i" var="book">

<%

if(!counts.get(book.type)) { counts.put(book.type, 0) }

counts[book.type].count++

%>

<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">

        <td>${book.type}</td>

        <td>${book.name}</td>

        <td>${book.author}</td>

</tr>

</g:each>

</tbody>

</table>

<div id="hiddenCalculatedStats" style="display:none">

<ul>

     <g:each var="item" in="${counts}">

     <li>${item.key} - ${item.value}</li>

     </g:each>

</ul>    

</div>    


 

Hope you like this tid bit. And if you have any other I ideas I would like your input.


 

No comments:

Post a Comment