views:

53

answers:

3

Is there a way to break out of a <g:each>? I have a page wherein I'm iterating through a list and I have to make sure that a checkbox is checked if that was the value stored in DB.

To make it a little clearer, please consider something like:

<g:each in=${list1}>
    <g:each in=${list2}>
        <g:if test="${list1.id == list2.id}">
            <input type="checkbox" ... checked="checked" />
        </if>
    </g:each>
    ...
</g:each>

where list1 is, say Domain1.list() (i.e. ALL possible values) and list2 is Domain2.find(...) (i.e. SELECTED values)

In the g:each, I need to display ALL of list1 (hence, the "..." after the inner each) with a checkbox but I need to make sure that those in list2 (user-selected items that were saved to DB) should be checked accordingly (if statement).

Now, if the checked status was changed on the first iteration, i need to get out of the inner each... any way to do this?

Thanks!

+1  A: 

Nope, not with the each clause.

I'd just write my own taglib that takes list1 and list2 and does the iteration for you, yielding back to the

<g:eachCheckedItem list1="${list1}" list2="${list2}">
    <input type="checkbox" ... checked="checked"/>
</g:eachCheckedItem>

And in your taglib class:

def eachCheckedItem = { attrs, body ->
    def list1 = attrs.list1
    def list2 = attrs.list2

    list1.findAll { list2.contains(it) }.each {
        out << body(listItem: it)  // access to listItem variable inside gsp
    }

}

Something like that (tuned to your specific problem) is easy to write, and also cleans up your gsp file quite a bit. I use these kinds of custom iterators all the time in my taglibs.

Ted Naleid
ah, ok... i'll look into this more. Thanks!!
callie16
A: 

If I understood you correctly, you need something like this:

<g:each var="elem1" in="${list1}">
   <g:if test="${list2.any{it.id==elem1.id}}">
     <input type="checkbox" checked="checked" />
   </g:if>
   ...
</g:each>

There is no g:any tag, but as Ted pointed out, it would be easy to write one (left as an exercise to the reader). Then you could simplify the the inner tag to something like this:

<g:any test="${it.id==elem1.id}" in="${list2}">...</g:any>
hlg
+1  A: 

You should do this in the model, so you then only have a simple loop in the view. Then it's just a matter of making the controller call Domain.findMyList() or whatever.

Emyr