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.
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.