Search code examples
grailsgrails-domain-classgrails-controller

grails - show validation error messages on gsp


I have the following domain class:

class User {

    String name
    String contactName
    String primaryEmail
    String url
    String phoneNumber
    String address

    static hasMany = [users: User]

    static constraints = {
        name blank: false
        contactName blank: false
        primaryEmail email: true
        url blank: false
        phoneNumber blank: false
        address blank: false
    }
}

And controller for the User:

class UserController {

    def create() {
        User user = new User()
        [user: user]
    }

    def save(User user) {
        if (!user.save(flush: true)) {
            render (view : 'create', model: [user: user])
        }

        redirect action: 'create'
    }
}

I want show validation errors in case if validation fails. My create.gsp looks like this:

<body>
<g:form action="save" >
    <g:renderErrors bean="${user}"/>
    <g:textField name="user.name" id="message" value="${user.name}"/>
    <g:textField name="user.contactName" id="contactName" value="${user.contactName}"/>
    <g:textField name="user.primaryEmail" id="primaryEmail" value="${user.primaryEmail}"/>
    <g:textField name="user.url" id="url" value="${user.url}"/>
    <g:textField name="user.phoneNumber" id="phoneNumber" value="${user.phoneNumber}"/>
    <g:textField name="user.address" id="address" value="${user.address}"/>

    <g:submitButton name="submit" value="Save"/>
</g:form>

</body>
</html>

But after sumbit of create.gsp with invalid data two strange thing happen 1) Despite the fact that all fields have value property mapped to some field of User bean all fields are empty

2) There are no validation errors on the page What I'm doing wrong? Thank you!


Solution

  • you must return after calling render() or use else

    def save(User user) {
        if (!user.save(flush: true)) {
            render (view : 'create', model: [user: user])
            return // either return here
        }else // or else here
    
        redirect action: 'create'
    }
    

    In your original code you redirect to create and pass no models into it