Search code examples
grailspropertiesindexed

Grails indexed parameters


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 got to 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! ;-)


Solution

  • 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:

    <g:form action="setSeeds"> 
    ... 
      <g:each in="${teams}" var="team"> 
        <input type="text" size="2" name="teams.seeds.${team.id}"
          value="${team.seed}"> 
      </g:each> 
    </g:form> 
    

    Then, in the controller:

    params.teams.seeds.each { teamId, seed ->
      def team = Team.get(teamId.toInteger())
      team.seed = seed.toInteger()
      team.save()
    }
    redirect(action:list)
    

    Works like a charm.