Limit Multifield Items

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 🍷

2 thoughts on “Limit Multifield Items

  1. THANK YOUUUUU! This was the easiest way I found!!! You helped me a lot, thank youuuu so much!!! ❤

    Like

Leave a reply to Rie Cancel reply