Quantcast
Viewing all articles
Browse latest Browse all 526

AEM 61 - Classic UI Composite Multifield Storing Values as Nodes

Goal


Create a Classic UI Composite Multifield, storing the composite field values as child nodes (useful when executing search queries for exact matches).

For storing values in json format, check this post

For Touch UI Composite Multifield storing values as child nodes check this post

Tested on AEM 61; should work ok on 60 and 561 too...  Demo | Package Install


Multi Field Panel


Image may be NSFW.
Clik here to view.


Value Nodes in CRX


Image may be NSFW.
Clik here to view.



Dialog in CRX


Image may be NSFW.
Clik here to view.



Dialog XML

#31, #37, #43 - property dName used in creating fully qualified name (./<multifield-name>/<order>/<dName>) eg ./stock/1/year

<?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">
<stock
jcr:primaryType="cq:Widget"
hideLabel="false"
name="./stock"
title="Stock"
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"/>
</items>
</fieldConfig>
</stock>
</items>
</tab1>
</items>
</items>
</jcr:root>


Solution


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

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

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

                         multi-field.js

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

CQ.Ext.ns("ExperienceAEM");

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

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

function addName(items, prefix, counter){
items.each(function(i){
if(!i.hasOwnProperty("dName")){
return;
}

i.name = prefix + "/" + (counter) + "/" + i.dName;

if(i.el && i.el.dom){ //form serialization workaround
i.el.dom.name = prefix + "/" + (counter) + "/" + i.dName;
}
},this);
}

var multi = this.findParentByType("multifield"),
multiPanels = multi.findByType("multi-field-panel");

addName(this.items, this.name, multiPanels.length + 1);

multi.on("removeditem", function(){
multiPanels = multi.findByType("multi-field-panel");

for(var x = 1; x <= multiPanels.length; x++){
addName(multiPanels[x-1].items, multiPanels[x-1].name, x);
}
});
},

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.hasOwnProperty("dName")){
return;
}

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

return pData;
},

setValue: function (value) {
var counter = 1, item,
multi = this.findParentByType("multifield"),
multiPanels = multi.findByType("multi-field-panel");

if(multiPanels.length == 1){
item = value[counter];
}else{
item = value;
}

this.items.each(function(i){
if(!i.hasOwnProperty("dName")){
return;
}

i.setValue(item[i.dName]);
});

if(multiPanels.length == 1){
while(true){
item = value[++counter];

if(!item){
break;
}

multi.addItem(item);
}
}
},

validate: function(){
return true;
},

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

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

5) A sample exact match query performed with query builder, on property name year, returning multifield nodes

http://localhost:4502/bin/querybuilder.json?property=year&property.value=2010&p.hits=full

Image may be NSFW.
Clik here to view.



Viewing all articles
Browse latest Browse all 526


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