Flexible date validation for Sitecore Forms based on a current date

Currently, the Date form element  that comes with Sitecore Forms out of the box allows to set start and end date properties, which corresponds to the earliest and the latest acceptable date available in a date picker. A user will not be able to select a day that does not fall within the range. Though, it is only possible to select a fixed/predefined date.

There can be scenarios when you would want to set such restrictions, but rather based on a current date. For example, to set the earliest available date for  a product delivery to be three days after a current date (a day on which the order is placed), or to set the latest available date to pick up an order to be a month after a current date (a day on which the order is placed). Below you can see an example of how to implement a custom Date form element together with a custom validation to be able to set start and end date restrictions based on a current date.

From Sitecore Forms Designer client application perspective, the idea is to add a new custom Date form element with two additional Integer fields (number of days after current date) to let  forms authors/editors to set start and end date based on a current date:

ExtendedDateFormElement

After these settings are applied, the corresponding restrictions will be reflected in a date picker, making it possible to choose a day only if it falls withing the range. If a negative number is selected, it will be considered as a day before a current day. Additionally, a custom validation has to be created:

CurrentDateValidation

You can find details on how to create a custom form element in Sitecore Forms documentation, as well as how to create a custom validation.

The view model class that can be used to set min and max attributes on a date picker based on start and end date properties, which are calculated based on a current date +/- a certain number of days, which can be configured in the Forms Designer:

    [Serializable]
    public class ExtendedDateViewModel : DateViewModel
    {
        public DateTime? StartDate { get; set; }

        public DateTime? EndDate { get; set; }

        public double? CurrentDateAdditionMin { get; set; }

        public double? CurrentDateAdditionMax { get; set; }

        protected override void InitItemProperties(Item item)
        {
            base.InitItemProperties(item);

            double.TryParse(item.Fields["CurrentDateAdditionMin"].Value, out double additionNumberMin);
            double.TryParse(item.Fields["CurrentDateAdditionMax"].Value, out double additionNumberMax);

            CurrentDateAdditionMin = additionNumberMin;
            CurrentDateAdditionMax = additionNumberMax;

            StartDate = DateTime.Today.AddDays(additionNumberMin);
            EndDate = DateTime.Today.AddDays(additionNumberMax);
        }

        protected override void UpdateItemFields(Item item)
        {
            base.UpdateItemFields(item);

            item.Fields["CurrentDateAdditionMin"]?.SetValue(CurrentDateAdditionMin.HasValue
                ? CurrentDateAdditionMin.ToString()
                : string.Empty, false);
            item.Fields["CurrentDateAdditionMax"]?.SetValue(CurrentDateAdditionMax.HasValue
                ? CurrentDateAdditionMax.ToString()
                : string.Empty, false);
        }
    }

And the corresponding validation class for it:

    public class CurrentDateBasedDateValidation : ValidationElement
    {
        public CurrentDateBasedDateValidation(ValidationDataModel validationItem) : base(validationItem)
        {

        }

        public DateTime? StartDate { get; set; }

        public DateTime? EndDate { get; set; }

        public double? CurrentDateAdditionMin { get; set; }

        public double? CurrentDateAdditionMax { get; set; }

        public override void Initialize(object validationModel)
        {
            base.Initialize(validationModel);

            if (!(validationModel is ExtendedDateViewModel extDateViewModel))
                return;

            CurrentDateAdditionMin = extDateViewModel.CurrentDateAdditionMin;
            CurrentDateAdditionMax = extDateViewModel.CurrentDateAdditionMax;
            StartDate = extDateViewModel.StartDate;
            EndDate = extDateViewModel.EndDate;

        }

        public override ValidationResult Validate(object value)
        {
            if (!(value is DateTime date))
                return new ValidationResult(FormatMessage());

            if (date &gt; StartDate &amp;&amp; date <span id="mce_SELREST_start" style="overflow:hidden;line-height:0;">&#65279;</span>&lt; EndDate)
            {
                return ValidationResult.Success;
            }

            return new ValidationResult(FormatMessage());
        }
    }

The custom form element and the custom validation above will let forms authors to set necessary start and end date restrictions that are based on a current date rather than a fixed/predefined date.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s