Goal
Limit the number of items inside your multifield dialog component.
Procedure
Let’s create our dialog as follows:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="Multifield Component"
extraClientlibs="[cq.author.accordion]"
sling:resourceType="cq/gui/components/authoring/dialog">
<content jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="true">
<items jcr:primaryType="nt:unstructured">
<general
jcr:primaryType="nt:unstructured"
jcr:title="General"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="true">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Title"
name="./title"/>
<subtitle
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Subtitle"
name="./subtitle"/>
<accordion
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
fieldLabel="News">
<granite:data
jcr:primaryType="nt:unstructured"
max-item="3"
min-item="1"/>
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./multifield">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<description
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Description"
name="./description"/>
</items>
</column>
</items>
</field>
</accordion>
</items>
</column>
</items>
</general>
</items>
</tabs>
</items>
</content>
</jcr:root>
The main difference between a standard multifield is the following piece of code:
<granite:data
jcr:primaryType="nt:unstructured"
max-item="3"
min-item="1"/>
In this way, on the multified rendered html, we will have two additional data-attribute that we will use for our validation.
Now, create a clientlib. Set your category name, for example:
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="[cq.author.accordion]"/>
And create the javascript file:
(function ($, $document) {
"use strict";
$.validator.register("foundation.validation.validator", {
selector: "coral-multifield",
validate: function(el) {
var totalPanels = el["0"].items.getAll().length;
var min;
var max;
if ($(el).data("min-item")){
min = $(el).data("min-item");
if(totalPanels < min) {
return "Minimum numbers of items required are: " + min;
}
}
if ($(el).data("max-item")){
max = $(el).data("max-item");
if(totalPanels > max) {
return "Maximum numbers of items allowed are: " + max;
}
}
}});
})($, $(document));
This will take care of the number of your items.
Remember to include your clientlib in the dialog, which is already done if you’ve copied the file, using the instruction “extraClientlibs=”[cq.author.accordion]”“.
Here two screenshots of the clientlibs at work:
Hope it helps!
If you need to use a nested multifield, you have to implement a little bit more of logic, but it’s really easy. Check it out here.
Cheers 🍷