I have a list of Team
objects that have an Integer seed
property. I want to edit all the teams' seeds at once, in a single form. I'm sure that Grails supports indexed parameters, but I can't get it to work.
Here is what I have, and it works but I'm jumping through way too many hoops and there's gotta be a better way.
gsp:
<g:form action="setSeeds">
...
<g:each in="${teams}" status="i" var="team">
<input type="hidden" name="teams[${i}].id" value="${team.id}">
<input type="text" size="2" name="teams[${i}].seed" value="${team.seed}">
</g:each>
</g:form>
controller:
def setSeeds = {
(0..<30).each { i ->
def team = Team.get(Integer.parseInt(params["teams[${i}].id"]))
team.seed = Integer.parseInt(params["teams[${i}].seed"])
}
redirect(action:list)
}
Isn't that awful? Way too much noise. How can I do something along the lines of:
params.teams.each { t ->
def team = Team.get(t.id)
team.seed = t.seed
}
That is, how do I map params named team[0].seed
, team[0].id
, team[1].seed
, team[1].id
to a List?
In Stripes you can just have a List<Team>
property and it will just work. I expect no less from Grails! ;-)
Thanks in advance for your help.
params
is more than a regular Map, it's aGrailsParameterMap
that automatically builds up sub-Map structures based on splitting the parameter names by '.'. You might take advantage of this by using the following gsp:NB: there's no [] in the name attributes. The controller is now pretty simple using some black Grails magic :
The first operation
findAll
filters out all parameters with a dot inside. The rest is a map of maps holding the row id ink
and theid
andseed
inv
.I hope this answers your question.
Not sure if this helps but you could use a closure with it like:
You could probably build a list from this instaed of outputting html. or build your form with it.
I finally figured out how to do this without any shenanigans.
Forget about the hidden parameter and just use the team ID in the seed parameter. In the GSP:
Then, in the controller:
Works like a charm.
In 2015.... Grails works a little differently now and you may find yourself running into strings rather than the expected sub-maps.I got something to work by doing
something like..
EDIT: By The Way...
inputs that have the same name, like
Are put into a List IF more then one are submitted. So if both of the above were checked
You would get a list.
But if only one is checked you do NOT get a List(at least in grails verison I use), you get a single value.
That means in a controller, if I were to do something like
It would throw an error if only one item was submitted. One groovy way to get around this is
If the parameter is set and not a list, it puts the value into the empty list; If the parameter is set and a list, the plus operator will add all the individual values to the empty list; if the parameter is not set, it will add two empty lists together, which creates a single empty list.