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 🍷

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: