Limiting items in a ContentArea
Feature
The ContentArea should
- Supported to limits a number of block inside it (for individual ContentArea).
- When total blocks is over max limited size, the action links section should be hidden.
- When total blocks is over max limited size, editor cannot DnD a block to that ContentArea.
Solution
The attribute
By using attribute, we can set individual limited total items for each ContentArea.
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class MaxItemCountAttribute : Attribute
{
public int Count { get; }
public MaxItemCountAttribute(int maxItemCount)
{
Count = maxItemCount;
}
}
The editor descriptor
We needed to extend both ContentArea and ContentAreaEditor widgets. Inside the custom editor descriptor, we read the value of attribute and then render it to client side.
/// <summary>
/// Editor descriptor that extends the <see cref="ContentAreaEditorDescriptor"/> for a <see cref="ContentArea"/>
/// that marked with <see cref="MaxItemCountAttribute"/> in order to limits total items inside it.
/// </summary>
[EditorDescriptorRegistration(TargetType = typeof(ContentArea), UIHint = "ContentAreaWithMaxItem")]
public class CustomContentAreaEditorDescriptor : ContentAreaEditorDescriptor
{
public CustomContentAreaEditorDescriptor()
{
ClientEditingClass = "alloy/contentediting/editors/CustomContentAreaEditor";
}
public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
{
const string maxItemCount = "maxItemCount";
var maxItemCountAttribute = metadata.Attributes.OfType<MaxItemCountAttribute>().SingleOrDefault();
if (maxItemCountAttribute != null)
{
metadata.EditorConfiguration[maxItemCount] = maxItemCountAttribute.Count;
metadata.OverlayConfiguration[maxItemCount] = maxItemCountAttribute.Count;
}
base.ModifyMetadata(metadata, attributes);
metadata.OverlayConfiguration["customType"] = "alloy/widget/overlay/CustomContentArea";
}
}
The custom ContentAreaEditor
define([
// dojo
"dojo/_base/declare",
"dojo/dom-style",
// epi
"epi-cms/contentediting/editors/ContentAreaEditor"
], function (
// dojo
declare,
domStyle,
// epi
ContentAreaEditor
) {
return declare([ContentAreaEditor], {
postCreate: function () {
this.inherited(arguments);
this._toggleDisplayActionLinks();
},
onChange: function (value) {
this._toggleDisplayActionLinks();
},
_setValueAttr: function (value) {
this.inherited(arguments);
this._toggleDisplayActionLinks();
},
_toggleDisplayActionLinks: function () {
var display = this._canAddItem();
this.actionsContainer && domStyle.set(this.actionsContainer, "display", display ? "" : "none");
this.tree && this.tree.set("readOnly", !display);
},
_canAddItem: function () {
// tags:
// private
if (this.maxItemCount == undefined) {
return true;
}
return this.maxItemCount > this.model.get("value").length;
}
});
});
The custom ContentArea
define([
// dojo
"dojo/_base/declare",
"dojo/dom-style",
// epi
"epi-cms/widget/overlay/ContentArea"
], function (
// dojo
declare,
domStyle,
// epi
ContentArea
) {
return declare([ContentArea], {
updatePosition: function () {
this.inherited(arguments);
this._toggleDisplayActionLinks();
},
executeAction: function (actionName) {
this._toggleDisplayActionLinks();
if (actionName === "createnewblock" && !this._canAddItem()) {
return;
}
this.inherited(arguments);
},
_onDrop: function (data, source, nodes, isCopy) {
// isCopy:
// Flag indicating whether the drag is a copy. False indicates a move.
// tags:
// protected extension
this._toggleDisplayActionLinks();
if (isCopy && !this._canAddItem()) {
return;
}
this.inherited(arguments);
},
_toggleDisplayActionLinks: function () {
this.textWithLinks && domStyle.set(this.textWithLinks.domNode, "display", this._canAddItem() ? "" : "none");
},
_canAddItem: function () {
// tags:
// private
if (this.maxItemCount == undefined) {
return true;
}
return this.maxItemCount > this.getChildren().length;
}
});
});
Start page
Add following attributes
[UIHint("ContentAreaWithMaxItem")]
[MaxItemCount(5)]
to MainContentArea property
[Display(
GroupName = SystemTabNames.Content,
Order = 320)]
[CultureSpecific]
[UIHint("ContentAreaWithMaxItem")]
[MaxItemCount(5)]
public virtual ContentArea MainContentArea { get; set; }
Result
On-Page Editing mode
When total items inside the ContentArea is 4 (qualified with the max item count), action links section still displayed.
The action links section in ContentArea is hidden when total items inside that ContentArea is 5.
On-Page Editing mode with popup
The action links section in ContentArea is hidden when total items inside that ContentArea are 5
All Properties mode
The action links section in ContentArea is hidden when total items inside that ContentArea are 5
Comments