Sunday, February 14, 2010

ShareYourLove.com is live!

Our latest Grails powered application is now officially live!

ShareYourLove.com is a creative community where you can upload images of what you love and view other people's loves to raise money for charity. It's a fundraising platform where you don't have to spend a cent of your own money - all donations will be 100% funded by our advertising partners.

Tuesday, October 27, 2009

Wow! Two car related posts in a row!

Here's some in-car footage from the Grafton Hillclimb. It's a short, tight course about 3 hours south of the Gold Coast. They hold 4 or 5 of these each year. Heaps of fun! I set a new PB this trip, beating my old best time by about 5 seconds thanks to better tires and suspension.




Check out Motorsport Photography for heaps of great shots of the events (including me!)

Friday, October 16, 2009

Finally something car related

So I've been very lazy with posting anything car related but finally have something interesting :) Here's some youtube video from my last two outings in the VR4. The first was to a track day at Queensland Raceway and the second was drag racing the following day.



Photobucket



Grails Amazon S3 0.7.4 Released

see http://refactor.com.au/blog/grails-amazon-s3-074-released

Saturday, June 13, 2009

Adding pagination to a Grails WebFlow state

I noticed a few unanswered questions relating to paginating a WebFlow state on the users mailing list and thought I'd post the solution I came up with for a Refactor project I was working on last week.

It basically involves splitting the behaviour into an action and a view state with a transition between them called 'paginate'
loadResults {
 action {
    def criteria = MyDomain.createCriteria(){
        eq('someField','someval')
    }
    flow.myDomainResults  = criteria.list([max: 9, offset: flow.myDomainOffset ?: 0])   
    flow.totalMyDomains = flow.myDomainResults.totalCount
    return success()
 }
 on('success').to('browse')
 on(Exception).to "handleError"
}
browse {
 on('paginate') {
    flow.myDomainOffset = params.offset
 }.to('loadResults')
 on('selectItem').to('someOtherState')
 //...
}
One point to note is that I use a criteria in order to get the totalCount property populated for me automatically so that I don't have to run a separate query. Also, the above only works if your domain class is Serializable, in my real application this wasn't the case so I stored a list of maps containing the properties I wanted to display instead of the list of domain objects.

Then in the view all we need to do is to pass the current page from the flow scope to the paginate tag. The paginate tag also contains an extra parameter in order to trigger the paginate event when the generated links are clicked.
<g:each in="${myDomainResults}" status="i" var="myDomain">
    <g:form action="myFlow">
        <input name="id" value="${myDomain.id}" type="hidden">
        URL: ${myDomain.url}
        <g:submitbutton name="selectItem" value="Select"/>
    </g:form>
</g:each>
<div class="paginateButtons">
   <g:paginate max="9" offset="${myDomainOffset}" total="${totalMyDomains}" params="${[_eventId_paginate:true]}" />
</div>

You can also see I render each item as a separate form with a hidden id field and a submit button to trigger the 'selectItem' event and move onto the next state.

I haven't tried messing with all the options for g:paginate to make sure they still work so please let me know if you find any problems with the above code.