Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM CQ 56 - Panel in CQ.form.MultiField

$
0
0

Goal


Create a multifield component (CQ.form.MultiField) with panel field config to store data from multiple widgets. Source code and video are available for download







Prerequisites


If you are new to CQ

1) Read this post on how to create a sample page component

2) Here is another blog post on multifield fieldConfig customization

Create Component


1) Create component /apps/multifieldpanel/multifieldpanel with the following properties


2) Create clientlib /apps/multifieldpanel/multifieldpanel/clientlib of type cq:ClientLibraryFolder with the following properties



3) Create file /apps/multifieldpanel/multifieldpanel/clientlib/multipanel.js and add the following code. Here we are creating a panel extension and registering it as xtype mymultipanel

var MyClientLib = MyClientLib || {};

MyClientLib.MyMultiPanel = CQ.Ext.extend(CQ.Ext.Panel, {
panelValue: '',

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

initComponent: function () {
MyClientLib.MyMultiPanel.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);
},

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;
}

if(!pData[i.dName]){
return;
}

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

validate: function(){
return true;
},

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

CQ.Ext.reg("mymultipanel", MyClientLib.MyMultiPanel);

4) Create file /apps/multifieldpanel/multifieldpanel/clientlib/js.txt and add the following code

               multipanel.js

5) Create dialog /apps/multifieldpanel/multifieldpanel/dialog for component above with the following properties. Here,

       a) The node /apps/multifieldpanel/multifieldpanel/dialog/items/items/tab1/items/map/fieldConfig has xtype mymultipanel

       b) Each widget in the multipanel (eg. /apps/multifieldpanel/multifieldpanel/dialog/items/items/tab1/items/map/fieldConfig/items/product-year-value) should have a dName property, which is read by multi panel to store value entered by author for the field

<?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="mymultipanel">
<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-lowStock-value
jcr:primaryType="cq:Widget"
dName="lowStock"
fieldLabel="Low Stock ?"
width="25"
xtype="checkbox"/>
</items>
</fieldConfig>
</map>
</items>
</tab1>
</items>
</items>
</jcr:root>



6) Add the following code in /apps/multifieldpanel/multifieldpanel/multifieldpanel.jsp

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

<div style="display: block; border-style: solid; border-width: 1px; margin: 10px; padding: 10px">
<b>Multi Field Sample</b>

<%
try {
Property property = null;

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

if (property != null) {
JSONObject obj = null;
Value[] values = null;

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

for (Value val : values) {
obj = new JSONObject(val.getString());
%>
Year : <b><%= obj.get("year") %></b>,
Price : <b><%= obj.get("price") %></b>,
Version : <b><%= obj.get("version")%></b>,
Low Stock : <b><%=obj.get("lowStock")%></b>
<%
}
} else {
%>
Add values in dialog
<%
}
} catch (Exception e) {
e.printStackTrace(new PrintWriter(out));
}
%>

</div>


7) Here is the component structure


Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>