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; }
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
Nice. Does this take into consideration the use of visitor groups?
I might want maximum five elements per visitor group - and not in all.