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 Multifield, check 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);
Hi Srikanth,
ReplyDeleteThere 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.
hi raghav, can you upload the dialog xml to google drive or dropbox and post the url here?
DeleteHi 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.
ReplyDeleteHere is the package link:
https://drive.google.com/open?id=0Bw8wcLLeYm3QMHBsVXZTTnR1NHM
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 "/".
DeleteClassic - 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
Vivek, access to the package uploaded to drive.google.com (above) is restricted.. can you make it public
DeleteI have the same problem. Who fixed this problem. Please share the solution. Thank you very much.
DeleteHi All,
DeleteCould you please share the package?
@Vivek Dhiman Any Solution found ? can u update here.
DeleteThis comment has been removed by the author.
ReplyDeleteHi Sreekanth
ReplyDeleteI 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
Hi Sreekanth
ReplyDeleteI 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.