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

AEM 63 - Touch UI Expandable Collapsible Composite Multifield

$
0
0

Goal


Extend the product Composite Multifield to provide Expand / Collapse feature, for better experience and easy reordering

Demo | Package Install | Github


All Items Collapsed



One Item Expanded

Easy Reordering

Solution


1) Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-touchui-collapsible-multifield

2) Sample dialog with composite multifield /apps/eaem-touchui-collapsible-multifield/sample-collapsible-multifield/cq: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="63 Collapsible Multifield"
sling:resourceType="cq/gui/components/authoring/dialog">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<products
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true"
eaem-show-on-collapse="EAEM.showProductName"
fieldLabel="Products">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
name="./products">
<items jcr:primaryType="nt:unstructured">
<column
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<product
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldDescription="Name of Product"
fieldLabel="Product Name"
name="./product"/>
<path
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/pathbrowser"
fieldDescription="Select Path"
fieldLabel="Path"
name="./path"
rootPath="/content"/>
<startDate
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/datepicker"
class="field"
displayedFormat="YYYY-MM-DD HH:mm"
fieldLabel="Start Date"
name="./startDate"
type="datetime"/>
<show
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
name="./show"
text="Show?"
value="yes"/>
<type
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldDescription="Select Size"
fieldLabel="Size"
name="./size">
<items jcr:primaryType="nt:unstructured">
<def
jcr:primaryType="nt:unstructured"
text="Select Size"
value=""/>
<small
jcr:primaryType="nt:unstructured"
text="Small"
value="small"/>
<medium
jcr:primaryType="nt:unstructured"
text="Medium"
value="medium"/>
<large
jcr:primaryType="nt:unstructured"
text="Large"
value="large"/>
</items>
</type>
</items>
</column>
</items>
</field>
</products>
</items>
</column>
</items>
</content>
</jcr:root>


3) #14 eaem-show-on-collapse property is for the function creating summary of multifield items in collapsed mode; here it is EAEM.showProductName, returns the first field value in multifield item (if empty or error in creating summary Click to expand text is shown)

4) Create node /apps/eaem-touchui-collapsible-multifield/clientlib of type cq:ClientLibraryFolder, add String property categories with value cq.authoring.dialog.all, String property dependencies with value underscore

5) Create file (nt:file) /apps/eaem-touchui-collapsible-multifield/clientlib/js.txt, add

                       collapsible-multifield.js

6) Create file (nt:file) /apps/eaem-touchui-collapsible-multifield/clientlib/collapsible-multifield.js, add the following code

(function(){
if(typeof EAEM === "undefined"){
EAEM = {};
}

//the function executed when user clicks collapse; returns summary of multifield item data
EAEM.showProductName = function(fields){
return Object.values(fields)[0];
}
}());

