EPiServer Forms: Adding custom client side validation to form field (Luhn algorithm)

When you’re developing custom EPiServer Forms field blocks you sometimes need to add your own custom validation as well. In this article you’ll see an example of how to add client side validation for the Luhn algorithm in a custom textfield block.

This article assumes that you already have server side validation on your EPiServer Forms field; covered in article EPiServer Forms: Adding custom server side validation to form fields (Luhn algorithm). Creds to my collegue Christer Bermar for his work on this one.

Adding custom client side validation to EPiServer Forms field blocks

Adding client side validation to your custom fields is not that difficult. All you’ll have to do is create a custom JavaScript file in your solution with code like below. The first part of the script only verifies that EPiServer’s scripts were loaded correctly, giving your a useful error message if they weren’t. You’ll have to move all the way down to line 34 for things to get interesting (past the Luhn algorithm which was just added for completion).

forms-validation.js

(function ($) {
  if (typeof (epi) == 'undefined' || typeof (epi.EPiServer) == 'undefined' || typeof (epi.EPiServer.Forms) == 'undefined') {
    console.error('EPiServer Forms was not properly initialized.');
    return;
  }
  if (typeof ($) == 'undefined') {
    console.error('jQuery must be loaded for EPiServer Forms to work.');
    return;
  }

  // takes the form field value and returns true on valid number
  var validateLuhn = function(value) {
    // accept only digits, dashes or spaces
    if (/[^0-9-\s]+/.test(value)) return false;

    // The Luhn Algorithm. It's so pretty.
    var nCheck = 0, nDigit = 0, bEven = false;
    value = value.replace(/\D/g, "");

    for (var n = value.length - 1; n >= 0; n--) {
      var cDigit = value.charAt(n),
      nDigit = parseInt(cDigit, 10);

      if (bEven) {
        if ((nDigit *= 2) > 9) nDigit -= 9;
      }

      nCheck += nDigit;
      bEven = !bEven;
    }
    return (nCheck % 10) === 0;
  }

  var customValidators = {
    Validators: {
      "MyProject.Core.Forms.Validators.LuhnValidator":
        function (fieldName, fieldValue, validatorMetaData) {
          return { isValid: validateLuhn(fieldValue), message: validatorMetaData.model.message };
        },
      "MyProject.Core.Forms.Validators.SomeValidator":
        function (fieldName, fieldValue, validatorMetaData) {
          var validationResult = true;
          return { isValid: validationResult, message: validatorMetaData.model.message };
        }
    }
  };
  $.extend(true, epi.EPiServer.Forms, customValidators);
})(jQuery);

Add your own custom validators as in the bottom of the script above, and then extend EPiServer Form’s existing validator array with them. It is important that you use the fully qualified name for your custom validators (that’s the namespace plus the class name of the validator class in your solution). EPiServer will then automatically map your field’s validator to whatever function you decide to add here. The parameters fieldName and fieldValue are rather self explanatory. The validatorMetaData contains useful things like your validation message as shown above.

Making EPiServer aware of your client side JavaScript validation

To make EPiServer actually run your custom client side validation, you’ll need to register it as an external view mode resource. This may be done by adding a service configuration like below.

FormsViewModeExternalResource.cs

[ServiceConfiguration(ServiceType = typeof(IViewModeExternalResources))]
public class FormsViewModeExternalResource : IViewModeExternalResources
{
  public IEnumerable<Tuple<string, string>> Resources
  {
    get
    {
      return new List<Tuple<string, string>>
      {
        new Tuple<string, string>("script", "/Static/js/forms-validation.js"),
      };
    }
  }
}