AEM 6 SP2 - Touch UI ( Coral UI ) Nested Multifield ( Multi Multifield )

Goal


Create a Touch UI Nested multifield (or Multi multifield). The nested one is configured with two form fields, a Textfield (granite/ui/components/foundation/form/textfield), Pathbrowser  (granite/ui/components/foundation/form/pathbrowser )

Remember, it's always recommended to minimize the  number of UI extensions in projects, given a choice, a better (or simple) design of the dialog i guess would be without a nested multifield

A Composite Touch UI multifield is available here

For AEM 62 Nested Multifield storing data as Child Nodes check this post

Demo | Package Install


Nested Multifield





Component Rendering




Solution


1) Login to CRXDE Lite (http://localhost:4502/crx/de) and create a folder (nt:folder) /apps/touch-ui-nested-multi-field-panel

2) Create a component (cq:Component) /apps/touch-ui-nested-multi-field-panel/sample-nested-multi-fieldCheck this post on how to create a CQ component

3) Add the following xml for /apps/touch-ui-nested-multi-field-panel/sample-nested-multi-field/dialog created. Ideally a cq:Dialog should be configured with necessary widgets for displaying dialog in Classic UI. This post is on Touch UI so keep it simple (node required for opening the touch ui dialog created in next step)

<?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:Dialog"
    title="Multi Field"
    xtype="dialog"/>

4) Create a nt:unstructured node /apps/touch-ui-nested-multi-field-panel/sample-nested-multi-field/cq:dialog with following xml (the dialog UI as xml)

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/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 TouchUI Component"
    sling:resourceType="cq/gui/components/authoring/dialog"
    helpPath="en/cq/current/wcm/default_components.html#Text">
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/foundation/container">
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
        <items jcr:primaryType="nt:unstructured">
            <column
                jcr:primaryType="nt:unstructured"
                sling:resourceType="granite/ui/components/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <fieldset
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Sample Dashboard"
                        sling:resourceType="granite/ui/components/foundation/form/fieldset">
                        <layout
                            jcr:primaryType="nt:unstructured"
                            sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"/>
                        <items jcr:primaryType="nt:unstructured">
                            <column
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/foundation/container">
                                <items jcr:primaryType="nt:unstructured">
                                    <dashboard
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/foundation/form/textfield"
                                        fieldDescription="Enter Dashboard name"
                                        fieldLabel="Dashboard name"
                                        name="./dashboard"/>
                                    <countries
                                        jcr:primaryType="nt:unstructured"
                                        sling:resourceType="granite/ui/components/foundation/form/multifield"
                                        class="full-width"
                                        fieldDescription="Click '+' to add a new page"
                                        fieldLabel="Countries">
                                        <field
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/foundation/form/fieldset"
                                            eaem-nested=""
                                            name="./countries">
                                            <layout
                                                jcr:primaryType="nt:unstructured"
                                                sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
                                                method="absolute"/>
                                            <items jcr:primaryType="nt:unstructured">
                                                <column
                                                    jcr:primaryType="nt:unstructured"
                                                    sling:resourceType="granite/ui/components/foundation/container">
                                                    <items jcr:primaryType="nt:unstructured">
                                                        <country
                                                            jcr:primaryType="nt:unstructured"
                                                            sling:resourceType="granite/ui/components/foundation/form/textfield"
                                                            fieldDescription="Name of Country"
                                                            fieldLabel="Country Name"
                                                            name="./country"/>
                                                        <states
                                                            jcr:primaryType="nt:unstructured"
                                                            sling:resourceType="granite/ui/components/foundation/form/multifield"
                                                            class="full-width"
                                                            fieldDescription="Click '+' to add a new page"
                                                            fieldLabel="States">
                                                            <field
                                                                jcr:primaryType="nt:unstructured"
                                                                sling:resourceType="granite/ui/components/foundation/form/fieldset"
                                                                name="./states">
                                                                <layout
                                                                    jcr:primaryType="nt:unstructured"
                                                                    sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
                                                                    method="absolute"/>
                                                                <items jcr:primaryType="nt:unstructured">
                                                                    <column
                                                                        jcr:primaryType="nt:unstructured"
                                                                        sling:resourceType="granite/ui/components/foundation/container">
                                                                        <items jcr:primaryType="nt:unstructured">
                                                                            <state
                                                                                jcr:primaryType="nt:unstructured"
                                                                                sling:resourceType="granite/ui/components/foundation/form/textfield"
                                                                                fieldDescription="Name of State"
                                                                                fieldLabel="State Name"
                                                                                name="./state"/>
                                                                            <path
                                                                                jcr:primaryType="nt:unstructured"
                                                                                sling:resourceType="granite/ui/components/foundation/form/pathbrowser"
                                                                                fieldDescription="Select Path"
                                                                                fieldLabel="Path"
                                                                                name="./path"
                                                                                rootPath="/content"/>
                                                                        </items>
                                                                    </column>
                                                                </items>
                                                            </field>
                                                        </states>
                                                    </items>
                                                </column>
                                            </items>
                                        </field>
                                    </countries>
                                </items>
                            </column>
                        </items>
                    </fieldset>
                </items>
            </column>
        </items>
    </content>
</jcr:root>

5) Line 45 in above dialog xml marks this multifield as nested by setting a no value flag eaem-nested

6) Different layouts can be used to structure the multifield, here we use granite/ui/components/foundation/layouts/fixedcolumns layout

7) Create a clientlib (cq:ClientLibraryFolder) /apps/touch-ui-nested-multi-field-panel/clientlib with categories property as String with value cq.authoring.dialog and dependencies as String[] with value underscore

8) Create file (nt:file) /apps/touch-ui-nested-multi-field-panel/clientlib/js.txt with

                nested-multifield.js

9) Create file (nt:file) /apps/touch-ui-nested-multi-field-panel/clientlib/nested-multifield.js with following code

(function () {
    var DATA_EAEM_NESTED = "data-eaem-nested";
    var CFFW = ".coral-Form-fieldwrapper";

    //reads multifield data from server, creates the nested composite multifields and fills them
    var addDataInFields = function () {
        $(document).on("dialog-ready", function() {
            var mName = $("[" + DATA_EAEM_NESTED + "]").data("name");

            if(!mName){
                return;
            }

            //strip ./
            mName = mName.substring(2);

            var $fieldSets = $("[" + DATA_EAEM_NESTED + "][class='coral-Form-fieldset']"),
                $form = $fieldSets.closest("form.foundation-form");

            var actionUrl = $form.attr("action") + ".json";

            var postProcess = function(data){
                if(!data || !data[mName]){
                    return;
                }

                var mValues = data[mName], $field, name;

                if(_.isString(mValues)){
                    mValues = [ JSON.parse(mValues) ];
                }

                _.each(mValues, function (record, i) {
                    if (!record) {
                        return;
                    }

                    if(_.isString(record)){
                        record = JSON.parse(record);
                    }

                    _.each(record, function(rValue, rKey){
                        $field = $($fieldSets[i]).find("[name='./" + rKey + "']");

                        if(_.isArray(rValue) && !_.isEmpty(rValue)){
                            fillNestedFields( $($fieldSets[i]).find("[data-init='multifield']"), rValue);
                        }else{
                            $field.val(rValue);
                        }
                    });
                });
            };

            //creates & fills the nested multifield with data
            var fillNestedFields = function($multifield, valueArr){
                _.each(valueArr, function(record, index){
                    $multifield.find(".js-coral-Multifield-add").click();

                    //a setTimeout may be needed
                    _.each(record, function(value, key){
                        var $field = $($multifield.find("[name='./" + key + "']")[index]);
                        $field.val(value);
                    })
                })
            };

            $.ajax(actionUrl).done(postProcess);
        });
    };

    var fillValue = function($field, record){
        var name = $field.attr("name");

        if (!name) {
            return;
        }

        //strip ./
        if (name.indexOf("./") == 0) {
            name = name.substring(2);
        }

        record[name] = $field.val();

        //remove the field, so that individual values are not POSTed
        $field.remove();
    };

    //for getting the nested multifield data as js objects
    var getRecordFromMultiField = function($multifield){
        var $fieldSets = $multifield.find("[class='coral-Form-fieldset']");

        var records = [], record, $fields, name;

        $fieldSets.each(function (i, fieldSet) {
            $fields = $(fieldSet).find("[name]");

            record = {};

            $fields.each(function (j, field) {
                fillValue($(field), record);
            });

            if(!$.isEmptyObject(record)){
                records.push(record)
            }
        });

        return records;
    };

    //collect data from widgets in multifield and POST them to CRX as JSON
    var collectDataFromFields = function(){
        $(document).on("click", ".cq-dialog-submit", function () {
            var $form = $(this).closest("form.foundation-form");

            var mName = $("[" + DATA_EAEM_NESTED + "]").data("name");
            var $fieldSets = $("[" + DATA_EAEM_NESTED + "][class='coral-Form-fieldset']");

            var record, $fields, $field, name, $nestedMultiField;

            $fieldSets.each(function (i, fieldSet) {
                $fields = $(fieldSet).children().children(CFFW);

                record = {};

                $fields.each(function (j, field) {
                    $field = $(field);

                    //may be a nested multifield
                    $nestedMultiField = $field.find("[data-init='multifield']");

                    if($nestedMultiField.length == 0){
                        fillValue($field.find("[name]"), record);
                    }else{
                        name = $nestedMultiField.find("[class='coral-Form-fieldset']").data("name");

                        if(!name){
                            return;
                        }

                        //strip ./
                        name = name.substring(2);

                        record[name] = getRecordFromMultiField($nestedMultiField);
                    }
                });

                if ($.isEmptyObject(record)) {
                    return;
                }

                //add the record JSON in a hidden field as string
                $('<input />').attr('type', 'hidden')
                    .attr('name', mName)
                    .attr('value', JSON.stringify(record))
                    .appendTo($form);
            });
        });
    };

    $(document).ready(function () {
        addDataInFields();
        collectDataFromFields();
    });

    //extend otb multifield for adjusting event propagation when there are nested multifields
    //for working around the nested multifield add and reorder
    CUI.Multifield = new Class({
        toString: "Multifield",
        extend: CUI.Multifield,

        construct: function (options) {
            this.script = this.$element.find(".js-coral-Multifield-input-template:last");
        },

        _addListeners: function () {
            this.superClass._addListeners.call(this);

            //otb coral event handler is added on selector .js-coral-Multifield-add
            //any nested multifield add click events are propagated to the parent multifield
            //to prevent adding a new composite field in both nested multifield and parent multifield
            //when user clicks on add of nested multifield, stop the event propagation to parent multifield
            this.$element.on("click", ".js-coral-Multifield-add", function (e) {
                e.stopPropagation();
            });

            this.$element.on("drop", function (e) {
                e.stopPropagation();
            });
        }
    });

    CUI.Widget.registry.register("multifield", CUI.Multifield);
})();

10) The function collectDataFromFields() registers a click listener on dialog submit, to collect the multifield form data, create a json to group it and add in a hidden field before data is POSTed to CRX. The function addDataInFields() reads json data added previously and fills the multifield & nested multifield fields, when dialog is opened. Extension uses simple jquery & underscore js calls to get and set data; based on the widget type more code may be necessary for supporting complex Granite UI widgets (granite/ui/components/foundation/form)

11) Create the component jsp /apps/touch-ui-nested-multi-field-panel/sample-nested-multi-field/sample-nested-multi-field.jsp for rendering data entered in dialog

<%@ page import="org.apache.sling.commons.json.JSONObject" %>
<%@ page import="java.io.PrintWriter" %>
<%@ page import="org.apache.sling.commons.json.JSONArray" %>
<%@include file="/libs/foundation/global.jsp" %>
<%@page session="false" %>

<div style="display: block; border-style: solid; border-width: 1px; margin: 10px; padding: 10px">
    <b>Countries and States</b>

<%
        try {
            Property property = null;

            if (currentNode.hasProperty("countries")) {
                property = currentNode.getProperty("countries");
            }

            if (property != null) {
                JSONObject country = null, state = null;
                Value[] values = null;

                if (property.isMultiple()) {
                    values = property.getValues();
                } else {
                    values = new Value[1];
                    values[0] = property.getValue();
                }

                for (Value val : values) {
                    country = new JSONObject(val.getString());
%>
                    Country : <b><%= country.get("country") %></b>
<%
                    if (country.has("states")) {
                        JSONArray states = (JSONArray) country.get("states");

                        if (states != null) {
                            for (int index = 0, length = states.length(); index < length; index++) {
                                state = (JSONObject) states.get(index);
%>
                                <div style="padding-left: 25px">
                                    <a href="<%= state.get("path") %>.html" target="_blank">
                                        <%= state.get("state") %> - <%= state.get("path") %>
                                    </a>
                                </div>
<%
                            }
                        }

                    }
                }
            } else {
%>
                Add values in dialog
<%
            }
        } catch (Exception e) {
            e.printStackTrace(new PrintWriter(out));
        }
