Forms & Validation demos

Introduction - Single field

Please note :

  • When you're done playing with the form, make sure you scroll to the How-To below the form, a quick tutorial will show you how the demo works.
  • There is no client-side validation in this demo. It's on purpose since we want to demonstrate how server-side validation works and how the Validation Messages can be displayed.
  • The demo is fully functional even when javascript is disabled.

Enter any valid or invalid input in the following field and submit the form to see the validations in action!

You can also try the tests suggested on the right...

You can display (or hide) some elements/sections depending on the validation status of a field or of the form itself. For example :
Fresh
This <div> is only displayed when the form has not been submitted yet (we say the form is "fresh"). This can be validated using the "_" element, which represents the form itself (more info) : {% if validation['demoForm._'] | validationFresh() %}
Validations to test :
  • 1. If the email is valid, we redirect to a new page with a Flash Message. This is a commonly used pattern when a form is valid : the user is redirected to a confirmation page so a "refresh" of the page won't send the POST data again. Fill form
  • 2. If the email is "stay@example.com", the field is valid but we do not redirect to a new page. This is to demonstrate that you can redisplay a form even if all the fields are valid. Fill form
  • 3. If the email is "success@example.com", we do not redirect to a new page and we display a Success Validation Message for the field. Fill form
  • 4. If the email is shorter than 8 characters ("a@b.ca" for example), we display a Warning Validation Message. Notice that the form doesn't become red since a warning is not an error, it doesn't make the form invalid! Fill form
  • 5. If the field is empty, or if it only contains spaces, an Error Validation Message is displayed. The form is invalid and becomes red... Empty form
  • 6. If the email is invalid, an Error Validation Message is displayed. The form is invalid and becomes red... Fill form
  • 7. If the email is "all@example.com" with display three Validation Messages, one for each level : Success, Warning and Error. This is to demonstate that a field can have multiple Validation Messages associated with it. Fill form

Code

How to

The purpose of this demo is to introduce you to the validation of HTML forms using Spincast and to demonstrate how you can use the various Validation Filters. Depending on the value of the "email" field, the controller may add Validation Messages to the response and then redisplay the form, or may redirect you to a confirmation page.

First notice that, in our HTML form, the "name" attribute of the email field is "demoForm.email" :

<input type="text" 
       class="form-control" 
       id="email" 
       name="demoForm.email" 
       placeholder="Email"
       value="{{demoForm.email | default('')}}">

You can learn in the Retrieving the submitted form section of the document that Spincast uses the names of the fields to build a JsonObject representing the submitted form :

public void singleFieldSubmit(AppRequestContext context) {

    Form form = context.request().getFormOrCreate("demoForm");
    context.response().addForm(form);

//...

Note that we could also have retrieved the email field directly, using its full "demoForm.email" JsonPath :


String email = context.request().getFormData().getString("demoForm.email");

But, in general, it's way easier to get the form data as a Form object and then deal with it!

Now that we have the form, we are going to validate it. A Form object is a simple JsonObject but with extra validation features. We can retrieve elements from it, validate those elements, and add validation messages. For example :


String email = form.getString("email");

if (StringUtils.isBlank(email)) {
    form.addError("email",
                  "email_empty",
                  "The email is required");
}

Notice that we use "email" as the JsonPath to target the element we want to validate [2]. Since the form object is the root element we started the validation on, we have to use a JsonPath relative to it.

When the validation is done, we check if the form contains any errors and, if so, we redisplay it with its associated Validation Messages. To do so, we single call the GET handler (named "singleField(...)" in this demo) from the POST handler :

if(!form.isValid()) {
    singleField(context);
    return;  
} else {
    //...
}

(Note that the actual code of this demo is slightly different, simply because we wanted to show that a form can be redisplayed even if it is valid.)

If the form is valid, you want to redirect the user to a confirmation page, using a Flash message :

if(!form.isValid()) {
    //...
} else {

    // No errors! We process the form data, using
    // services, respositories, etc.
    // processForm(form)...
    
    // And then we redirect to a confirmation page
    context.response().redirect(FlashMessageLevel.SUCCESS,
                                "The form has been processed successfully.");
}

The last step of the validation process is to redisplay the form with the resulting Validation Messages, in your template, when it contains errors.

To help you, Validation Filters are provided :


<div class="form-group {{validation['demoForm.email'] | validationClass()}}">
    <label for="email" class="col-sm-4 control-label">Email *</label>
    <div class="col-sm-8">
        <input type="text" 
               class="form-control" 
               id="email" 
               name="demoForm.email" 
               placeholder="Email"
               value="{{demoForm.email | default('')}}">
        {{validation['demoForm.email'] | validationMessages()}}
        
        <div class="validationsDirectBtnDiv">
            <button id="subBtn" type="submit" class="btn btn-primary">Submit</button>
        </div>    
    </div>
</div>

Since we added the form to the response model using context.response().addForm(form), our template has access to the validation messages through a "validation" element. From this element, we get the Validation Messages associated with our field using the "demoForm.email" key and we pass the result to the validationClass() and validationMessages() filters.

  • The validationClass() filter outputs an appropriate CSS class name, depending on the result of the validation.
  • The validationMessages() filter format and output the Validation Messages themselves. The HTML template fragment to use is configurable.

Notice that we also use the default() filter which is provided by Pebble out of the box : {{demoForm.email | default('')}}. This will fill the email field with the submitted value, or will fallback to an empty string if that value doesn't exist on the model.

The last thing we also demonstrate in this demo is how to display some HTML elements/sections or not, depending on the result of the validation. For example, using the validationHasWarnings() filter, we check if the email contains Warning Validation Messages and, if so, we display a special <div> element :


 {% if validation['demoForm.email'] | validationHasWarnings() %}
     <div class="well niceWell warning">
         <div class="niceWellTitle">Warning</div>
         This <code>&lt;div&gt;</code> is displayed because the following condition is true :
         {% verbatim %}<code class="snippet">{% if validation['demoForm.email'] | validationHasWarnings() %}</code>{% endverbatim %}
     </div>
 {% endif %}

Make sure you read the Validation Filters section of the documentation to see what are the filters related to validation, and how to use them!

More info

Learn everything about forms and validation in the dedicated Forms section of the documentation.