views:

136

answers:

4

I have a Contact Domain class that can be associated with multiple Organizations, which are also domain classes. I want to use a multiple selection box to allow the user to select the organizations that are associated with the current contact. The selection box is populated with the available organizations. How do I assign the selected items to the organizations list in my Contact class?

 <g:select name="organizations.id"  multiple="multiple" optionKey="id" from="${com.ur.Organization.list()}" value="${contact?.organizations}" />

The above is what I am currently trying, and while it does populate the selection with organizations it doesn't seem to put the selected items in my organizations field.

Thanks for any advice.

Edit: Incorporated comments from krsjunk and omarello.

Here's an abbreviated version of the domain classes.

class Contact{
    static searchable = true
    static mapping = {
        sort "lastName"
    }
    String firstName
    String lastName
    .  
    .
    .
    static belongsTo = [organizations:Organization, projects:Project]
}

class Organization {
    static searchable = true
    static mapping = {
        sort "name"
    }
    String name
    static hasMany = [contacts:Contact]
}
+1  A: 

one problem is that value="contact?.organizations" should be value="${contact?.organizations}" — not sure if that is the whole problem or not. (also, the attribute multiple=".." is not necessary if value is a collection)

You may also need name="contact.organizations" to be name="contact.organizations.id" and another attribute optionKey="id"

Made the changes but no luck. I did try removing the mulitple, but that made the selection a single line selection so I added it back.
nathan
sorry, without setting up an example it is difficult to see all the pieces… did you try value="${contact?.organizations?.id}" (which should provide a collection of IDs assuming organizations is a list from a hasMany relationship)
You are correct, organizations is a list from a hasMany relationship. I tried using ${contact?.organizations?.id} but still nothing is saved to the list. Could my "from" attribute be returning the "toString" representation of Organization, which would not map to the Organization list?
nathan
A: 

Try changing your name to name="organizations.id"

Micor
+1  A: 

Well just change the name to

<g:select name="organizations"  multiple="multiple" 
          optionKey="id" 
          from="${com.ur.Organization.list()}" 
          value="${contact?.organizations}" />

Should work fine, just tried it.

Note my domain definitions look like this, (just in case you have something different

class Contact {

    static constraints = {
    }

    static hasMany = [organizations:Organization]

    String name
}


class Organization {

    static constraints = {
    }

    static hasMany = [contacts:Contact]
    static belongsTo = [Contact]

    String name
}
omarello
Works great for a single selection, but when I select more than one items I get an exception because the select is returning a list of strings representing the id instead of a list of objects.
nathan
Hmm, do you have an almost similar domain def. as the above. I just tried the sample i created with multiple selection and it seems to work fine, saving and retrieving. What is the exception you get?
omarello
Ah, my hasMany mapping is from Organizations to Contacts. Contacts "belong to" organizations. That seems to be the problem. I'll update the question to better illustrate. Here's the exception anyway. executing action [save] of controller [com.ur.ContactController] caused exception: groovy.lang.MissingMethodException: No signature of method: com.ur.Organization.get() is applicable for argument types: (java.lang.String, java.lang.String) values: [2, 3] Possible solutions: get(java.lang.Object), getId(), getAt(java.lang.String), getAll(), ident(), getLog()Servlet: grails
nathan
A: 

In your newly edit domain example you don't have a one-to-many relationship between contact and organization. You have a one-to-many from organization to contact.

So

value="${contact?.organizations}"

will always be a single item, never a list.

Trying to select/assign multiple organization to a contact will never be valid.

I see your point. How would I go about updating the list of organizations so that they contain a reference to the contact using the organizations selected in the list?
nathan
Yep what krsjunk mentioned is correct, you define contact to belong to an organization, i.e. only one. You need to define a has many in order to achieve what you want. Since a contact can have multiple organizations associated (according to your initial req.)
omarello
If you want multiple organizations associated to a given contact you'll have to change your domain model to look more like the one omarello presented in his answer.
nathan