JSR 303 Bean Validation + Javascript Client-Side Validation JSR 303 Bean Validation + Javascript Client-Side Validation spring spring

JSR 303 Bean Validation + Javascript Client-Side Validation


I would suggest that you look at Spring JS, which relies heavily on Dojo. A tutorial can be found here.

Easiest way for yourself to start playing with it is to download Spring Roo, create the petclinic sample application with one of the example-scripts (this takes you 5 minutes) and then play around with how the javascript is integrated. Spring Roo creates an app with the same technology stack that you use (Spring+hibernate+implementation of jsr 303)


I found this open source project but it looks dead, maybe it is worth resurrecting.

http://kenai.com/projects/jsr303js/pages/Home

This library provides client side validation of an HTML form based on JSR-303 and Hibernate Validator annotations, integrated with Spring MVC. The library provides a JavaScript validation code base that handles basic interaction with HTML forms, as well as JavaScript functions implementing the validation annotations supported by Hibernate Validator (including those not from the JSR-303 spec). This JavaScript code base can be included in a page by using a provided taglib or by extracting the JavaScript file from the jar and including it using a tag. Once this code base has been included in a page, a second taglib is used to generate the JavaScript code for validating an HTML form. You can also provide a JSON object in the body of the tag to specify additional configuration information.


Here's how I'm doing it using Spring MVC + JQuery + Bootstrap, partially based on a recent blog post at SpringSource:

AddressController.java

@RequestMapping(value="/validate")public @ResponseBody ValidationResponse processForm(Model model, @Valid AddressForm addressForm, BindingResult result) {    ValidationResponse res = new ValidationResponse();    if (result.hasErrors()) {        res.setStatus("FAIL");        for (ObjectError error : result.getAllErrors()) {            if (error instanceof FieldError) {                FieldError fieldError = (FieldError) error;                res.addError(fieldError.getField(), fieldError.getDefaultMessage());            }            }    }    else {        res.setStatus("SUCCESS");    }    return res;}

AddressForm.java

public class AddressForm {    @NotNull    @Size(min=1, max=50, message="Address 1 is required and cannot be longer than {max} characters")    private String address1;    @Size(max=50, message="Address 2 cannot be longer than {max} characters")    private String address2;    // etc}

ValidationResponse.java:

public class ValidationResponse {    private String status;    private Map<String,String> errors;    // getters, setters}

address.jsp:

<f:form commandName="addressForm">    <div class="control-group">        <label for="address1">Address 1</label>        <div class="controls">            <f:input path="address1" type="text" placeholder="Placeholder Address 1" class="wpa-valid" />            <span class="help-inline"></span>        </div>    </div>    <!-- etc -->    <div class="form-actions">        <button type="submit" class="btn btn-primary">Save</button>        <button type="button" class="btn">Cancel</button>    </div></f:form><script type="text/javascript">function collectFormData($fields) {    var data = {};    for (var i = 0; i < $fields.length; i++) {        var item = $($fields[i]);        data[item.attr("id")] = item.val();    }    return data;}function clearErrors($fields) {    for (var i = 0; i < $fields.length; i++) {        var item = $($fields[i]);        $("#"+item.attr("id")).parents(".control-group").removeClass("error");        $("#"+item.attr("id")).siblings(".help-inline").html("");    }}function markErrors(errors) {    $.each(errors, function(key, val) {        $("#"+key).parents(".control-group").addClass("error");        $("#"+key).siblings(".help-inline").html(val);    });}$(document).ready(function() {    var $form = $("form.validate");    $form.bind("submit", function(e) {        var $fields = $form.find(".validate");        clearErrors($fields);        var data = collectFormData($fields);        var validationUrl = "validate";        $.get(validationUrl, data, function(response) {            $("#alert").removeClass();            if (response.status == "FAIL") {                markErrors(response.errors);                $("#alert").addClass("alert alert-error");                $("#alert").html("Correct the errors below and resubmit.");            } else {                $("#alert").addClass("alert alert-success");                $("#alert").html("Success!");                $form.unbind("submit");                $form.submit();            }        }, "json");        e.preventDefault();        return false;    });});</script>

It could use some refactoring, but this will do an ajax GET with the form data and update the page based on the result.