Views: 3089
Number of votes: 2
Average rating:

Limit number of elements in a LinkItemCollection or ContentArea

A colleague asked me today how to ensure that editors don't add too many elements in a LinkItemCollection or ContentArea - since too many could potentially break the design. I figured a simple validation attribute could do the trick - and sure enough, it can. I figured I'd share it here as it's a nice example of how to do custom validations of property values. I could have extended it even further to also ensure that the front-end code wouldn't even allow for the editor to try and drop an element if there's already too many - but due to time restraints and my limited dojo-skills, I simply left that part as a fun TODO for all of you out there. If you have that part, feel free to share in the comments...

Here is the main class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.ModelBinding;
using EPiServer.Core;
using EPiServer.ServiceLocation;
using EPiServer.Shell.ObjectEditing;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using EPiServer.SpecializedProperties;

namespace ExperimentsValidationAttributes
{
    /// <summary>
    /// Sets the maximum element count in a linkcollection, a content area - or any other type of collection.
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class MaxElementsAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute, IMetadataAware
    {
        public int MaxCount { get; set; }

        public void OnMetadataCreated(ModelMetadata metadata)
        {
            //TODO: Use to disable editor drag and drop at a certain point.
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
            {
                return null;
            }
            if(value is LinkItemCollection)
            {
                if((value as LinkItemCollection).Count > MaxCount)
                {
                    return new ValidationResult("Too many Link Items in the collection. Maximum is " + MaxCount);
                }
            } else if(value is ContentArea)
            {
                if((value as ContentArea).Count>MaxCount)
                {
                    return new ValidationResult("Too many content items in content area. Maximum is " + MaxCount);
                }
            } 

            return null;
        }

        public MaxElementsAttribute(int MaxElementsInList)
        {
            this.MaxCount = MaxElementsInList;
        }
    }
}

And of course it's straightforward to use:

        [MaxElements(3)]
        public virtual LinkItemCollection Links { get; set; }

        [Display(
            GroupName = SystemTabNames.Content,
            Order = 320)]
        [MaxElements(5)]
        public virtual ContentArea MainContentArea { get; set; }
Nov 27, 2017

valdis
(By valdis, 11/28/2017 11:16:56 AM)

cool. also, similar - if you are using Bootstrap and want to notify editors that too much items in that content area might blow up something - you can use very similar validator. https://github.com/valdisiljuconoks/EPiBootstrapArea/blob/master/README.md#validate-item-count

Robert Runge
(By Robert Runge, 11/29/2017 11:05:47 AM)

Nice. Does this take into consideration the use of visitor groups?

I might want maximum five elements per visitor group - and not in all.

Please login to comment.