Grails(9)Guide Book Chapter 7 The Web Layer Web Flow
7.5 Web Flow
Grails supports the creation of web flows built on the Spring Web Flow project.
To install a plugin
>grails install-plugin webflow
7.6 Filters
Although Grails controllers support fine gained interceptors. There are only really useful when applied to a few controllers and become difficult to manage with larger applications. Filters on the other hand can be applied across a whole group of controllers, a URI space or to a specific action.
7.7 Ajax
<g:javascript library="jquery" />
7.7.1.1 Remoting Linking
<g:remoteLink action="delete" id="1">Delete Book</g:remoteLink>
<g:remoteLink update="[success: 'message', failure: 'error']"
action="delete" id="1">
Delete Book
</g:remoteLink>
7.7.1.3 Remote Form Submission
<g:formRemote url="[controller: 'book', action: 'delete']"
update="[success: 'message', failure: 'error']">
<input type="hidden" name="id" value="1" />
<input type="submit" value="Delete Book" />
</g:formRemote>
Data Centric Ajax with JSON
import grails.converters.JSON
def showBook(){
def b = Book.get(params.id)
render b as JSON
}
Data Centric Ajax with XML
import grails.converters.XML
def showBook(){
def b = Book.get(params.id)
render b as XML
}
Responding to both Ajax and non-Ajax requests
It's straightforward to have the same Grails controller action handle both Ajax and non-Ajax requests. Grails adds the isXhr() method to HttpServletRequest which can be used to identify Ajax requests.
7.8 Content Negotiation
8. Validation
8.1 Declaring Constraints
class User {
String login
String password
String email
Integer age
static constraints = {
login size: 5..15, blank: false, unique: true
password size: 5..1, blank: false
email email: true, blank: false
age min: 18
}
}
8.2 Validating Constraints
def user = new User(params)
if(user.validate()){
…snip...
}else{
user.errors.allErrors.each {
println it
}
}
Validation Phases
def user = new User(params)
if(user.hasErrors()){
if(user.errors.hasFieldErrors("login")) {
println user.errors.getFieldError("login").rejectedValue
}
}
By default the save method calls validate before executing, allowing us to write code like this:
if(user.save()){
return user
}else{
user.errors.allErrors.each {
println it
}
}
Importing Constraints
class User {
String firstName
String lastName
String passwordHash
static constraints = {
firstName blank: false, nullable: false
lastName blank: false, nullable: false
passwordHash blank: false, nullable: false
}
}
class UserCommand {
String firstName
String lastName
String password
String confirmPassword
static constraints = {
importFrom User
password blank: false, nullable: false
confirmPassword blank: false, nullable: false
}
}
8.4 Validation on the Client
Displaying Errors
<g:renderErrors bean="${user}" /> // this can render the errors list.
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li>${err}</li>
</g:eachError>
</ul>
</g:hasErrors>
Highlighting Errors
<div class=‘value ${hasErrors(bean:user, field: 'login', 'errors')}’>
<input type="text" name="login" value="${fieldValue(bean:user, field:'login'}" />
</div>
If there is error, there should be errors CSS in the div.
Also, we restore the value input by the user using the fieldValue tag
8.5 Validation and Internationalization
8.6 Applying Validation to Other Classes
References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html#webflow
http://grails.org/doc/latest/guide/validation.html
7.5 Web Flow
Grails supports the creation of web flows built on the Spring Web Flow project.
To install a plugin
>grails install-plugin webflow
7.6 Filters
Although Grails controllers support fine gained interceptors. There are only really useful when applied to a few controllers and become difficult to manage with larger applications. Filters on the other hand can be applied across a whole group of controllers, a URI space or to a specific action.
7.7 Ajax
<g:javascript library="jquery" />
7.7.1.1 Remoting Linking
<g:remoteLink action="delete" id="1">Delete Book</g:remoteLink>
<g:remoteLink update="[success: 'message', failure: 'error']"
action="delete" id="1">
Delete Book
</g:remoteLink>
7.7.1.3 Remote Form Submission
<g:formRemote url="[controller: 'book', action: 'delete']"
update="[success: 'message', failure: 'error']">
<input type="hidden" name="id" value="1" />
<input type="submit" value="Delete Book" />
</g:formRemote>
Data Centric Ajax with JSON
import grails.converters.JSON
def showBook(){
def b = Book.get(params.id)
render b as JSON
}
Data Centric Ajax with XML
import grails.converters.XML
def showBook(){
def b = Book.get(params.id)
render b as XML
}
Responding to both Ajax and non-Ajax requests
It's straightforward to have the same Grails controller action handle both Ajax and non-Ajax requests. Grails adds the isXhr() method to HttpServletRequest which can be used to identify Ajax requests.
7.8 Content Negotiation
8. Validation
8.1 Declaring Constraints
class User {
String login
String password
String email
Integer age
static constraints = {
login size: 5..15, blank: false, unique: true
password size: 5..1, blank: false
email email: true, blank: false
age min: 18
}
}
8.2 Validating Constraints
def user = new User(params)
if(user.validate()){
…snip...
}else{
user.errors.allErrors.each {
println it
}
}
Validation Phases
def user = new User(params)
if(user.hasErrors()){
if(user.errors.hasFieldErrors("login")) {
println user.errors.getFieldError("login").rejectedValue
}
}
By default the save method calls validate before executing, allowing us to write code like this:
if(user.save()){
return user
}else{
user.errors.allErrors.each {
println it
}
}
Importing Constraints
class User {
String firstName
String lastName
String passwordHash
static constraints = {
firstName blank: false, nullable: false
lastName blank: false, nullable: false
passwordHash blank: false, nullable: false
}
}
class UserCommand {
String firstName
String lastName
String password
String confirmPassword
static constraints = {
importFrom User
password blank: false, nullable: false
confirmPassword blank: false, nullable: false
}
}
8.4 Validation on the Client
Displaying Errors
<g:renderErrors bean="${user}" /> // this can render the errors list.
<g:hasErrors bean="${user}">
<ul>
<g:eachError var="err" bean="${user}">
<li>${err}</li>
</g:eachError>
</ul>
</g:hasErrors>
Highlighting Errors
<div class=‘value ${hasErrors(bean:user, field: 'login', 'errors')}’>
<input type="text" name="login" value="${fieldValue(bean:user, field:'login'}" />
</div>
If there is error, there should be errors CSS in the div.
Also, we restore the value input by the user using the fieldValue tag
8.5 Validation and Internationalization
8.6 Applying Validation to Other Classes
References:
http://grails.org/doc/latest/guide/index.html
http://grails.org/doc/latest/guide/theWebLayer.html#webflow
http://grails.org/doc/latest/guide/validation.html