Expand my Community achievements bar.

SOLVED

CoralUI 3 show hide based off a checkbox?

Avatar

Level 1

Hello,

Does anyone have an (ideally copy/paste) example of how to do a showing and hiding of some fields based on the checked value of a form checkbox in AEM 6.5+?

I see over here there is a CoralUI 3-based example containing a Dialog Snippet, of how to do a conditional show/hide of some AEM 6.5.12 option fields, which works well for me.

I've looked at this CoralUI 3 Migration guide and it tells me that Coral.Checkbox has been promoted to a custom element, though little else I can glean.

For additional context, I have existing CoralUI 2-based examples (which in their implementation I can see in the DOM add a .hidden CSS class, which doesn't seem to exist in CoralUI 3) which I'd like to migrate.

 

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hello @PeterJS ,

Here is an example where you will able to add checkbox and give show hide functionality.

To do this you need to add the following steps:

  1. Create a clientlib called commons.coral-checkbox-showhide with checkbox-showhide.js
  2. In your dialog add this clientlib as an extra dependency
    extraClientlibs="[commons.checkbox-showhide]"

     

Example of usages:

<enableOpener
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
text="Enable Opener"
name="./enableOpen"
value="{Boolean}true"
uncheckedValue="{Boolean}false">
<granite:data
jcr:primaryType="nt:unstructured"
toggle-checkbox_master="true"/>
</enableModalOpener>

<containerWrapper
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<customName
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Custom ID"
emptyText="Custom ID"
name="./customName"/>
</items>
<granite:data
jcr:primaryType="nt:unstructured"
toggle-checkbox_slave="true"/>
</containerWrapper>

 

 

In the checkbox-showhide.js

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

var TOGGLE_ATTRIBUTE_PREFIX = "data-toggle-";
var MASTER_ATTRIBUTE_SUFFIX = "_master";
var SLAVE_ATTRIBUTE_SUFFIX = "_slave";
var DIALOG_CONTENT_SELECTOR = ".cq-dialog-content";


/**
* Build the master and slave attribute names from the toggle name.
* @param {string} toggleName
*/
function getAttributes(toggleName) {
return {
master: TOGGLE_ATTRIBUTE_PREFIX + toggleName + MASTER_ATTRIBUTE_SUFFIX,
slave: TOGGLE_ATTRIBUTE_PREFIX + toggleName + SLAVE_ATTRIBUTE_SUFFIX
}
}

/**
* Builds the master and slave selectors from the toggle name.
* @param {string} toggleName
*/
function getSelectors(toggleName) {
var attributes = getAttributes(toggleName);
return {
master: "[" + attributes.master + "]",
slave: "[" + attributes.slave + "]"
}
}

var toggle = {
name: "checkbox",
updateFunction: function (master, $slaves) {
var isChecked = master[0].hasAttribute("checked");
$slaves.each(function () {
if (isChecked.toString() !== $(this).attr(getAttributes("checkbox").slave)) {
$(this).addClass("hide");
} else {
$(this).removeClass("hide");
}
})
}
};

var selectors = getSelectors(toggle.name);

// When the dialog is loaded, init all slaves
$(document).on("foundation-contentloaded", function (e) {

// Find the dialog
var $dialog = $(e.target);
if ($dialog && $dialog.length === 1) {

// Find the toggel master
var $master = $dialog.find(selectors.master);
if ($master) {
if ($master.length !== 1) {
console.error($master.length + " masters for toggle <" + toggle + ">");
return;
}

// Update slaves
var $slaves = $dialog.find(selectors.slave);
toggle.updateFunction($master, $slaves);
}
}
});

// When a value is changed, trigger update
$(document).on("change", function (e) {

// Find the master which was updated
var $master = $(e.target);
var $dialog = $master.parents(DIALOG_CONTENT_SELECTOR);
if ($master && $master.length === 1 && $master.is(selectors.master)) {

// Update slaves
var $slaves = $dialog.find(selectors.slave);
toggle.updateFunction($master, $slaves);
}
});

})(document, Granite.$);

View solution in original post

4 Replies

Avatar

Correct answer by
Community Advisor

Hello @PeterJS ,

Here is an example where you will able to add checkbox and give show hide functionality.

To do this you need to add the following steps:

  1. Create a clientlib called commons.coral-checkbox-showhide with checkbox-showhide.js
  2. In your dialog add this clientlib as an extra dependency
    extraClientlibs="[commons.checkbox-showhide]"

     

Example of usages:

<enableOpener
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/checkbox"
text="Enable Opener"
name="./enableOpen"
value="{Boolean}true"
uncheckedValue="{Boolean}false">
<granite:data
jcr:primaryType="nt:unstructured"
toggle-checkbox_master="true"/>
</enableModalOpener>

