Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show enum values on GSP page and then bind them in the database

Tags:

enums

grails

gsp

I have a use case in which I need to first show the value of enum on the GSP page first as a drop down list, have the user select one of those values and then finally bind the data to the domain.

So my code on GSP looks like my enum is MyEnum

<g:select from="${MyEnum.getAllEnumList()}" optionValue="name" name="duration"/>

my enum is

public enum MyEnum {

    MIN15('15 Minutes'),
    MIN30('30 Minutes'),
    HOUR1('1 Hour'),
    HOUR2('2 Hours'),
    HOUR5('5 Hours'),
    HOUR8('8 Hours'),
    HALFDAY('half day'),
    FULLDAY('full day')

    private final String name
    private final String displayName

    public static final List<MyEnum> getAllEnumList() {
        [MIN15,MIN30,HOUR1,HOUR2,HOUR5,HOUR8,HALFDAY,FULLDAY]
    }

    public String toString() {
        return displayName
    }

    MyEnum(String name,String displayName) {
        this.name = name
        this.displayName = displayName;
    }

}

when I hit the page its showing an error like:

Error processing GroovyPageView: Error executing tag <g:form>: Error evaluating expression [MyEnum.getAllEnumList()] on line [37]: java.lang.NoClassDefFoundError: Could not initialize class ENUM.MyEnum at D:/myspace/projects/IcepushpluginSampleApp/grails-app/views/util/test.gsp:46

Any ideas ????

like image 919
Nikhil Sharma Avatar asked Jul 29 '11 11:07

Nikhil Sharma


3 Answers

This is how I have done it in the past. This way you have i18n support.

gsp

<g:select name="duration" from="${MyEnum.values()}" valueMessagePrefix="ENUM.MyEnum" />

messages.properties

ENUM.MyEnum.MIN15=15 Minutes
ENUM.MyEnum.MIN30=30 Minutes
ENUM.MyEnum.HOUR1=1 Hour
ENUM.MyEnum.HOUR2=2 Hours
ENUM.MyEnum.HOUR5=5 Hours
ENUM.MyEnum.HOUR8=8 Hours
ENUM.MyEnum.HALFDAY=half day
ENUM.MyEnum.FULLDAY=full day
like image 118
Nick Larson Avatar answered Oct 27 '22 00:10

Nick Larson


<%@ page import="fully.qualified.path.MyEnum" %>

Try this at the top of your GSP (with the fully qualified path adjusted to your packages, of course).

Edit (this should work (your enum syntax is wrong too)):

<%@ page import="ENUM.MyEnum" %>
<html>
<head>
</head>
<body>
<g:select from="${MyEnum.getAllEnumList()}" optionValue="displayName" name="duration"/>
</body>
</html>

And then the revised class:

package ENUM

public enum MyEnum {

    MIN15('15 Minutes'),
    MIN30('30 Minutes'),
    HOUR1('1 Hour'),
    HOUR2('2 Hours'),
    HOUR5('5 Hours'),
    HOUR8('8 Hours'),
    HALFDAY('half day'),
    FULLDAY('full day')


    private final String displayName

    public static final List<MyEnum> getAllEnumList() {
        [MIN15,MIN30,HOUR1,HOUR2,HOUR5,HOUR8,HALFDAY,FULLDAY]
    }

    public String toString() {
        return displayName
    }

    MyEnum(String displayName) {

        this.displayName = displayName;
    }
}

Edit2:

The easiest way to avoid the whole thing (both the second answer here and my solution) is to simply pass off the value list to the gsp from the controller. Simply add

[duration:MyEnum.values()]

or something similar to your controller return.

like image 39
Oliver Tynes Avatar answered Oct 27 '22 00:10

Oliver Tynes


You can avoid importing in your GSP (which is kind of ugly) if you use a custom tag library. You'll also need to add another method (getKey()) to your enum if you want to have the option key be different from its value.

MyEnum.groovy

enum MyEnum {
    MIN15('15 Minutes'),
    MIN30('30 Minutes'),
    HOUR1('1 Hour'),
    HOUR2('2 Hours'),
    HOUR5('5 Hours'),
    HOUR8('8 Hours'),
    HALFDAY('half day'),
    FULLDAY('full day')

    final String displayName

    private MyEnum(String displayName) {
        this.displayName = displayName
    }

    String getKey() {
        name()
    }

    String toString() {
        displayName
    }
}

MyEnumTagLib.groovy

// add import if MyEnum is in a different package

class MyEnumTagLib {
    static namespace = 'my'

    def enumSelect = { attrs ->
        attrs.from = MyEnum.values()
        attrs.optionKey = 'key'
        out << g.select(attrs)
    }
}

gsp

<my:enumSelect name="duration"/>
like image 43
Rob Hruska Avatar answered Oct 27 '22 00:10

Rob Hruska