(function ($, $document, gAuthor) {
var summaryCreators = {},
CORAL_MULTIFIELD = "coral-multifield",
CORAL_MULTIFIELD_ITEM = "coral-multifield-item",
CORAL_MULTIFIELD_ITEM_CONTENT = "coral-multifield-item-content",
EAEM_SHOW_ON_COLLAPSE = "eaem-show-on-collapse",
RS_MULTIFIELD = "granite/ui/components/coral/foundation/form/multifield";

$document.on("dialog-ready", addCollapsers);

function addCollapsers(){
var $multifields = $(CORAL_MULTIFIELD).css("padding-right", "2.5rem");

if(_.isEmpty($multifields)){
return;
}

$multifields.find(CORAL_MULTIFIELD_ITEM).each(handler);

$multifields.on('change', function(){
$multifields.find(CORAL_MULTIFIELD_ITEM).each(handler);
});

loadShowSummaryCreatorFunctions();

addExpandCollapseAll($multifields);

function handler(){
var $mfItem = $(this);

if(!_.isEmpty($mfItem.find("[icon=accordionUp]"))){
return;
}

addAccordionIcons($mfItem);

addSummarySection($mfItem);
}
}

function addSummarySection($mfItem){
var $summarySection = $("<div/>").insertAfter($mfItem.find(CORAL_MULTIFIELD_ITEM_CONTENT))
.addClass("coral-Well").css("cursor", "pointer").hide();

$summarySection.click(function(){
$mfItem.find("[icon='accordionDown']").click();
});
}

function addExpandCollapseAll($multifields){
var $mfAdd, expandAll, collapseAll;

$multifields.find("[coral-multifield-add]").each(handler);

function handler(){
$mfAdd = $(this);

expandAll = new Coral.Button().set({
variant: 'secondary',
innerText: "Expand All"
});

expandAll.$.css("margin-left", "10px").click(function(){
event.preventDefault();
$(this).closest(CORAL_MULTIFIELD).find("[icon='accordionDown']").click();
});

collapseAll = new Coral.Button().set({
variant: 'secondary',
innerText: "Collapse All"
});

collapseAll.$.css("margin-left", "10px").click(function(){
event.preventDefault();
$(this).closest(CORAL_MULTIFIELD).find("[icon='accordionUp']").click();
});

$mfAdd.after(expandAll).after(collapseAll);
}
}

function loadShowSummaryCreatorFunctions(){
var editable = gAuthor.DialogFrame.currentDialog.editable;

if(!editable){
return;
}

$.ajax(editable.config.dialog + ".infinity.json").done(fillLabelCreatorFns);

function fillLabelCreatorFns(obj){
if(!_.isObject(obj) || _.isEmpty(obj)){
return;
}

_.each(obj, function(value){
if(value["sling:resourceType"] === RS_MULTIFIELD){
if(!_.isEmpty(value.field) && !_.isEmpty(value.field.name)) {
summaryCreators[value.field.name] = value[EAEM_SHOW_ON_COLLAPSE];
}
}else{
if(_.isObject(value) && !_.isEmpty(value)){
fillLabelCreatorFns(value);
}
}
});
}
}

function addAccordionIcons($mfItem){
var up = new Coral.Button().set({
variant: "quiet",
icon: "accordionUp",
title: "Collapse"
});

up.setAttribute('style', 'position:absolute; top: 0; right: -2.175rem');
up.$.on('click', handler);

$mfItem.append(up);

var down = new Coral.Button().set({
variant: "quiet",
icon: "accordionDown",
title: "Expand"
});

down.setAttribute('style', 'position:absolute; top: 0; right: -2.175rem');
down.$.on('click', handler).hide();

$mfItem.append(down);

function handler(event){
event.preventDefault();

var mfName = $(this).closest(CORAL_MULTIFIELD).attr("data-granite-coral-multifield-name"),
$mfItem = $(this).closest(CORAL_MULTIFIELD_ITEM),
$summarySection = $mfItem.children("div");

$summarySection.html(getSummary($mfItem, mfName));

adjustUI.call(this, $summarySection);
}

function adjustUI($summarySection){
var icon = $(this).find("coral-icon").attr("icon"),
$content = $mfItem.find(CORAL_MULTIFIELD_ITEM_CONTENT);

if(icon == "accordionUp"){
if($summarySection.css("display") !== "none"){
return;
}

$summarySection.show();

$content.slideToggle( "fast", function() {
$content.hide();
});

up.$.hide();
down.$.show();
}else{
if($summarySection.css("display") === "none"){
return;
}

$summarySection.hide();

$content.slideToggle( "fast", function() {
$content.show();
});

up.$.show();
down.$.hide();
}
}
}

function getSummary($mfItem, mfName){
var summary = "Click to expand";

try{
if(summaryCreators[mfName]){
var fields = {};

$mfItem.find("input").each(function(){
var $input = $(this);
fields[$input.attr("name")] = $input.val();
});

summary = eval(summaryCreators[mfName])(fields);
}
}catch(err){}

if(!summary){
summary = "Click to expand";
}

return summary;
}
}(jQuery, jQuery(document), Granite.author));


Viewing all articles
Browse latest Browse all 525

Trending Articles



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