Grails pagination on a ArrayList

14 / Sep / 2010 by Vishal Sahu 10 comments

Hi all,


In my recent grails project, i needed to paginate on an array list, so I wrote a function and thought would share it with you all.


public List getFilteredList(int max, int offset) {
    max = Math.min(max ?: 25, 100)
    offset = (offset && offset>0) ?: 0

    List names = getNames() //Loads the complete list
    int total = names.size()
    int upperLimit = findUpperIndex(offset, max, total)
    List filteredNames = names.getAt(offset..upperLimit)
    return filteredNames
  }

  public static int findUpperIndex(int offset, int max, int total) {
    max = offset + max - 1
    if (max >= total) {
      max -= max - total + 1
    }
    return max
  }

So now if offset=20 and max=10, total = 28 so this will generate a list from 21st to 28th elements of the main list.



Hope this helps.



Vishal Sahu
Softare Developer
vishal@intelligrape.com

Tag -

FOUND THIS USEFUL? SHARE IT

comments (10)

  1. mobila ucraina

    I do accept as true with all of the ideas you have presented for your post. They are really convincing and can certainly work. Nonetheless, the posts are very short for newbies. Could you please lengthen them a little from next time? Thank you for the post.

    Reply
  2. Jukesie

    “Thats the dumbest piece of code i’ve seen. You get the entire database then return just the potion you want.
    Fail!!”

    People can be so rude!

    It worked a treat for me thanks.

    Reply
  3. Mark

    Thanks,
    This came in handy for me dealing with the fact that when using named queries with one-to-many children you can get duplicate results. The duplicate results mess up using the list/listDistinct with max/offset.

    I’m not sure if there is a better way to get around the named queries issue, but this works for now.

    Here is my tweaked code:

    public getPaginatedList(list, max, offset) {
    max = Math.min(max ?: 10, 100)
    offset = offset?:0
    int total = list.size()
    int upperLimit = (offset+max>=total?total:offset+max)-1
    return offset<total ? list.getAt(offset..upperLimit) : []
    }

    Reply
  4. omarji

    offset = (offset && offset>0) ?: 0

    This will only work when offset is null or offset is less than 0, in which case it will return 0, otherwise it will return true if I am not mistaken, which is not what you want.

    Reply
  5. Michael

    I had to show paginated list of around 100 cities at all pages on my website. I was adding list as a config property during bootstrap and used similar code to show the paginated view.

    Reply
  6. Vishal Sahu

    Hi Tim, Vacuela

    I never mentioned that I am doing this on a domain class. I would have written MyDomain.list() instead of getNames() to load the complete list.
    In my case, I was reading a list of around 50 values from a csv file and then showing it in a paginated view.

    It would have been a performance hit if there were thousands of rows in file or as you mentioned, if I was loading entire database table.

    Reply

Leave a comment -