Date field validation with constraints and formvalidationJS in ColdBox


When developing web forms or applications, server and client side user input validations should be on every developers’ mind. In this quick guide we will provide a simple code example to illustrate how we can use ColdBox’s domain model constraint on the server side, and formvalidationJS and momentJS on the client side to perform some basic date field validations.

Firstly, let’s tackle server side validation using domain model constraints in ColdBox. Let’s create the Coldbox domain model for clients and add the constraints for the date of birth (dob) field:


component persistent="true" extends="BaseEntity" table="clients" {
  property name="client_id" fieldtype="id" generator="identity" setter="false";
  property name="title" sqltype="nvarchar" length="10";
  property name="firstname" sqltype="nvarchar" length="100";
  property name="lastname" sqltype="nvarchar" length="100";
  property name="dob" ormtype="date";
  property name="gender" sqltype="nvarchar" length="6";

  //validations
  this.constraints = {
    firstname = {required=true, requiredMessage="First Name is required"},
    lastname = {required=true, requiredMessage="Last Name is required"},
    gender = {required=true, requiredMessage="Gender is required"},
    dob = {
      required=true, requiredMessage="DOB is required",
      type="date", typeMessage="DOB must be a valid date",
      discrete="lte:#now()#", discreteMessage="DOB cannot be in the future"}
   } //constraints
}

The dob field has three constraints: required, type and discrete. That is, dob is required, has to be of type date and cannot be a date that is in the future. We are adding a custom message when the constraint fails. To add your own custom messages for specific constraints, use this constraint message convention:

{constraintName}Message = "My Custom Message";

So in our code above, we have the following custom messages for the constraints of required, type, and discrete:

  • requiredMessage=”DOB is required”
  • typeMessage=”DOB must be a valid date”
  • discreteMessage=”DOB cannot be in the future”

For more information on constraints, head over to the ColdBox wiki validation page.

Let’s test the dob field constraints before we add the client side validations. Here’s the error message if you select a future date for the dob field and submitted the update:

dob-model-future-constraint-error

Now let’s add client side validations for the dob field. We will need to do the following:

  • Add references to formvalidationJS and momentJS in the Main layout (layouts/Main.cfm)
  • In the view page where the dob field is used, we will need to add the necessary script to validate it using formvalidationJS and momentJS

In the head and body of layouts/Main.cfm, add the following to reference the required JavaScript libaries and frameworks:


<head>
<link href="/path/to/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/ >
<link href="/path/to/bootstrap/bootstrap-dialog.min.css" rel="stylesheet" type="text/css" />
<link href="/path/to/bootstrap/formvalidation/css/formValidation.min.css" rel="stylesheet" />
<link href="/path/to/bootstrap/bootstrap-datepicker/css/bootstrap-datepicker.min.css" rel="stylesheet" />
<link href="/path/to/bootstrap/bootstrap-datepicker/css/bootstrap-datepicker3.min.css" rel="stylesheet" />
</head>
<body>

<script src="/path/to/jquery/jquery.min.js"></script>
<script src="/path/to/bootstrap/js/bootstrap.min.js"></script>
<script src="/path/to/bootstrap/formvalidation/js/formValidation.min.js"></script>
<script src="/path/to/bootstrap/formvalidation/js/framework/bootstrap.min.js"></script>
<script src="/path/to/bootstrap/bootstrap-datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="/path/to/moment.js"></script>

</body>

Then in the add/edit view page (i.e. edit.cfm) for the client domain model, towards the bottom of the page, add the part in the script section to perform client side validation using formvalidationJS and momentJS:


<form class="form-horizontal" role="form" id="frmClientEdit" method="post" action="#event.buildLink('clients.save')#">
 <div class="form-group required">
   <label for="dob" class="col-md-3 control-label">DOB &nbsp;</label>
   <div class="col-md-2 date">
    <div class="input-group input-append date" id="dpDOB">
     <input type="text" class="form-control" name="dob"  value="#dateFormat(rc.client.getDOB(), 'dd/mm/yyyy')#" placeholder="dd/mm/yyyy"/>
     <span class="input-group-addon add-on"><span class="glyphicon glyphicon-calendar"></span></span>
    </div>
   </div>
 </div>
</form>

<script>
$(document).ready(function() {
  $('#dpDOB').datepicker({
        format: 'dd/mm/yyyy'
  })
  .on('changeDate', function(e) {
        // Revalidate the dob field
        $('#frmClientEdit').formValidation('revalidateField', 'dob');
  });
  $('#frmClientEdit').formValidation({
    framework: 'bootstrap',
      icon: {
      valid: 'glyphicon glyphicon-ok',
      invalid: 'glyphicon glyphicon-remove',
      validating: 'glyphicon glyphicon-refresh'
    },
    fields: {
      dob: {
        validators: {
          notEmpty: {
            message: 'DOB is required and cannot be empty'
          },
          date: {
            message: 'The value is not a valid date',
            format: 'DD/MM/YYYY'
          },
          callback: {
            message: 'This date is in the future and invalid',
            callback: function(value, validator) {
              var m = new moment(value, 'DD/MM/YYYY', true);
              var now = moment();
              if (!m.isValid()) {
                return false;
              }
              return m.isBefore(now);
           } //callback
         } //validators
       } //dob
     }//fields
   }); //formvalidation
}); //document

To ensure that dob is not a date in the future, we use formvaliationJScallback feature in conjunction with momentJS. We compare the selected date value with current date and time. If it is greater, an error message is displayed to alert the user.

We’ve also add the re-validation for the dob field so that formvalidationJS re-validate this field when users clicks the calendar to re-select the dob. The result for validation when it fails and succeeds are:

dob-client-side-future-date-error-1

dob-client-side-future-date-error-2

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s