In the section on
start and end states, the start state in the first example triggered a transition to the
enterPersonalDetails
state. This state renders a view and waits for the user to enter the required information:
enterPersonalDetails {
on("submit").to "enterShipping"
on("return").to "showCart"
}
The view contains a form with two submit buttons that either trigger the submit event or the return event:
<g:form action="shoppingCart">
<g:submitButton name="submit" value="Continue"></g:submitButton>
<g:submitButton name="return" value="Back"></g:submitButton>
</g:form>
However, what about the capturing the information submitted by the form? To to capture the form info we can use a flow transition action:
enterPersonalDetails {
on("submit") {
flow.person = new Person(params)
!flow.person.validate() ? error() : success()
}.to "enterShipping"
on("return").to "showCart"
}
Notice how we perform data binding from request parameters and place the
Person
instance within
flow
scope. Also interesting is that we perform
validation and invoke the
error()
method if validation fails. This signals to the flow that the transition should halt and return to the
enterPersonalDetails
view so valid entries can be entered by the user, otherwise the transition should continue and go to the
enterShipping
state.
Like regular actions, flow actions also support the notion of
Command Objects by defining the first argument of the closure:
enterPersonalDetails {
on("submit") { PersonDetailsCommand cmd ->
flow.personDetails = cmd
!flow.personDetails.validate() ? error() : success()
}.to "enterShipping"
on("return").to "showCart"
}