%>
</div>


54 comments:

  1. Thanks Sreekanth , ain't you just awesome

    ReplyDelete
  2. Hi Sreekanth, I am using both nested multifield and composite multifield components and they are behaving very weirdly together. I am getting Uncaught RangeError: Maximum call stack size exceeded (too much recursion).

    _addListeners: function () {
    this.superClass._addListeners.call(this);

    The dialogs are storing the values in the node but then at times aren't retrieving the values back when you reopen them. Any suggestions around how to get rid of the problem?

    ReplyDelete
    Replies
    1. hi sahil, can you paste the dialog configuration here....

      Delete
    2. This comment has been removed by the author.

      Delete
    3. This comment has been removed by the author.

      Delete
    4. Hey Sreekanth,

      Thanks, I tried uploading the file twice but i was unable to. The values of the dialog isn't being retained when you reopen it. The values do persists though.

      I have attached it here http://temp-host.com/download.php?file=wi23zk

      Cheers

      Delete
    5. Missing "./" in name property; so iconPath should be ./iconPath, omnitureButtonName shuld be ./omnitureButtonName etc

      Delete
    6. Hi srikanth,
      I want this for classic ui

      Delete
    7. Raghav, its the same as composite multifield (http://experience-aem.blogspot.com/2013/09/aem-cq-56-multifield-panel.html). Anyway i've added a post with sample dialog configuration etc. - http://experience-aem.blogspot.com/2015/06/aem-61-classic-ui-nested-composite-multifield-panel.html

      Delete
  3. Hey Sreekanth, That did resolve the issue. Thanks a lot.

    ReplyDelete
  4. Hey Sreekanth,

    I'm seeing an error thrown "CUI is not defined" at this point in the js file : CUI.Multifield = new Class({....

    Any idea as to how this might be resolved?

    Thanks

    ReplyDelete
    Replies
    1. mah8473, what is the aem version? is the category of clientlib cq.authoring.dialog

      Delete
  5. Sreekanth, I was on AEM 6 sp2, but have just upgraded to 6.1. The CUI error was evident in both versions. Yes the clientlib category is cq.authoring.dialog. I was curious if I might be missing a dependency? I note there is a dependency for underscore.

    btw: This is actually the same dialog mentioned by sahil thadhani above. I've inherited this from him.

    Thanks
    Mark

    ReplyDelete
    Replies
    1. Mark, can you upload the package and send url?

      Delete
    2. https://www.dropbox.com/s/t86nrb4hgacc2z5/mypost.ui.apps-1.0-SNAPSHOT.zip?dl=0
      https://www.dropbox.com/s/hq8paziizm14vn6/mypost.ui.content-1.0-SNAPSHOT.zip?dl=0

      Delete
    3. Sreekanth, were those packages OK?

      Delete
    4. Mark, installed packages, but the content page with dashboardSection component rendered with exceptions (i guess because of some missing jars).. havent explored further, can you create a package with just the component and added on geometrixx english page, resend it

      Delete
    5. Sreehanth, apologies, i forgot the dashboard page used a property iterator in my core package

      here are the additional jars you will need

      https://www.dropbox.com/s/dq14zcr7a1ygao0/core.ui.apps-1.0-SNAPSHOT.zip?dl=0
      https://www.dropbox.com/s/66roxnfuyx91i95/core.ui.content-1.0-SNAPSHOT.zip?dl=0

      Delete
    6. There is no jar in the packages attached, throwing - Cannot find class au.com.auspost.mypost.core.sightly.PropertyIterator

      Also i would suggest adding just the multifield component on geometrixx page and try

      Delete
    7. Sreenkanth, I've narrowed it done further. it looks like the category cq.authoring.dialog injects these in the wrong order

      /libs/cq/gui/components/common/tagspicker/clientlibs.js
      etc/clientlibs/granite/coralui2keys.js

      I'm going to raise a daycare ticket.

      Delete
  6. Hi.
    It's working. but if we add any fields (.ie textfield) right after nest-multifield, then the layout will break. :(
    i.e in your example, I'm adding 1 more textfield right after countries (which is nested one). the layout after countries will be broken.

    ReplyDelete
    Replies
    1. Hi, thank you for reporting, i see the issue.... workaround is to make sure the nested multifield is last widget of dialog, working on a fix

      Delete
    2. Hi Sreekanth,
      Is there a fix for the above issue. I have a similar issue where there are two multifields in a nested multifield. The fields after the first multified appear outside the parent multi-field.
      Here is the crx package of the component: https://www.dropbox.com/sh/x8twgl4cx66l77w/AABlEaeya2--CNSujPaofJQSa?dl=0

      Delete
    3. Hi Sreekanth
      Is there a fix for this issue?
      I am unable to add elements after a nested multifield in a dialog?

      Delete
  7. Hi Sreekanth, I am using composite multifield component. I am getting Uncaught RangeError: Maximum call stack size exceeded (too much recursion).

    _addListeners: function () {
    this.superClass._addListeners.call(this);

    Can you please give me in this issue?

    ReplyDelete
    Replies
    1. hi Syam, check the comments above (you might be hitting the same issue).. check if "./" is missing in name property

      Delete
  8. This comment has been removed by the author.

    ReplyDelete
  9. Hi Sreekanth
    It seems that it doesn't work on 6.1 , I tested your package on 6.1 and it throws Maximum call stack size exceeded on clientlib.js ,any update on that ?

    /Parisa

    ReplyDelete
    Replies
    1. Parisa, i remember testing the widget on 61; make sure you have "./" in name property.. check above comments

      Delete
    2. Hi Sreekanth,

      ./ is present on all name property, even then i am getting Maximum call stack size exceeded error, please advise

      Delete
  10. Hi,

    I created a multifield as above. But I have a problem: The Multifield's fields can't set required. I checked source code and saw you removed the multifield's fields out form. So The Granite Validation don't see that fields and can't validate for that fields.

    Could you please help me resolve that problem?

    Thanks

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. Hi Sreekanth,

    I have a checkbox in the child multifield. The value is not changed on edit and is always persisted as default value.
    Tried to update js to include your changes in https://github.com/schoudry/acs-aem-commons/commit/ac91c67707d0b2c5ae6230706ea02f1f4bdce891, but couldn't resolve it.

    Could you please help with that?

    Thanks!

    ReplyDelete
    Replies
    1. Hi,

      I am also having the same issue? If you were able to resolve it, please let me know how. Thanks.

      Delete
  13. Hi Sreekanth,

    What are the changes required if I want to have different versions of nested-multifield.js in different components? Since the categories is same i.e. cq.authoring.dialog for all, they override the behavior of each other. To create two different versions, we changed the resourceType in component as "granite/ui/components/foundation/form/newmultifield" and changed the register logic in nested-multifield.js i.e.

    CUI.NewMultifield = new Class({
    toString: "Multifield",
    extend: CUI.Multifield,

    construct: function (options) {
    this.script = this.$element.find(".js-coral-Multifield-input-template:last");
    },

    _addListeners: function () {
    this.superClass._addListeners.call(this);

    //otb coral event handler is added on selector .js-coral-Multifield-add
    //any nested multifield add click events are propagated to the parent multifield
    //to prevent adding a new composite field in both nested multifield and parent multifield
    //when user clicks on add of nested multifield, stop the event propagation to parent multifield
    this.$element.on("click", ".js-coral-Multifield-add", function (e) {
    e.stopPropagation();
    });

    this.$element.on("drop", function (e) {
    e.stopPropagation();
    });
    }
    });

    CUI.Widget.registry.register("newmultifield", CUI.NewMultifield);
    })();

    Do we need to do something else as well? This doesnt give any js error but doesnt show the multifield as well.

    ReplyDelete
    Replies
    1. Hi Shelly Goel,
      Have you got solution for your issue.Please let me know as I m also facing similar issue.

      Delete
  14. Hi Sreekanth,

    I have modified the script little bit to fix issue "multifield blank entries added when dialog-ready trigger explicitly".
    Changes description:
    a) Remove 'js-coral-Multifield-add' click trigger from fillNestedFields and invoke before checking which field is active.
    if(_.isArray(rValue) && !_.isEmpty(rValue)){
    var $multifield = $($fieldSets[i]).find("[data-init='multifield']"),
    //find active tab rValue after striping ./
    activeKey = $multifield.closest('section[data-eaem-nested]').attr('data-name').substring(2);

    /*Add the multifield only for active tab */
    if(rKey == activeKey){
    $multifield.find(".js-coral-Multifield-add").click();
    }
    fillNestedFields( $multifield, rValue);
    }


    2) Add $(document).trigger('dialog-ready'); (in cq.authoring.dialog scenario have analyzed that dialog-ready is not triggering at first attempt), Hope this will solve Shally problem as well.

    ReplyDelete
    Replies
    1. you can give me file nested-multifield.js.
      I integrated, it isn't work.

      Delete
  15. Hi Sreekanth,

    In case of touch UI, any solution for When Datepicker is a field in a multifield, the date is not loaded while editing again?

    ReplyDelete
    Replies
    1. Hi, this was fixed in ACS commons - check https://github.com/Adobe-Consulting-Services/acs-aem-commons/pull/674/files

      Delete
  16. Hi Sreekanth,

    I'm facing also the problem that it is not working in 6.1 throwing the error clientlibs.js:177 Uncaught RangeError: Maximum call stack size exceeded. I use the example you provided, so there are ./ properties fields in there.

    Can you help me out, really need a nested multifield solution

    ReplyDelete
  17. Hi Sreekanth,

    My requirement is to have 3 level nested multifield. I can see that the layout is breaking for dialog when 3rd level multifield is added. Also This scriipt is not working for 3 level multifield. Can you please help me out. It is a mandatory requirement for me.

    Thanks

    ReplyDelete
  18. Hi Sreekanth,

    I'm facing also the problem that it is not working in 6.1 throwing the error Uncaught RangeError: Maximum call stack size exceeded.
    I use the example you provided, the ./ is in the name properties. Please advice what else i need to check on.

    ReplyDelete
  19. Hi Wayne/Sreekanth,

    Can you please provide an update for Uncaught RangeError: Maximum call stack size exceeded. We are already using ./ in name properties.

    Thanks,
    Vijender

    ReplyDelete
  20. Hi.This nested-multifield.js stores the data as json.I want to store data as child node.How can i do that?

    ReplyDelete
  21. @Wayne Pang, @Ishita Gandhi

    Uncaught RangeError: Maximum call stack size exceeded?

    You are facing this error because
    1. this.superClass._addListeners.call(this); goes for infinite loop call. The reason is this.superClass never gives Superclass of CUI.Multifield which is in CoralUI js but instead it is giving its same CUI.Multifield which is in custom multifield js.
    2. Not sure what causing this issue. Becuase a fresh installtion of AEM 6.1 is not facing problem mentioned in point 1.
    3. Install a fresh instance, and try applying this custom multifield package.

    ReplyDelete
    Replies
    1. A solution to this is to create the child with a different name other than CUI.Multifield. I used CUI.Multifields and was successful.

      Delete
  22. Hi Sreekanth,
    I have customized siteadmin with new columns using https://docs.adobe.com/docs/en/cq/5-6-1/developing/customize_siteadmin.html
    I observed roll out option is disabled for blueprint and live copy configured pages after customizing siteadmin.Could you please help me.

    ReplyDelete
  23. Can anyone please paste the .js file for the Sreekanth example which is not giving Uncaught RangeError: Maximum call stack size exceeded? error

    ReplyDelete
  24. Hi Sreekanth,

    This solution is working fine for me in a dialog having only one tab. But once I add one more tab in my dialog, then the elements in the second tab is not showing at all or getting disappeared.

    Do you know this problem?. Thanks

    ReplyDelete
  25. https://aemblogger.wordpress.com/2017/03/14/aem-touchui-multifield-nested-nodes/

    best solution to implement multifield and save values in nested nodes

    ReplyDelete
  26. Hello,

    Thank you for all the valuable information shared in this blog, it has been very useful!

    Does anyones has worked in adding the Image functionality in this nested multifield?

    ReplyDelete
  27. cq:dialog structure should be same as given or it will work for any cq:dialog with nested multifield????
    I have created dialog with two column and in second column i need to add one multifield and inside that multifield i have put child multifield(nested).
    This will work for that also?

    ReplyDelete