We can create a custom xtype using the out of the box xtypes from AEM. We can do it using the compositeField. Composite field allows a number of form Fields to be rendered on the same row. We use EXT JS to extend Composite Field and add all the required fields into it as a list. Then, we can register this Class as a custom xtype.
Any user who needs this list of fields together can directly use this custom xtype while developing dialogs instead of creating them individually. We can use this custom xtype as a mutilfield to make it as a replicant.
Code and Steps are given below.
1) Registering the Custom Component : Create a Javascript file in Client Lib folder and add that into the Component JSP. This Javascript file is used to create the custom xtype and then register it to with EXT JS , so that it can be used in Dialogs.
CustomPathField.js
----------------------------------------------------------------------------------------------------------------------------------
/**
* @class MyClientLib.CustomPathFieldWidget
* @extends CQ.form.CompositeField
* This is a custom path field with a Link Text and a Link URL
* @param {Object} config the config object
*/
/**
* @class Ejst.CustomWidget
* @extends CQ.form.CompositeField
* This is a custom widget based on {@link CQ.form.CompositeField}.
* @constructor
* Creates a new CustomWidget.
* @param {Object} config The config object
*/
CQ.form.CustomMultiField = CQ.Ext.extend(CQ.form.CompositeField, {
/**
* @private
* @type CQ.Ext.form.TextField
*/
hiddenField: null,
/**
* @private
* @type CQ.Ext.form.TextField
*/
linkText: null,
/**
* @private
* @type CQ.Ext.form.PathField
*/
linkURL: null,
/**
* @private
* @type CQ.Ext.form.CheckBox
*/
openInNewWindow: null,
constructor: function (config) {
config = config || {};
var defaults = {
"border": true,
"labelWidth": 75,
"layout": "form"
};
config = CQ.Util.applyDefaults(config, defaults);
CQ.form.CustomMultiField.superclass.constructor.call(this, config);
},
initComponent: function () {
CQ.form.CustomMultiField.superclass.initComponent.call(this);
// Hidden field
this.hiddenField = new CQ.Ext.form.Hidden({
name: this.name
});
this.add(this.hiddenField);
// Text TextField to enter Title
this.linkText = new CQ.Ext.form.TextField({
cls: "customwidget-1",
maxLength: 100,
emptyText: "Enter Title",
maxLengthText: "A maximum of 100 characters is allowed for the Link Text.",
width: 335,
allowBlank: true,
name : "item",
listeners: {
change: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.linkText);
// Link PathField to map a URL
this.linkURL = new CQ.form.PathField({
cls: "customwidget-2",
allowBlank: true,
emptyText: "Enter Title URL",
width: 335,
listeners: {
change: {
scope: this,
fn: this.updateHidden
},
dialogclose: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.linkURL);
// Link openInNewWindow
this.openInNewWindow = new CQ.Ext.form.Checkbox({
cls: "customwidget-3",
boxLabel: "New window",
listeners: {
change: {
scope: this,
fn: this.updateHidden
},
check: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.openInNewWindow);
},
processInit: function (path, record) {
this.linkText.processInit(path, record);
this.linkURL.processInit(path, record);
this.openInNewWindow.processInit(path, record);
},
setValue: function (value) {
var link = JSON.parse(value);
this.linkText.setValue(link.text);
this.linkURL.setValue(link.url);
this.openInNewWindow.setValue(link.openInNewWindow);
},
getValue: function () {
return this.getRawValue();
},
getRawValue: function () {
var link = {
"url": this.linkURL.getValue(),
"text": this.linkText.getValue(),
"openInNewWindow": this.openInNewWindow.getValue()
};
return JSON.stringify(link);
},
updateHidden: function () {
this.hiddenField.setValue(this.getValue());
}
});
CQ.Ext.reg("CustomMultiField", CQ.form.CustomMultiField);
----------------------------------------------------------------------------------------------------------------------------------
When this Javascript is executed you should have the CustomMultiField as xtype.
2) Using the Custom Component in Dialog: Use this xtype in the Dialog to see all the 3 fields ( Text Field, Link Field , Open in New Window ) displayed as a set. For example, if we want to display them as a multifield, here is how the dialog.xml should look like.
<?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"
width="550"
xtype="dialog">
<items
jcr:primaryType="cq:Widget"
xtype="tabpanel">
<items jcr:primaryType="cq:WidgetCollection">
<tab1
jcr:primaryType="cq:Panel"
title="Links Component">
<items jcr:primaryType="cq:WidgetCollection">
<links
jcr:primaryType="cq:Widget"
border="false"
fieldDescription="Press + to add more links"
fieldLabel="Links"
hideLabel="true"
name="./links"
xtype="multifield">
<fieldConfig
jcr:primaryType="cq:Widget"
xtype="CustomMultiField"/>
</links>
</items>
</tab1>
</items>
</items>
</jcr:root>
Any user who needs this list of fields together can directly use this custom xtype while developing dialogs instead of creating them individually. We can use this custom xtype as a mutilfield to make it as a replicant.
Code and Steps are given below.
1) Registering the Custom Component : Create a Javascript file in Client Lib folder and add that into the Component JSP. This Javascript file is used to create the custom xtype and then register it to with EXT JS , so that it can be used in Dialogs.
CustomPathField.js
----------------------------------------------------------------------------------------------------------------------------------
/**
* @class MyClientLib.CustomPathFieldWidget
* @extends CQ.form.CompositeField
* This is a custom path field with a Link Text and a Link URL
* @param {Object} config the config object
*/
/**
* @class Ejst.CustomWidget
* @extends CQ.form.CompositeField
* This is a custom widget based on {@link CQ.form.CompositeField}.
* @constructor
* Creates a new CustomWidget.
* @param {Object} config The config object
*/
CQ.form.CustomMultiField = CQ.Ext.extend(CQ.form.CompositeField, {
/**
* @private
* @type CQ.Ext.form.TextField
*/
hiddenField: null,
/**
* @private
* @type CQ.Ext.form.TextField
*/
linkText: null,
/**
* @private
* @type CQ.Ext.form.PathField
*/
linkURL: null,
/**
* @private
* @type CQ.Ext.form.CheckBox
*/
openInNewWindow: null,
constructor: function (config) {
config = config || {};
var defaults = {
"border": true,
"labelWidth": 75,
"layout": "form"
};
config = CQ.Util.applyDefaults(config, defaults);
CQ.form.CustomMultiField.superclass.constructor.call(this, config);
},
initComponent: function () {
CQ.form.CustomMultiField.superclass.initComponent.call(this);
// Hidden field
this.hiddenField = new CQ.Ext.form.Hidden({
name: this.name
});
this.add(this.hiddenField);
// Text TextField to enter Title
this.linkText = new CQ.Ext.form.TextField({
cls: "customwidget-1",
maxLength: 100,
emptyText: "Enter Title",
maxLengthText: "A maximum of 100 characters is allowed for the Link Text.",
width: 335,
allowBlank: true,
name : "item",
listeners: {
change: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.linkText);
// Link PathField to map a URL
this.linkURL = new CQ.form.PathField({
cls: "customwidget-2",
allowBlank: true,
emptyText: "Enter Title URL",
width: 335,
listeners: {
change: {
scope: this,
fn: this.updateHidden
},
dialogclose: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.linkURL);
// Link openInNewWindow
this.openInNewWindow = new CQ.Ext.form.Checkbox({
cls: "customwidget-3",
boxLabel: "New window",
listeners: {
change: {
scope: this,
fn: this.updateHidden
},
check: {
scope: this,
fn: this.updateHidden
}
}
});
this.add(this.openInNewWindow);
},
processInit: function (path, record) {
this.linkText.processInit(path, record);
this.linkURL.processInit(path, record);
this.openInNewWindow.processInit(path, record);
},
setValue: function (value) {
var link = JSON.parse(value);
this.linkText.setValue(link.text);
this.linkURL.setValue(link.url);
this.openInNewWindow.setValue(link.openInNewWindow);
},
getValue: function () {
return this.getRawValue();
},
getRawValue: function () {
var link = {
"url": this.linkURL.getValue(),
"text": this.linkText.getValue(),
"openInNewWindow": this.openInNewWindow.getValue()
};
return JSON.stringify(link);
},
updateHidden: function () {
this.hiddenField.setValue(this.getValue());
}
});
CQ.Ext.reg("CustomMultiField", CQ.form.CustomMultiField);
----------------------------------------------------------------------------------------------------------------------------------
When this Javascript is executed you should have the CustomMultiField as xtype.
2) Using the Custom Component in Dialog: Use this xtype in the Dialog to see all the 3 fields ( Text Field, Link Field , Open in New Window ) displayed as a set. For example, if we want to display them as a multifield, here is how the dialog.xml should look like.
<?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"
width="550"
xtype="dialog">
<items
jcr:primaryType="cq:Widget"
xtype="tabpanel">
<items jcr:primaryType="cq:WidgetCollection">
<tab1
jcr:primaryType="cq:Panel"
title="Links Component">
<items jcr:primaryType="cq:WidgetCollection">
<links
jcr:primaryType="cq:Widget"
border="false"
fieldDescription="Press + to add more links"
fieldLabel="Links"
hideLabel="true"
name="./links"
xtype="multifield">
<fieldConfig
jcr:primaryType="cq:Widget"
xtype="CustomMultiField"/>
</links>
</items>
</tab1>
</items>
</items>
</jcr:root>
Thanks for posting this. Can you please attach some screen shots with each of the steps and also how the final Dialog looks? As they say a picture is worth a 1000 words I am sure it will help novice developers (like me) to make the most out of it.
ReplyDeletethanks
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDelete