简体   繁体   中英

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

I prepare a simple gsp with your setup:

Domain class as:

class Author {
    String name
    String email
    BigDecimal price1
    BigDecimal price2
    BigDecimal price3
    BigDecimal price4
    String choosedCert
    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
        choosedCert nullable: true
    }

    def beforeInsert() {
        availableCert = getAvailableCert()
    }

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

Controller as:

class AuthorController {
    static responseFormats = ['json']

    def index() {
        [author: Author.findByName('Dave')]
    }

    def update() {
        println(params)
    }
}

and index.gsp as:

<!DOCTYPE html>
<html>
    <head>
        <meta name="layout" content="main"/>
        <title>Form</title>
    </head>
    <body>
        <g:form controller="author" action="update">
            <g:select name="choosedCert" from="${author?.availableCert}" value='' />
            <g:actionSubmit value="Update" />
        </g:form>
    </body>
</html>

Then when I check the params value in the output: [choosedCert:FSC, _action_Update:Update, controller:author, action:update]

Here , mentioned after FSC is just to seperate choosedCert value from _action_Update

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM