May 1, 2020
Estimated Post Reading Time ~

Touch UI - Hide/Show fields inside coral-3 multifield in AEM by coral dropdown

This post shows how to hide/show fields inside multifield in the Touch UI dialog of AEM.
The resourceType used here for composite multifield, selection dropdown, textfield, and numberfield are coral 3 ui components.

For Example: granite/ui/components/coral/foundation/form/multifield and it has been tested in aem 6.3.

This method uses granite:class attribute added as a property to add a class in the fields and granite:data node with data key-value added as a property to add data attributes in the fields.
Implemented 4 steps are mentioned below:

1. Add granite: class attribute to the selection field as shown below
granite:class: cq-dialog-dropdown-showhide1


2. Add granite:data node inside selection field with data key-value added as property as shown below:
cq-dialog-dropdown-showhide-target1 : .list-option-listfrom-showhide-target


3. Add granite:class attribute to each of the fields which you want to show/hide based on the dropdown selection which matches the data-target attribute of selection field as shown below:
granite:class: list-option-listfrom-showhide-target1


4. Add granite:data node inside each of the fields which you want to show/hide with showhidetargetvalue key
and value equal to dropdown options value as shown below:
showhidetargetvalue : textval


To avoid any confusion, the cq_dialog xml I created is pasted below.

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:granite="http://www.adobe.com/jcr/granite/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="Multi ShowHide Component"
sling:resourceType="cq/gui/components/authoring/dialog"
helpPath="https://www.adobe.com/go/aem6_3_docs_component_en#Image - HTL">
<content
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/tabs"
type="nav"/>
<items jcr:primaryType="nt:unstructured">
<multi
jcr:primaryType="nt:unstructured"
jcr:title="Multi"
sling:resourceType="granite/ui/components/foundation/section">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/fixedcolumns"
margin="{Boolean}false"/>
<items jcr:primaryType="nt:unstructured">
<custom
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<items jcr:primaryType="nt:unstructured">
<heading
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/heading"
class="coral-Heading coral-Heading--4"
level="{Long}4"
text="Composite Multifield"/>
<well
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/container">
<layout
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/foundation/layouts/well"/>
<items jcr:primaryType="nt:unstructured">
<fieldenter
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/multifield"
composite="{Boolean}true">
<field
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container"
fieldLabel="Products Container"
name="./products">
<items jcr:primaryType="nt:unstructured">
<listFromMulti
granite:class="cq-dialog-dropdown-showhide1"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/select"
fieldLabel="Select Multi showhide"
name="listFromMulti">
<items jcr:primaryType="nt:unstructured">
<text
jcr:primaryType="nt:unstructured"
text="Text field"
value="textval"/>
<num
jcr:primaryType="nt:unstructured"
text="Num field"
value="numval"/>
</items>
<granite:data
jcr:primaryType="nt:unstructured"
cq-dialog-dropdown-showhide-target1=".list-option-listfrom-showhide-target1"/>
</listFromMulti>
<multitext
granite:class="list-option-listfrom-showhide-target1"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Multi Text"
name="multitext"
showhidetargetvalue="textval">
<granite:data
jcr:primaryType="nt:unstructured"
showhidetargetvalue="textval"/>
</multitext>
<multinum
granite:class="list-option-listfrom-showhide-target1"
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/numberfield"
fieldLabel="Multi Num"
name="multinum"
showhidetargetvalue="numval">
<granite:data
jcr:primaryType="nt:unstructured"
showhidetargetvalue="numval"/>
</multinum>
</items>
</field>
</fieldenter>
</items>
</well>
</items>
</custom>
</items>
</multi>
</items>
</content>
</jcr:root>

Now to toggle fields using selection dropdown inside composite multifield independently, use below jquery logic written in a js file inside the clientlibs folder of the component with category cq.authoring.dialog.

(function(document, $) {
"use strict";

// when dialog gets injected
$(document).on("foundation-contentloaded", function(e) {
// if there is already an inital value make sure the
//according target element becomes visible
showHideHandler($(".cq-dialog-dropdown-showhide1", e.target));
});

$(document).on("change", ".cq-dialog-dropdown-showhide1", function(e) {
showHideHandler($(this));
});

function showHideHandler(el) {
el.each(function(i, element) {
// handle Coral3 base drop-down
Coral.commons.ready(element, function(component) {
showHideCustom(component, element);
component.on("change", function() {
showHideCustom(component, element);
});
});
})
}

function showHideCustom(component, element) {
// get the selector to find the target elements.
//its stored as data-.. attribute
var target = $(element).data("cq-dialog-dropdown-showhide-target1");
var $target = $(target);
var elementIndex = $(element).closest('coral-multifield-item').index();

if (target) {
var value;
if (component.value) {
value = component.value;
} else {
value = component.getValue();
}
$(element).closest("coral-multifield-item").find(target)
.each(function(index) {
var tarIndex = $(this).closest('coral-multifield-item').index();
if (elementIndex == tarIndex) {
$(this).not(".hide").parent().addClass("hide");
$(this).filter("[data-showhidetargetvalue='" + value + "']")
.parent().removeClass("hide");
}
});
}
}

})(document, Granite.$);

The screenshot of how the dialog looks like and how it to toggle fields is shown below


You can also find this component in my github project here.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.