AEM 61 - Classic UI Nested Composite Multifield Panel

Goal


Create a Classic UI Nested Composite Multifield Panel. The logic for nested composite multifield and composite multifield is same; this post just has a copy of composite multifield code with additional dialog configuration required for nested multifield

For Touch UI Nested Composite Multifieldcheck this post

Demo | Package Install


Nested Composite Multifield



Values Stored in CRX as JSON



Dialog



Dialog as XML

#27 specifies the xtype multi-field-panel, for parent composite multifield, #60 the child composite multifield

<?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">
    <items
        jcr:primaryType="cq:Widget"
        xtype="tabpanel">
        <items jcr:primaryType="cq:WidgetCollection">
            <tab1
                jcr:primaryType="cq:Panel"
                title="Add">
                <items jcr:primaryType="cq:WidgetCollection">
                    <map
                        jcr:primaryType="cq:Widget"
                        hideLabel="false"
                        name="./map"
                        title="Map"
                        xtype="multifield">
                        <fieldConfig
                            jcr:primaryType="cq:Widget"
                            border="true"
                            hideLabel="true"
                            layout="form"
                            padding="10px"
                            width="1000"
                            xtype="multi-field-panel">
                            <items jcr:primaryType="cq:WidgetCollection">
                                <product-year-value
                                    jcr:primaryType="cq:Widget"
                                    dName="year"
                                    fieldLabel="Year"
                                    width="60"
                                    xtype="textfield"/>
                                <product-price-value
                                    jcr:primaryType="cq:Widget"
                                    dName="price"
                                    fieldLabel="Price"
                                    width="60"
                                    xtype="textfield"/>
                                <product-version-value
                                    jcr:primaryType="cq:Widget"
                                    dName="version"
                                    fieldLabel="Path to Version"
                                    xtype="pathfield"/>
                                <product-region-multifield
                                    jcr:primaryType="cq:Widget"
                                    dName="region"
                                    fieldLabel="Region"
                                    hideLabel="false"
                                    title="Add Regions"
                                    xtype="multifield">
                                    <fieldConfig
                                        jcr:primaryType="cq:Widget"
                                        border="true"
                                        hideLabel="true"
                                        layout="form"
                                        padding="10px"
                                        width="1000"
                                        xtype="multi-field-panel">
                                        <items jcr:primaryType="cq:WidgetCollection">
                                            <product-country
                                                jcr:primaryType="cq:Widget"
                                                dName="country"
                                                fieldLabel="Country"
                                                width="60"
                                                xtype="textfield"/>
                                            <product-state
                                                jcr:primaryType="cq:Widget"
                                                dName="state"
                                                fieldLabel="State"
                                                width="60"
                                                xtype="textfield"/>
                                        </items>
                                    </fieldConfig>
                                </product-region-multifield>
                            </items>
                        </fieldConfig>
                    </map>
                </items>
            </tab1>
        </items>
    </items>
</jcr:root>


Solution


1) Login to CRXDE Lite, create folder (nt:folder) /apps/classic-ui-nested-multi-field-panel

2) Create clientlib (type cq:ClientLibraryFolder/apps/classic-ui-nested-multi-field-panel/clientlib and set a property categories of String type to cq.widgets

3) Create file ( type nt:file ) /apps/classic-ui-nested-multi-field-panel/clientlib/js.txt, add the following

                         multi-field.js

4) Create file ( type nt:file ) /apps/classic-ui-nested-multi-field-panel/clientlib/multi-field.js, add the following code

CQ.Ext.ns("ExperienceAEM");

