Multifield dialog-
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
jcr:primaryType="nt:unstructured"
jcr:title="List Collection"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<tabs
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/tabs"
maximized="{Boolean}true">
<items jcr:primaryType="nt:unstructured">
<Basic
jcr:primaryType="nt:unstructured"
jcr:title="Basic"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns"
margin="{Boolean}false">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<enterheadline
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Please enter headline"
fieldLabel="Enter Headline"
name="./headlineText"/>
<headingurl
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Select Link Path"
fieldLabel="Link Url"
name="./headingUrl"/>
<menu
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
composite="{Boolean}true"
fieldDescription="Click + to add a new page"
fieldLabel="Multifield collection"
name="./menu">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/fieldset"
multifield-nested=""
name="./items">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
method="absolute"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<linkurl
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathfield"
fieldDescription="Select Link Path"
fieldLabel="Link Url"
name="./linkUrl"/>
<enterlinktext
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Enter Link Text"
fieldLabel="Enter link text"
name="./linkText"/>
<submenu
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/multifield"
fieldDescription="Add upto 14 links"
fieldLabel="Submenus"
name="./submenussss">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/fieldset"
name="./submenu">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
method="absolute"/>
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<url
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/pathbrowser"
allowBlank="false"
fieldLabel="Provide navigation link for text"
key="url"
name="./subUrl"/>
<title
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/form/textfield"
allowBlank="false"
fieldLabel="Provide navigation text"
key="title"
maxLength="16"
maxLengthText="A maximum of 16 characters is allowed for navigation text"
name="./subTitle"/>
</items>
</column>
</items>
</field>
</submenu>
</items>
</column>
</items>
</field>
</menu>
</items>
</column>
</items>
</Basic>
</items>
</tabs>
</items>
</content>
</jcr:root>
navigation.js
"use strict";
use(function () {
var readJson = null;
var listArr = [];
if (this.fieldValue != '') {
readJson = this.fieldValue;
var count = 0;
if (readJson != null && readJson != "") {
readJson.forEach(function (entry) {
var itemJson = entry;
listArr[count++] = itemJson;
});
}
} else if (this.fieldName != '') {
readJson = granite.resource.properties[this.fieldName];
if (typeof readJson != "undefined" && readJson != null && readJson != "") {
if (readJson.length > 0) {
var count = 0;
readJson.forEach(function (entry) {
var itemJson = JSON.parse(entry);
listArr[count++] = itemJson;
});
} else {
listArr[0] = JSON.parse(readJson);
}
}
}
return {
listJson: listArr
}
});
Sightly: somecomponent.html
<sly data-sly-use.menuInfo="${'navigation.js' @ fieldName = 'items',fieldValue = ''}">
<sly data-sly-list.menuDetails="${menuInfo.listJson}">
<li><a href="${menuDetails.linkUrl}">${menuDetails.linkText}</a>
<ul>
<sly data-sly-use.submenuInfo="${'navigation.js' @ fieldName = '',fieldValue = menuDetails.submenu}">
<sly data-sly-list.innerlistJson="${submenuInfo.listJson}">
${innerlistJson.subTitle}</span></a></li>
</sly>
</sly>
</ul>
</li>
</sly>
</sly>
I have created this without using ACS-common package. hope it will helpful for the community
Thanks for posting this.
Views
Replies
Total Likes
thank you for this!! <3
Views
Replies
Total Likes
the add button for multifield node which is menu
slingResourceType: granite/ui/components/foundation/form/multifield - add button not working
sling:resourceType="granite/ui/components/coral/foundation/form/multifield" - add button working but the Ok/Submit button not working
Views
Replies
Total Likes
Are you using ACS common.?
Views
Replies
Total Likes
(function () {
var DATA_NESTED = "data-multifield-nested";
var CFFW = ".coral-Form-fieldwrapper";
//reads multifield data from server, creates the nested composite multifields and fills them
function addDataInFields() {
$(document).on("dialog-ready", function () {
var $fieldSets = $("[" + DATA_NESTED + "][class='coral-Form-fieldset']");
if (_.isEmpty($fieldSets)) {
return;
}
var mNames = [];
$fieldSets.each(function (i, fieldSet) {
mNames.push($(fieldSet).data("name"));
});
mNames = _.uniq(mNames);
var actionUrl = $fieldSets.closest("form.foundation-form").attr("action") + ".json";
$.ajax(actionUrl).done(postProcess);
function postProcess(data) {
_.each(mNames, function (mName) {
buildMultiField(data, mName);
});
}
//creates & fills the nested multifield with data
function fillNestedFields($multifield, valueArr) {
_.each(valueArr, function (record, index) {
$multifield.find(".js-coral-Multifield-add").click();
//a setTimeout may be needed
_.each(record, function (value, key) {
var $field = $($multifield.find("[name='./" + key + "']")[index]);
$field.val(value);
});
});
}
function buildMultiField(data, mName) {
if (_.isEmpty(mName)) {
return;
}
$fieldSets = $("[data-name='" + mName + "']");
mName = mName.substring(2);
var mValues = data[mName], $field, name;
if (_.isString(mValues)) {
mValues = [JSON.parse(mValues)];
}
_.each(mValues, function (record, i) {
if (!record) {
return;
}
if (_.isString(record)) {
record = JSON.parse(record);
}
_.each(record, function (rValue, rKey) {
$field = $($fieldSets[i]).find("[name='./" + rKey + "']");
if (_.isArray(rValue) && !_.isEmpty(rValue)) {
fillNestedFields($($fieldSets[i]).find("[data-init='multifield']"), rValue);
} else {
$field.val(rValue);
}
});
});
}
});
}
function fillValue($field, record) {
var name = $field.attr("name");
if (!name) {
return;
}
//strip ./
if (name.indexOf("./") === 0) {
name = name.substring(2);
}
record[name] = $field.val();
//remove the field, so that individual values are not POSTed
//$field.remove();
}
//for getting the nested multifield data as js objects
function getRecordFromMultiField($multifield) {
var $fieldSets = $multifield.find("[class='coral-Form-fieldset']");
var records = [], record, $fields, name;
$fieldSets.each(function (i, fieldSet) {
$fields = $(fieldSet).find("[name]");
record = {};
$fields.each(function (j, field) {
fillValue($(field), record);
});
if (!$.isEmptyObject(record)) {
records.push(record);
}
});
return records;
}
//collect data from widgets in multifield and POST them to CRX as JSON
function collectDataFromFields() {
$(document).on("click", ".cq-dialog-submit", function () {
var fieldd = $(".coral-Multifield");
var sizee = fieldd.attr("data-minlinksallowed");
if (sizee) {
var uii = $(window).adaptTo("foundation-ui");
var totalLinkCount = $(".coral-Multifield-list li").length;
if (totalLinkCount < sizee) {
uii.alert("Minimum " + sizee + " fields are required");
return false;
}
}
var $form = $(this).closest("form.foundation-form");
$form.find('input.input-mf-data').each(function(){
$(this).remove();
});
var $fieldSets = $("[" + DATA_NESTED + "][class='coral-Form-fieldset']");
var record, $fields, $field, name, $nestedMultiField;
$fieldSets.each(function (i, fieldSet) {
$fields = $(fieldSet).children().children(CFFW);
record = {};
$fields.each(function (j, field) {
$field = $(field);
//may be a nested multifield
$nestedMultiField = $field.find("[data-init='multifield']");
if ($nestedMultiField.length === 0) {
fillValue($field.find("[name]"), record);
} else {
name = $nestedMultiField.find("[class='coral-Form-fieldset']").data("name");
if (!name) {
return;
}
//strip ./
name = name.substring(2);
record[name] = getRecordFromMultiField($nestedMultiField);
}
});
if ($.isEmptyObject(record)) {
return;
}
//add the record JSON in a hidden field as string
$('<input />').attr('type', 'hidden')
.attr('class', 'input-mf-data')
.attr('name', $(fieldSet).data("name"))
.attr('value', JSON.stringify(record))
.appendTo($form);
});
return true;
});
}
$(document).ready(function () {
addDataInFields();
collectDataFromFields();
});
$(document).on("dialog-ready", function () {
$(".js-coral-Multifield-add").click(function () {
var field = $(this).parent();
var size = field.attr("data-limit");
if (size) {
var ui = $(window).adaptTo("foundation-ui");
var totalLinkCount = $(this).prev('ol').children('li').length;
if (totalLinkCount >= size) {
ui.alert("Warning", "Only " + totalLinkCount + " fields are allowed!", "notice");
return false;
}
}
});
});
//extend otb multifield for adjusting event propagation when there are nested multifields
//for working around the nested multifield add and reorder
CUI.MultifieldProject = new Class({
toString: "Multifield",
extend: CUI.Multifield,
construct: function (options) {
this.script = this.$element.find(".js-coral-Multifield-input-template:last");
},
_addListeners: function () {
this.superClass._addListeners.call(this);
//otb coral event handler is added on selector .js-coral-Multifield-add
//any nested multifield add click events are propagated to the parent multifield
//to prevent adding a new composite field in both nested multifield and parent multifield
//when user clicks on add of nested multifield, stop the event propagation to parent multifield
this.$element.on("click", ".js-coral-Multifield-add", function (e) {
e.stopPropagation();
});
this.$element.on("drop", function (e) {
e.stopPropagation();
});
}
});
CUI.Widget.registry.register("multifield", CUI.MultifieldProject);
})();
(function () {
var DATA_NESTED = "data-multifield-nested";
var CFFW = ".coral-Form-fieldwrapper";
//reads multifield data from server, creates the nested composite multifields and fills them
function addDataInFields() {
$(document).on("dialog-ready", function () {
var $fieldSets = $("[" + DATA_NESTED + "][class='coral-Form-fieldset']");
if (_.isEmpty($fieldSets)) {
return;
}
var mNames = [];
$fieldSets.each(function (i, fieldSet) {
mNames.push($(fieldSet).data("name"));
});
mNames = _.uniq(mNames);
var actionUrl = $fieldSets.closest("form.foundation-form").attr("action") + ".json";
$.ajax(actionUrl).done(postProcess);
function postProcess(data) {
_.each(mNames, function (mName) {
buildMultiField(data, mName);
});
}
//creates & fills the nested multifield with data
function fillNestedFields($multifield, valueArr) {
_.each(valueArr, function (record, index) {
$multifield.find(".js-coral-Multifield-add").click();
//a setTimeout may be needed
_.each(record, function (value, key) {
var $field = $($multifield.find("[name='./" + key + "']")[index]);
$field.val(value);
});
});
}
function buildMultiField(data, mName) {
if (_.isEmpty(mName)) {
return;
}
$fieldSets = $("[data-name='" + mName + "']");
mName = mName.substring(2);
var mValues = data[mName], $field, name;
if (_.isString(mValues)) {
mValues = [JSON.parse(mValues)];
}
_.each(mValues, function (record, i) {
if (!record) {
return;
}
if (_.isString(record)) {
record = JSON.parse(record);
}
_.each(record, function (rValue, rKey) {
$field = $($fieldSets[i]).find("[name='./" + rKey + "']");
if (_.isArray(rValue) && !_.isEmpty(rValue)) {
fillNestedFields($($fieldSets[i]).find("[data-init='multifield']"), rValue);
} else {
$field.val(rValue);
}
});
});
}
});
}
function fillValue($field, record) {
var name = $field.attr("name");
if (!name) {
return;
}
//strip ./
if (name.indexOf("./") === 0) {
name = name.substring(2);
}
record[name] = $field.val();
//remove the field, so that individual values are not POSTed
//$field.remove();
}
//for getting the nested multifield data as js objects
function getRecordFromMultiField($multifield) {
var $fieldSets = $multifield.find("[class='coral-Form-fieldset']");
var records = [], record, $fields, name;
$fieldSets.each(function (i, fieldSet) {
$fields = $(fieldSet).find("[name]");
record = {};
$fields.each(function (j, field) {
fillValue($(field), record);
});
if (!$.isEmptyObject(record)) {
records.push(record);
}
});
return records;
}
//collect data from widgets in multifield and POST them to CRX as JSON
function collectDataFromFields() {
$(document).on("click", ".cq-dialog-submit", function () {
var fieldd = $(".coral-Multifield");
var sizee = fieldd.attr("data-minlinksallowed");
if (sizee) {
var uii = $(window).adaptTo("foundation-ui");
var totalLinkCount = $(".coral-Multifield-list li").length;
if (totalLinkCount < sizee) {
uii.alert("Minimum " + sizee + " fields are required");
return false;
}
}
var $form = $(this).closest("form.foundation-form");
$form.find('input.input-mf-data').each(function(){
$(this).remove();
});
var $fieldSets = $("[" + DATA_NESTED + "][class='coral-Form-fieldset']");
var record, $fields, $field, name, $nestedMultiField;
$fieldSets.each(function (i, fieldSet) {
$fields = $(fieldSet).children().children(CFFW);
record = {};
$fields.each(function (j, field) {
$field = $(field);
//may be a nested multifield
$nestedMultiField = $field.find("[data-init='multifield']");
if ($nestedMultiField.length === 0) {
fillValue($field.find("[name]"), record);
} else {
name = $nestedMultiField.find("[class='coral-Form-fieldset']").data("name");
if (!name) {
return;
}
//strip ./
name = name.substring(2);
record[name] = getRecordFromMultiField($nestedMultiField);
}
});
if ($.isEmptyObject(record)) {
return;
}
//add the record JSON in a hidden field as string
$('<input />').attr('type', 'hidden')
.attr('class', 'input-mf-data')
.attr('name', $(fieldSet).data("name"))
.attr('value', JSON.stringify(record))
.appendTo($form);
});
return true;
});
}
$(document).ready(function () {
addDataInFields();
collectDataFromFields();
});
$(document).on("dialog-ready", function () {
$(".js-coral-Multifield-add").click(function () {
var field = $(this).parent();
var size = field.attr("data-limit");
if (size) {
var ui = $(window).adaptTo("foundation-ui");
var totalLinkCount = $(this).prev('ol').children('li').length;
if (totalLinkCount >= size) {
ui.alert("Warning", "Only " + totalLinkCount + " fields are allowed!", "notice");
return false;
}
}
});
});
//extend otb multifield for adjusting event propagation when there are nested multifields
//for working around the nested multifield add and reorder
CUI.MultifieldProject = new Class({
toString: "Multifield",
extend: CUI.Multifield,
construct: function (options) {
this.script = this.$element.find(".js-coral-Multifield-input-template:last");
},
_addListeners: function () {
this.superClass._addListeners.call(this);
//otb coral event handler is added on selector .js-coral-Multifield-add
//any nested multifield add click events are propagated to the parent multifield
//to prevent adding a new composite field in both nested multifield and parent multifield
//when user clicks on add of nested multifield, stop the event propagation to parent multifield
this.$element.on("click", ".js-coral-Multifield-add", function (e) {
e.stopPropagation();
});
this.$element.on("drop", function (e) {
e.stopPropagation();
});
}
});
CUI.Widget.registry.register("multifield", CUI.MultifieldProject);
})();
Views
Replies
Total Likes
This solution is not working in coral3 for aem6.3 migration. In coral 3 multifield tenplate is different so this js doesnt work.
Views
Replies
Total Likes
Hi,
In Coral3, multifields items are store as a node not as JSON, To make it work this with Js or Java, you can iterate through nodes and return as JSON array or java Arraylist.
Views
Replies
Total Likes
Using aem 6.3 service pack and cummulative fix pack, multiield of 'n' number of levels can be added in AEM 6.3.
Views
Replies
Total Likes
Views
Like
Replies
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies