## 6.5.5 Data Binding and Validation

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">
        <!-- Other fields -->
        <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"
    }