ExperienceAEM.MultiFieldPanel = CQ.Ext.extend(CQ.Ext.Panel, {
    panelValue: '',

    constructor: function(config){
        config = config || {};
        ExperienceAEM.MultiFieldPanel.superclass.constructor.call(this, config);
    },

    initComponent: function () {
        ExperienceAEM.MultiFieldPanel.superclass.initComponent.call(this);

        this.panelValue = new CQ.Ext.form.Hidden({
            name: this.name
        });

        this.add(this.panelValue);

        var dialog = this.findParentByType('dialog');

        dialog.on('beforesubmit', function(){
            var value = this.getValue();

            if(value){
                this.panelValue.setValue(value);
            }
        },this);

    },

    afterRender : function(){
        ExperienceAEM.MultiFieldPanel.superclass.afterRender.call(this);

        this.items.each(function(){
            if(!this.contentBasedOptionsURL
                    || this.contentBasedOptionsURL.indexOf(CQ.form.Selection.PATH_PLACEHOLDER) < 0){
                return;
            }

            this.processPath(this.findParentByType('dialog').path);
        })
    },

    getValue: function () {
        var pData = {};

        this.items.each(function(i){
            if(i.xtype == "label" || i.xtype == "hidden" || !i.hasOwnProperty("dName")){
                return;
            }

            pData[i.dName] = i.getValue();
        });

        return $.isEmptyObject(pData) ? "" : JSON.stringify(pData);
    },

    setValue: function (value) {
        this.panelValue.setValue(value);

        var pData = JSON.parse(value);

        this.items.each(function(i){
            if(i.xtype == "label" || i.xtype == "hidden" || !i.hasOwnProperty("dName")){
                return;
            }

            i.setValue(pData[i.dName]);
        });
    },

    validate: function(){
        return true;
    },

    getName: function(){
        return this.name;
    }
});

CQ.Ext.reg("multi-field-panel", ExperienceAEM.MultiFieldPanel);

10 comments:

  1. Hi Srikanth,
    There is a issue when we have checkboxes in multifield panel and try to click move down or up (multifield move up or down) .The checkbox values in the panel are not moving .
    For instance
    I have checkbox A in the panel
    I checked in first item and un checked in second .
    when i click multifield move up or down first is always being checked.

    ReplyDelete
    Replies
    1. hi raghav, can you upload the dialog xml to google drive or dropbox and post the url here?

      Delete
  2. Hi Sreekanth, I was referring this blog and http://experience-aem.blogspot.in/2015/03/aem-6-sp2-touch-ui-coral-ui-nested-multi-multifield.html . I need to create a dialog for component having both Touch UI and Classic UI. I came up with the standard layout for both of these dialogs, But the issue is once i add the nested level multifield values via Touch UI dialog, these doesn't appear in Classic UI vice-versa. Can you please have a look where i am doing the wrong.
    Here is the package link:
    https://drive.google.com/open?id=0Bw8wcLLeYm3QMHBsVXZTTnR1NHM

    ReplyDelete
    Replies
    1. Content that getting store in JCR for touch-ui nested multi-field doesn't contains "/" in json array, but in classic-ui nested multi-field its store with "/".
      Classic - UI
      {"countryname":"India","states":["{\"state\":\"NDLS\"}","{\"state\":\"PUN\"}"]}
      {"countryname":"AUS","states":["{\"state\":\"SYD\"}","{\"state\":\"VIC\"}"]}
      Touch UI
      {"countryname":"India","states":[{"state":"NDLS"},{"state":"PUN"}]}
      {"countryname":"AUS","states":[{"state":"SYD"},{"state":"VIC"}]}

      Can you provide the fix for it. Thanks

      Delete
    2. Vivek, access to the package uploaded to drive.google.com (above) is restricted.. can you make it public

      Delete
    3. I have the same problem. Who fixed this problem. Please share the solution. Thank you very much.

      Delete
    4. Hi All,

      Could you please share the package?

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

    ReplyDelete
  4. Hi Sreekanth

    I have added your nested multifield code to an existing component and it works great!! Nested data is stored in the jcr:content. However when i view a page with that component, the pre-authored content does not appear on page load. only after i "edit" the component and touch the content and save, does the pre-authored content appear on the page.

    Any ideas on a bug-fix would be great.

    Thanks Jason

    ReplyDelete
  5. Hi Sreekanth

    I am also facing the same issue wherein the classic nested multifield includes '/' in the generated json where as the touch ui nested multifield does not have '/'. Could you please provide a solution to this.

    ReplyDelete