Nathan Russell
Nathan Russell

Reputation: 3668

Ajax validation with Spring Webflow 2

I wonder if anyone can help. I'm putting together a Spring Webflow app, and am trying to work out what to do for validation.

As per the documentation http://static.springsource.org/spring-webflow/docs/2.0.x/reference/html/ch04s10.html I've created a validator class which conforms to the name pattern of ${model}Validator and with method names which conform to validate${state}

// validation method for About You
public void validateAboutYou(QB2MotorQuote p_quote, ValidationContext p_ctx) {
    MessageContext messages = p_ctx.getMessageContext();

    // mandatory checks ...
    mandatoryChecks_AboutYou(p_quote, messages);

    // field format/content validation checks ...
    formatChecks_AboutYou(p_quote, messages);

}

As shown in the above code, I call out to 2 methods to perform mandatory checks, then format checks.

This works fine - when the page is submitted, SWF invokes the validation class - excellent :)

What I would like to do now though is invoke the formatChecks_AboutYou(p_quote, messages) method via ajax. As the user blurs each field, I want to fire an ajax request to validate that field, thereby having all my validation code and rules serverside.

I cant find anything written about how to do with with SWF. I've done something very similar with a standard Spring MVC app, where I had a request mapping on my controller specifically for ajax validation. The beauty of this is that the controller already had a reference to the validator, and the data had been bound to the form backing object.

But I'm not sure how to go about this with SWF. I have tentatively played with the idea of writing a controller for ajax validations:

@Controller
public class AjaxController {

@Autowired
private QuoteValidator m_validator;

@RequestMapping(value="/AjaxValidate", method=RequestMethod.GET)
public String ajaxValidate(HttpServletRequest p_req, Model p_model) {

    // controller has access to validate via autowired m_validate
    // but the method signature I want to call is:
    //   formatChecks_AboutYou(QB2MotorQuote p_quote, MessageContext p_messages)
    // Don't know where to get a MessageContext from

    return "ajaValidate";
}
}

I'll be able to call this from the client side no problem, but I doubt the data will be bound to the command object, and I'm not sure where I'll get the MessageContext object from.

If anyone could help with this I'd be very grateful; Cheers

Nathan

Upvotes: 1

Views: 983

Answers (1)

Jose Muanis
Jose Muanis

Reputation: 557

First you need to define global transitions that don't transition to any place and render a fragment

<transition on="forgotPassword">
   <evaluate expression="mybean.forgotPassword(flowRequestContext)" />
   <render fragments="forgotPassword"/>
</transition>

The validate method will run when you transition to this

private void validateForgotPassword(ValidationContext context) {
   String event = context.getUserEvent();
   Object formObject = null;
   String formName = null;
   GenericFormValidator formValidator = new GenericFormValidator(validator);
   if (StringUtils.equalsIgnoreCase(event, "forgotPassword")) {
      formObject = this.getForgotPasswordForm();
      formName = "forgotPasswordForm";
      formValidator.perform(context, formObject, formName, ForgotPasswordForm.DefaultValidationGroup.class);
   }
}

And you need your chunks defined on tiles

<definition name="pages.guest.info" extends="master-layout">
    <put-attribute name="bodyId" value="guest-info" />
    <put-attribute name="body" value="/WEB-INF/jsp/pages/guest-info.jsp"/>

    <!-- specified for ajax reloading by webflow-->
    <put-attribute name="forgotUsernamePassword" value="/WEB-INF/jsp/pages/guest/chunks/request-login.jsp"/>
    <put-attribute name="forgotPassword" value="/WEB-INF/jsp/pages/guest/chunks/forget-password.jsp"/>

    <put-attribute name="jsPageBundle" value="/bundles/guest.js" />

    <put-list-attribute name="css" inherit="true">
        <add-attribute value="/bundles/module.guest.css" /> 
    </put-list-attribute>

    <put-list-attribute name="js" inherit="true">
        <add-attribute value="/js/pages/guest-flow.js" />
  </put-list-attribute>

</definition>

Hope that this is a starting point.

Upvotes: 1

Related Questions