AEM 6510 - Multiselect Assets in Autocomplete Picker if Auto Complete exists in Multifield

Goal


In the Picker of Auto Complete granite/ui/components/coral/foundation/form/pathfield add feature to browse and select multiple assets (selecting multiple assets using search was not implemented). In the following demo, multifield (with autocomplete) was added in a content fragment model

Demo | Package Install | Github


Select Multiple in Picker



Assets Selected


Solution


1) Login to CRXDE Lite (http://localhost:4502/crx/de), create folder /apps/eaem-multiselect-assets-in-picker

2) Create node /apps/eaem-multiselect-assets-in-picker/clientlib of type cq:ClientLibraryFolder, add String[] property categories with value [granite.ui.coral.foundation, String[] property dependencies with value lodash.

3) Create file (nt:file) /apps/eaem-multiselect-assets-in-picker/clientlib/js.txt, add

                        multiselect-assets.js

4) Create file (nt:file) /apps/eaem-multiselect-assets-in-picker/clientlib/multiselect-assets.js, add the following code

(function($, $document) {
    var MF_SELECTOR = "coral-multifield",
        CORAL_MF_ITEM = "coral-multifield-item",
        EAEM_ITEM_VALUE = "data-eaem-item-value",
        SELECTED_TAGS_DIV = "eaem-column-view-selections",
        FOUNDATION_SELECTIONS_CHANGE = "foundation-selections-change",
        FOUNDATION_SELECTIONS_ITEM = "foundation-selections-item",
        FOUNDATION_COLLECTION = ".foundation-collection",
        FOUNDATION_COLLECTION_ITEM_ID = "foundation-collection-item-id",
        $assetsContainer,
        extended = false;

    $document.on("foundation-contentloaded", handleAssetPicker);

    function handleAssetPicker(){
        if(extended){
            return;
        }

        var $autoCompletes = $("foundation-autocomplete");

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

        extended = true;

        _.each($autoCompletes, function(autoCompete){
            var $autoComplete = $(autoCompete),
                acName = $autoComplete.attr("name"),
                $nearestMF = $autoComplete.closest("coral-multifield[data-granite-coral-multifield-name='" + acName + "']");

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

            $nearestMF.on("coral-collection:add", function(event){
                Coral.commons.ready(event.detail.item, function(mfItem){
                    var $autoComplete = $(mfItem).find("foundation-autocomplete");

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

                    extendPicker($autoComplete[0]);
                });
            });

            extendPicker($autoComplete[0]);
        });
    }

    function extendPicker(pathField){
        var origShowPicker = pathField._showPicker,
            origSetSelections = pathField._setSelections;

        pathField._showPicker = function(){
            origShowPicker.call(this);

            var $dialog = $(this._picker.el),
                $columnView = $dialog.find("coral-columnview");

            addSelectedSection($columnView);

            $dialog.on(FOUNDATION_SELECTIONS_CHANGE, FOUNDATION_COLLECTION, collectAssets);
        };

        pathField._setSelections = function(selections, deferChangeEvent){
            var $autoComplete = $(this),
                acName = $autoComplete.attr("name"),
                $assets = $assetsContainer.find("coral-tag"),
                $nearestMF = $autoComplete.closest("coral-multifield[data-granite-coral-multifield-name='" + acName + "']"),
                mfAddEle = $nearestMF[0].querySelector("[coral-multifield-add]"),
                existingValues = [], thisNotFilled = true;

            _.each($nearestMF[0].items.getAll(), function(item) {
                existingValues.push($(item.content).find("foundation-autocomplete").val());
            });

            _.each($assets, function(asset){
                if(existingValues.includes(asset.value)){
                    return;
                }

                if(thisNotFilled){
                    $autoComplete[0].value = asset.value;
                    thisNotFilled = false;
                    return;
                }

                mfAddEle.click();

                var $lastItem = $nearestMF.find(CORAL_MF_ITEM).last();

                $lastItem.attr(EAEM_ITEM_VALUE, asset.value);

                Coral.commons.ready($lastItem[0], setMultifieldItem);
            });
        };

        function setMultifieldItem(lastItem){
            var $imageReference = $(lastItem).find("foundation-autocomplete"),
                assetPath = $(lastItem).attr(EAEM_ITEM_VALUE);

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

            $imageReference.val(assetPath);
        }
    }

    function collectAssets(){
        var selectedAssets = {};

        $("." + FOUNDATION_SELECTIONS_ITEM).each(function(index, asset){
            var $asset = $(asset),
                assetPath = $asset.data(FOUNDATION_COLLECTION_ITEM_ID);

            if(_.isEmpty(assetPath)){
                return;
            }

            selectedAssets[assetPath] = $asset.find(".foundation-collection-item-title").html();
        });

        var $submit = $(this).closest("coral-dialog").find(".granite-pickerdialog-submit");

        if(_.isEmpty(selectedAssets)){
            $submit.prop("disabled", _.isEmpty(getSelectedAssetsInContainer()));
            return;
        }

        buildSelectedContainer(selectedAssets, $assetsContainer);

        $(this).adaptTo("foundation-selections").clear();

        $submit.prop("disabled", false);
    }

    function buildSelectedContainer(selectedAssets, $container) {
        var $tagList = $container.find("coral-taglist");

        _.each(selectedAssets, function (text, value) {
            $tagList.append(getAssetHtml(text, value));
        });
    }

    function getAssetHtml(title, value){
        return '<coral-tag class="coral3-Tag" value="' + value + '">' +
                    '<coral-tag-label>' + title + '</coral-tag-label>' +
               '</coral-tag>';
    }

    function addSelectedSection($columnView){
        $columnView.css("height", "70%");

        $assetsContainer = $("<div/>").appendTo($columnView.parent());

        var html =  "<div style='text-align:center; padding:1px; background-color: rgba(0,0,0,0.05)'>" +
                        "<h3>Selected Assets</h3>" +
                    "</div>" +
                    "<div style='margin: 15px' id='" + SELECTED_TAGS_DIV + "'>" +
                        "<coral-taglist class='coral3-TagList'></coral-taglist>" +
                    "</div>";

        $(html).appendTo($assetsContainer);

        $assetsContainer.find("coral-taglist").on("change", function(){
            $assetsContainer.closest("coral-dialog").find(".granite-pickerdialog-submit").prop("disabled", _.isEmpty(this.values));
        })
    }

    function getSelectedAssetsInContainer(){
        var $assetList = $assetsContainer.find("coral-taglist");

        if(_.isEmpty($assetList)){
            return [];
        }

        return $assetList[0].values;
    }
})(jQuery, jQuery(document));

No comments:

Post a Comment