17
Mar
2016

Custom validators with Episerver Forms

A few weeks ago Episerver Forms was released. We have seen several blogs about creating custom forms types like a Color Picker or a Constrained Textbox.
But what about creating your own validators?

To create you own validator simply inherit from ElementValidatorBase.
You can also use RegularExpressionValidatorBase, which itself inherits from ElementValidatorBase, if you want to use a regular expression for validation.

In this example I will validate a Dutch postal code.

public class ZipCodeValidator : RegularExpressionValidatorBase
{
    public override IValidationModel Model
    {
        get
        {
            if (_model == null)
            {
                string str = "^[1-9][0-9]{3}\s?[a-zA-Z]{2}$";
               _model = GetRegularExpressionValidationModel(str, str);
            }
            return _model;
        }
    }
}

We override the model to set our regular expression.
The GetRegularExpressionValidationModel takes two argument. One regex string for DotNet (dotnetPattern) and one regex string for JavaScript (jsPattern).

Add the following lines to you language file. Use the full namespace of your validator.

<episerver>
  <forms>
     <validators>
        <FormsDemo.Business.Validation.ZipCodeValidator>
          <displayname>ZipCode (1234 AB)</displayname>
          <message>This is not a valid zipcode</message
        </FormsDemo.Business.Validation.ZipCodeValidator>
    </validators>
  </forms>
</episerver>

After compiling, the new validator is immediately available in the UI.

However it will only give us server side validation, so we need to register our validator for client side validation.

When you look at the EpiserverForms.js file you will see that all the client side validators are added to the Validator list.
So we have to add our validator too. This can be done with a fews line of JavaScript

(function ($) {
    if (typeof (epi) == 'undefined' || typeof (epi.EPiServer) == 'undefined' || 
        typeof (epi.EPiServer.Forms) == 'undefined') {
        console.error('Forms is not initialized correctly');
        return;
    }
    if (typeof ($) == 'undefined') {
        console.error('Forms cannot work without jQuery');
        return;
    }

    var _utilsSvc = epi.EPiServer.Forms.Utils;

    /// add buildin implementation of validators
    /// ========================================
    var customValidators = {
        Validators: {
            //For regular expression validators
            "FormsDemo.Business.Validation.ZipCodeValidator": 
                _utilsSvc.validateRegularExpressionValidator
            //For other validator
            //"the.full.namespace.of.your.validator" : 
            //    function (fieldName, fieldValue, validatorMetaData){
            // summary:
            //      VALIDATE REQUIRED
            // fieldName: String
            //      Name of the field to be validated.
            // fieldValue: [Object]
            //      User input value for the field.
            // validatorMetaData: [Object]
            //      Validation meta data for the current element
            // returns: Object
            // tags:
            //      private
            // See EpiserverForms.js for examples
            // }
        }
    };
    $.extend(true, epi.EPiServer.Forms, customValidators);
})($epiforms || $);  // use the Forms's jQuery before using site's jQuery

Again, be sure to use the full namespace of your validator.

Now that we have the JavaScript in place we have to make sure it it loaded when forms are used. This can be done by implementing IViewModeExternalResources

[ServiceConfiguration(ServiceType = typeof(IViewModeExternalResources))]
public class FormsViewModeExternalResource : IViewModeExternalResources
{
    public IEnumerable<Tuple<string, string>> Resources
    {
        get
        {
            var arrRes = new List<Tuple<string, string>>
            {
                new Tuple<string, string>("script", 
                    "/ClientResources/ViewMode/FormsValidators.js"),
            };
            return arrRes;
        }
    }
}

That’s it! We now have both server and client side validation!

Share

You may also like...