<containerWrapper
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/container">
<items jcr:primaryType="nt:unstructured">
<customName
jcr:primaryType="nt:unstructured"
sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
fieldLabel="Custom ID"
emptyText="Custom ID"
name="./customName"/>
</items>
<granite:data
jcr:primaryType="nt:unstructured"
toggle-checkbox_slave="true"/>
</containerWrapper>

 

 

In the checkbox-showhide.js

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

var TOGGLE_ATTRIBUTE_PREFIX = "data-toggle-";
var MASTER_ATTRIBUTE_SUFFIX = "_master";
var SLAVE_ATTRIBUTE_SUFFIX = "_slave";
var DIALOG_CONTENT_SELECTOR = ".cq-dialog-content";


/**
* Build the master and slave attribute names from the toggle name.
* @param {string} toggleName
*/
function getAttributes(toggleName) {
return {
master: TOGGLE_ATTRIBUTE_PREFIX + toggleName + MASTER_ATTRIBUTE_SUFFIX,
slave: TOGGLE_ATTRIBUTE_PREFIX + toggleName + SLAVE_ATTRIBUTE_SUFFIX
}
}

/**
* Builds the master and slave selectors from the toggle name.
* @param {string} toggleName
*/
function getSelectors(toggleName) {
var attributes = getAttributes(toggleName);
return {
master: "[" + attributes.master + "]",
slave: "[" + attributes.slave + "]"
}
}

var toggle = {
name: "checkbox",
updateFunction: function (master, $slaves) {
var isChecked = master[0].hasAttribute("checked");
$slaves.each(function () {
if (isChecked.toString() !== $(this).attr(getAttributes("checkbox").slave)) {
$(this).addClass("hide");
} else {
$(this).removeClass("hide");
}
})
}
};

var selectors = getSelectors(toggle.name);

// When the dialog is loaded, init all slaves
$(document).on("foundation-contentloaded", function (e) {

// Find the dialog
var $dialog = $(e.target);
if ($dialog && $dialog.length === 1) {

// Find the toggel master
var $master = $dialog.find(selectors.master);
if ($master) {
if ($master.length !== 1) {
console.error($master.length + " masters for toggle <" + toggle + ">");
return;
}

// Update slaves
var $slaves = $dialog.find(selectors.slave);
toggle.updateFunction($master, $slaves);
}
}
});

// When a value is changed, trigger update
$(document).on("change", function (e) {

// Find the master which was updated
var $master = $(e.target);
var $dialog = $master.parents(DIALOG_CONTENT_SELECTOR);
if ($master && $master.length === 1 && $master.is(selectors.master)) {

// Update slaves
var $slaves = $dialog.find(selectors.slave);
toggle.updateFunction($master, $slaves);
}
});

})(document, Granite.$);

Avatar

Community Advisor

Hi @PeterJS ,

Could you please check below JS. It's working for me.

 

 

(($, Coral) => {
    // when dialog gets injected
    $(document).on('foundation-contentloaded', (e) => {
        // if there is already an inital value make sure the according target element becomes visible
        checkboxShowHideHandler($('.cq-dialog-checkbox-showhide', e.target));
    });

    $(document).on('change', '.cq-dialog-checkbox-showhide', () => {
        checkboxShowHideHandler($(this));
    });

    function checkboxShowHideHandler(el) {
        el.each((i, element) => {
            if ($(element).is('coral-checkbox')) {
                // handle Coral3 base drop-down
                Coral.commons.ready(element, (component) => {
                    showHide(component, element);
                    component.on('change', () => {
                        showHide(component, element);
                    });
                });
            } else {
                // handle Coral2 based drop-down
                const component = $(element).data('checkbox');
                if (component) {
                    showHide(component, element);
                }
            }
        });
    }

    function showHide(component, element) {
        // get the selector to find the target elements. its stored as data-.. attribute
        const target = $(element).data('cqDialogCheckboxShowhideTarget');
        const $target = $(target);

        if (target) {
            $target.addClass('hide');
            if (component.checked) {
                $target.removeClass('hide');
            }
        }
    }
})(jQuery, Coral);

 

 

Avatar

Level 1

Thank you @Sady_Rifat @MayurSatav @arunpatidar for your answers. I'm still going through them as there's a lot to understand.

Though for a start at least, it's at least quite clear the CoralUI 2-based ".hidden" CSS class would need to go, and the (Granite UI?) ".hide" CSS class essentially common to all answers is what will ultimately need and be needed to implement the show hide based off a checkbox which I am looking for.