AEM 65 - Composite Multifield with Radio Group

Goal


Create a composite multifield configuration with radio buttons in multifield items

Demo | Package Install | Github


RadioGroup in Multifield

Dialog XML

<?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="65 Composite Multi Field Radio"
    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"/>
                                        <size
                                            jcr:primaryType="nt:unstructured"
                                            sling:resourceType="granite/ui/components/coral/foundation/form/radiogroup"
                                            name="./size"
                                            vertical="{Boolean}true">
                                            <items jcr:primaryType="nt:unstructured">
                                                <small
                                                    jcr:primaryType="nt:unstructured"
                                                    checked="{Boolean}true"
                                                    text="Small"
                                                    value="small"/>
                                                <medium
                                                    jcr:primaryType="nt:unstructured"
                                                    text="Medium"
                                                    value="medium"/>
                                                <large
                                                    jcr:primaryType="nt:unstructured"
                                                    text="Large"
                                                    value="large"/>
                                            </items>
                                        </size>
                                    </items>
                                </column>
                            </items>
                        </field>
                    </products>
                </items>
            </column>
        </items>
    </content>
</jcr:root>

Solution


1) Login to CRXDE Lite, create folder (nt:folder) /apps/eaem-touchui-composite-multifield-with-radio

2) Create clientlib (type cq:ClientLibraryFolder) /apps/eaem-touchui-composite-multifield-with-radio/clientlib and set a property categories of String[] type to [cq.authoring.dialog.all]dependencies of type String[] with value lodash

3) Create file ( type nt:file ) /apps/eaem-touchui-composite-multifield-with-radio/clientlib/js.txt, add the following

                         select-radios.js

4) Create file ( type nt:file ) /apps/eaem-touchui-composite-multifield-with-radio/clientlib/select-radios.js, add the following code to fix the issue with radio button select on dialog load

(function ($, $document) {
    var COMPOSITE_MULTIFIELD_SELECTOR = "coral-multifield[data-granite-coral-multifield-composite]";

    $document.on("foundation-contentloaded", function(e) {
        var composites = $(COMPOSITE_MULTIFIELD_SELECTOR, e.target);

        composites.each(function() {
            Coral.commons.ready(this, function(el) {
                selectRadioValue(el);
            });
        });
    });

    function selectRadioValue(multifield){
        var $multifield = $(multifield),
            dataPath = $multifield.closest(".cq-dialog").attr("action"),
            mfName = $multifield.attr("data-granite-coral-multifield-name");

        dataPath = dataPath + "/" + getStringAfterLastSlash(mfName);

        $.ajax({
            url: dataPath + ".2.json",
            cache: false
        }).done(handler);

        function handler(mfData){
            multifield.items.getAll().forEach(function(item, i) {
                var $mfItem = $(item),
                    $radio = $mfItem.find('[type="radio"]');

                var itemName = getJustMFItemName($radio.attr("name")),
                    radioName = $radio.attr("name");

                radioName = radioName.substring(radioName.lastIndexOf("/") + 1);

                if(_.isEmpty(mfData[itemName]) || _.isEmpty((mfData[itemName][radioName]))){
                    return;
                }

                $radio.filter("[value='" + mfData[itemName][radioName] + "']").prop("checked", "true");
            });
        }

        function getJustMFItemName(itemName){
            itemName = itemName.substr(itemName.indexOf(mfName) + mfName.length + 1);

            itemName = itemName.substring(0, itemName.indexOf("/"));

            return itemName;
        }
    }

    function getStringAfterLastSlash(str){
        if(!str || (str.indexOf("/") == -1)){
            return "";
        }

        return str.substr(str.lastIndexOf("/") + 1);
    }
}(jQuery, jQuery(document), Granite.author));



1 comment:

  1. Great example! when I try to reorder, it does not retain the value of the radio button. is there a bug?

    ReplyDelete