Search code examples
grailsgsp

grails dynamic select in gsp


Well it's not so dynamic but will change it's contents depending on a set of fields in a domain.

I have 4 prices in 4 fields and then I have a field that point's which price is to be used.

I created a list of those prices to be selected some of the prices can be empty and should not show up in the list.

I used the beforeInsert in the domain where I created the list. But I get only one string with each element separated by a ';' so in the select will contain only one string with all elements.

It must be something with type of list I generated so I need help to know how I should create this list properly.

The domain:

class Author {
    def String name
    def String email
    def BigDecimal price1
    def BigDecimal price2
    def BigDecimal price3
    def BigDecimal price4
    def String choosedCert
    def List<String> availableCert

    static transients = ['availableCert']

    static constraints = {
        name nullable:true
        email nullable:true
        price1 nullable:true
        price2 nullable:true
        price3 nullable:true
        price4 nullable:true
    }

    def beforeInsert() {
       availableCert = getAvailableCert()         
    }

    def List<String> getAvailableCert() {
        def List<String> sl = new ArrayList<String>()
        if (price1 != null) sl.add('FSC')
        if (price2 != null) sl.add('PEFC')
        if (price3 != null) sl.add('CW')
        if (price4 != null) sl.add('UC')
        return sl
    }
}

and the line in the gsp:

<g:select name="choosedCert" from="${author.availableCert}
 "value="${choosedCert}" />

//----------

After correcting my typo:

<g:select name="choosedCert" from="${author?.availableCert}" value='' />

But I still got problems:

When I select 'FSC' I get the value in choosedCert as 'FSC,' and if I then will select a new value e.g. 'UC' I'll get the value as UC,FSC. This is an edit.gsp so after each update I'll get the selected value added to the existing value all time so after updating once more with 'PEFC' selected i'll get 'PEFC,UC,FSC' so the new value is first inserted and then the old value is added after.


Solution

  • Because you're editing the scaffolding view you end up with 2 elements named choosedCert, ideally you'd need to create your own edit.gsp and render only the elements required but as an example I did the following.

    Added an Author in BootStrap like so:

    def init = { servletContext ->
        new Author( name: 'Dave', email: 'myemail', price1: new BigDecimal(1), price2: new BigDecimal(2), choosedCert: 'FSC' ).save( failOnError: true )
    }
    

    Then edit the update action in AuthorController:

    ...
    author.choosedCert = params.availableCert
    author.save flush:true
    ...
    

    Then in edit.gsp:

    ...
    </fieldset>
        <g:select name="availableCert" from="${author.availableCert}" value="${author.choosedCert}" />
    <fieldset class="buttons">
    ...
    

    Clearly this is not ideal because you still have the choosedCert text element rendered by Grails and no styling has been applied to the drop down form element but if you change the drop down and update the correct value will be saved in the domain object's choosedCert. Scaffolding is great for getting things going but does have limitations, eventually you'll end up writing your own gsp's and use services for the transaction leg work.