Search code examples
listgrailssavegsp

Grails many to many passing multiple values from gsp to controller to save


I have a many to many relationship between forms and events, in a list using a join table and when I display the data in edit mode I show each item in its own dropdown in a table as opposed to one multi select dropdown list. I also have a little jQuery in there to add extra dropdowns in if I want to add more items, My question is, how do I then save back this set of "events", in order? Code is as follows: -

Initial _form.gsp to load all linked events for the form: -

   <table id="eventList">
        <g:each in="${formInstance?.events}" status = "i" var="item">
            <tr class="${(i % 2) == 0 ? 'even' : 'odd'}">
                <td>
                    <label></label>
                    <g:select name="event_${i}" from="${framework.Event.list()}" required="required" optionKey="id" value="${item.id}" />
                </td>
            </tr>
        </g:each>
    </table>

Additional objects are added with this gsp

<tr class="${((newRow+1) % 2) == 0 ? 'even' : 'odd'}">
    <td>
        <label></label>
            <g:select name="event_${newRow-1}" from="${framework.Event.list()}" required="required" optionKey="id" />
    </td>
</tr>

The save button currently is as such: -

<g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />

And the Update action is unchanged from the one generated automatically from the domain setup. How do I get the save to recognise the new fields added? Currently hitting save does to the "events", even if I change the order...

Domain Classes are as such

import java.util.List;

class Form {
    static constraints = {
        formDesc(blank:false,maxSize:100,unique: true)
    }

    static mapping = {
        table "form"
        version false
        columns{
            id column:"form_id"
            formDesc column:"description"
            testscenarios joinTable:[name:"lnk_scenario_form",key:'form_id']
            events joinTable:[name:"lnk_form_event",key:'form_id']
        }
    }

    String formDesc
    List events

    static hasMany = [testscenarios:TestScenario, events:Event]
    static belongsTo = fartframework.TestScenario

    String toString (){
        "${formDesc}"
    }
}

And

class Event {
       static constraints = {
           eventTypeID()
           eventOrder()
           objectID()
           testDataID()
        }

    static mapping = {
        table "event_form"
        version false
        columns{
            id column:"event_form_id"
            eventTypeID column:"event_id"
            eventOrder column:"event_order"
            testDataID column:"test_data_id"
            objectID column:"object_id"

            forms joinTable:[name:"lnk_form_event", key:'event_id']
        }
    }

    EventType eventTypeID
    Integer eventOrder
    TestData testDataID
    Object objectID

    static hasMany = [forms:Form]
    static belongsTo = fartframework.Form

    String toString (){
        "${eventTypeID}"
    }
}

Solution

  • Turns out this was because my link table had a primary key set on both the form_id AND event_id combination columns, which I don't care about as I WANT to be able to have duplicates in there (as its the order that's more important), removing these primary key values on the table solved the problem!

    I do still have the issue that if I now add/remove a bunch of times I get problems with identical names and the issues that represents, but I can work round that one with some jquery hacking (I hope)...