Sitecore Content authorable error messages for form validation in MVC

I have created a form to get user input in Sitecore MVC application, it has different validation assigned like
  • Required Field Validation
  •  Regex validation
 I have created a model for this Form objects and assigned the Out of the box.Net DataAnnotations Attributes along with the error message, but my business requested that these error messages need to be content authorable, but with this.Net out of the box we can’t achieve it, So I have created custom Attribute to manage these error messages from Sitecore.

Before we dive in to create the custom attribute, it is necessary to have an item in Sitecore with all error messages for the fields that we going to use in the form, I have created an item with all necessary fields, but we can also go with Sitecore dictionary etc.

Sitecore Item for error messages:




So, let’s start creating the custom attributes to display content authorable error messages.
·         I’m going to create two Attributes one for Required filed validation and other for Regex validation like email address
      
       Attribute Creation:
  • Create a class for Required field named SitecoreRequiredField and inherit from RequiredAttribute
  •  It also implements IClientValidate interface, It is very important that in order to have the validation also to occur on the client side, without implementing validation will only take place on the server side. 
  • Override IsValid method to assign the error message from Sitecore. I have create a method(ValidationErrorMsg.GetErrorMessage) to retrieve message from Sitecore.

        Required Attribute: SitecoreRequiredField

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Sitecore.Data.Items;
using System.Text.RegularExpressions;

namespace CustomAttribute
{
    public class SitecoreRequiredField : RequiredAttribute, IClientValidatable
    {
        private string fieldName;
        public SitecoreRequiredField(string fieldName)
        {
           
            this.fieldName = fieldName;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            // Get the error message for this property
            ErrorMessage = ValidationErrorMsg.GetErrorMessage( fieldName, ErrorMessage);

            return base.IsValid(value, validationContext);
        }
// For client side validation

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var modelClientValidationRule = new ModelClientValidationRule
            {
                ValidationType = "sitecorerequiredfield",
                ErrorMessage = ValidationErrorMsg.GetErrorMessage( fieldName, ErrorMessage)
            };
            modelClientValidationRule.ValidationParameters.Add("required", metadata.PropertyName);
            return new List<ModelClientValidationRule> { modelClientValidationRule };
        }
    }
}
  
RegEx Attribute : SitecoreRequiredField
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;

namespace CustomAttribute
{

    public class SitecoreRegEx : ValidationAttribute, IClientValidatable
    {
       
        private string fieldName;     

        public string pattern { get; set; }

        public SitecoreRegEx(string fieldName, string regExpattern)
        {
            this.fieldName = fieldName;
            this.pattern = regExpattern;
        }

        public override bool IsValid(object value)
        {
            string input = value.ToString();
            bool valid = true;
            Regex regex = new Regex(@pattern);
            if (!String.IsNullOrEmpty(input))
            {

                Match match = regex.Match(input);
                if (!match.Success)
                {
                    valid = false;
                    ErrorMessage = ValidationErrorMsg.GetErrorMessage( fieldName, ErrorMessage);
                }
            }
            return valid;
        }

      
// For client side validation
        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var modelClientValidationRule = new ModelClientValidationRule
            {
                ValidationType = "sitecoreregex",
                ErrorMessage = ValidationErrorMsg.GetErrorMessage( fieldName, ErrorMessage)
            };
            modelClientValidationRule.ValidationParameters.Add("regexpattern", @pattern);
            return new List<ModelClientValidationRule> { modelClientValidationRule };
        }
    }
}


Helper Class: To get Error messages from Sitecore.

using Sitecore.Data.Items;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CustomAttribute
{
    public class ValidationErrorMsg
    {
  
        public static string GetErrorMessage(string fieldName, string ErrorMessage)
        {
            string message = null;
            Item item = Sitecore.Context.Database.GetItem("/sitecore/Content/SiteName/Data/ErrorMessages", Sitecore.Context.Language);
            if (item != null && item.Versions.Count > 0)
            {
                message = item[fieldName];
            }
            if (string.IsNullOrWhiteSpace(message))
            {
                message = ErrorMessage;
            }
            return message;
        }
    }
}

Now its time to Add these custom Attributes to Model.
I have also assigned default error message to the attribute, it will be used when no error message available in the Sitecore item.

public class SubscribeModel
    {
    
        [SitecoreRequiredField("FullNameRequiredMsg", ErrorMessage = "Please enter full name.")]
        [SitecoreRegEx("FullNameValidationMsg", "^[a-zA-z .]*$", ErrorMessage = "Alphabet only in the Name.")]
        public virtual string FullName { get; set; }

        [SitecoreRequiredField("ContactNumberRequiredMsg", ErrorMessage = "Please enter contact number.")]
        [SitecoreRegEx("ContactNumberValidationMsg", "^[0-9 ]*$", ErrorMessage = "Numeric only for Phone number")]
        public virtual string ContactNumber { get; set; }

        [SitecoreRequiredField("EmailRequiredMsg", ErrorMessage = "Valid Email address required.")]
        [SitecoreRegEx("EmailValidationMsg", @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", ErrorMessage = "Valid Email address required.")]
     
        public virtual string Email { get; set; }

By now our Form will successfully validate the input and will throw content authored error messages from Sitecore. But all will happen only in server side. In order to make it also work with client side, we need to do few more things apart from the method(IEnumerable<ModelClientValidationRule> GetClientValidationRules) implementation.

Client Side Validation:
We need to add two important jquery plugins to enable client-side validation

·          
Create two javascript file with the same name as( ValidationType = "sitecoreregex") in GetClientValidationRules method
  • ·         sitecoreregex.js
  • ·         sitecorerequiredfield.js


 Open sitecoreregex.js and add the below script.
$.validator.unobtrusive.adapters.addSingleVal("sitecoreregex", "regexpattern");
$.validator.addMethod('sitecoreregex', function (value, element, params) {
    if (value != null && value != "") {
        var patternMatch = new RegExp(params);
        if (patternMatch.test(value)) {
            return true;
        }
        else
            return false;
    }   
    return true;
}, '');

Open sitecorerequiredfield.js and add the below script.
$.validator.unobtrusive.adapters.addSingleVal("sitecorerequiredfield", "required");
$.validator.addMethod('sitecorerequiredfield', function (value, element, params) {
    if (value != null && value != "") {
        return true;
    }
    else
        return false;
  
}, '');


Now let's try to submit the form to check the validation triggers from the client side, But still, it not triggers from the client side, Ah I have to add two Appsetting to make it work at client side in the web.config file.

<appSettings>
    <add key="ClientValidationEnabled" value="true"/>
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>

Output:

That’s it 😊

Comments

Popular posts from this blog

Custom Item Url and resolving the item in Sitecore - Buckets

Exploring Sitecore XM Cloud Forms: A Comprehensive Overview

Sitecore Custom Rule (Action and Condition)