Expand my Community achievements bar.

SOLVED

How to create a custom pathfield which allow user to drag & drop digital asset from content finder?

Avatar

Level 2

I am currently having trouble to build a multiple composite fields.  This field include a textfield and a pathfield.  For the pathfield, I am trying to customize the xtype so that user can drag & drop the digital asset from content finder, exactly like the pathfield in rte editor when user try to create an hyperlink.

Can someone please give me some advice.  Below is my current code implemented:

Ejst.CustomWidget = CQ.Ext.extend(CQ.form.CompositeField, {

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    hiddenField: null,

    /**
     * @private
     * @type CQ.Ext.form.ComboBox
     */
    allowField: null,

    /**
     * @private
     * @type CQ.Ext.form.TextField
     */
    otherField: null,
    richtext: null,
    pathfield: null,
    
    constructor: function(config) {
        config = config || { };
        var defaults = {
                /*
            "border": false,
            "layout": "table",
            "columns":2
            */
                "title" : "Banner",
                "border": true,
                "labelWidth": 75,
                "layout": "form"
        };
        config = CQ.Util.applyDefaults(config, defaults);
        Ejst.CustomWidget.superclass.constructor.call(this, config);
    },

    // overriding CQ.Ext.Component#initComponent
    initComponent: function() {
        Ejst.CustomWidget.superclass.initComponent.call(this);

        this.hiddenField = new CQ.Ext.form.Hidden({
            name: this.name
        });
        this.add(this.hiddenField);
        
        this.allowField = new CQ.Ext.form.TextField({
            cls:"ejst-customwidget-1",
            fieldLabel: "Title",
            listeners: {
                change:  {
                    scope:this,
                    fn:this.updateHidden
                    
                },
                blur: function() {
                    //scope:this,
                    //fn:this.updateHidden
                    alert("textfield outfocus");
                    
                }
            }
        });
        this.add(this.allowField);
        
        //this.richtext = new CQ.form.RichText({
        //this.richtext = new CQ.Ext.form.HtmlEditor({
        this.richtext = new CQ.Ext.form.TextArea({
            cls:"ejst-customwidget-2",
            fieldLabel: "Description",
            width: 600,
            listeners: {
                
                change: {
                    scope:this,
                    fn:this.updateHidden
                    
                }
            }//,
            
            //destroy: function() {this.el.dom={}; }
        });
        this.add(this.richtext);
        
       
        
        this.pathField = new CQ.form.PathField({
        
            cls:"ejst-customwidget-3",
            fieldLabel: "Banner Path",
            "parBrowse": true,
            "anchor": CQ.themes.Dialog.ANCHOR,
            width: 600,
            "ddGroups": [
                 CQ.wcm.EditBase.DD_GROUP_PAGE,
                 CQ.wcm.EditBase.DD_GROUP_ASSET
             ],
             "fieldDescription": CQ.I18n.getMessage("Drop files or pages from the Content Finder"),
             "listeners": {
                 "dialogselect": {
                     "fn": this.selectAnchor,
                     "scope": this
                 },
                 //"change": {
                 //    scope:this,
                 //    fn:this.updateHidden
                 //},
                 "render": this.initHrefDragAndDrop
             },
             "validator": this.validateLink.createDelegate(this),
             "validationEvent": "keyup",
             "escapeAmp": true
        });
        this.add(this.pathField);

    },
    
    /**
     * @private
     */
    selectAnchor: function(pathfield, path, anchor) {
        // custom path + anchor handling
        path = CQ.HTTP.encodePath(path);
        // encodePath will not encode '&', so we're doing it here, as other callees of
        // encodePath might rely on that documented behaviour - see bug #30206
        path = path.replace(/&/g, "%26");
        if (anchor && (anchor.length > 0)) {
            path += ".html#" + anchor;
        }
        pathfield.setValue(path);
    },
    
    /**
     * <p>Note that this method is executed in the scope of the pathfield.</p>
     * @private
     */
    initHrefDragAndDrop: function() {

        this.ddGroups = [
                         CQ.wcm.EditBase.DD_GROUP_PAGE,
                         CQ.wcm.EditBase.DD_GROUP_ASSET
                     ];
        
        if (this.ddGroups) {
            alert("1: " + this.ddGroups);
            if (typeof(this.ddGroups) == "string") {
                this.ddGroups = [ this.ddGroups ];
            }
            var field = this;
            
            var target = new CQ.wcm.EditBase.DropTarget(this.el, {
                "notifyDrop": function(dragObject, evt, data) {
                    
                    if (dragObject && dragObject.clearAnimations) {
                        dragObject.clearAnimations(this);
                    }
                    if (dragObject.isDropAllowed(this)) {
                        if (data.records && data.single) {
                            var record = data.records[0];
                            var path = record.get("path");
                            path = CQ.HTTP.encodePath(path);
                            // again, '&' needs to be encoded explicitly - see bug #30206
                            path = path.replace(/&/g, "%26");
                            field.setValue(path);
                            evt.stopEvent();
                            return true;
                        }
                        return false;
                    }
                }
            });

            //var dialog = this.findParentByType(CQ.form.rte.plugins.LinkDialog);
            var dialog = this.findParentByType(CQ.Dialog);

            dialog.on("activate", function(dialog) {
                alert(dialog + " " + dialog.el + " " + this.highlight);
                if (dialog && dialog.el && this.highlight) {
                    var dialogZIndex = parseInt(dialog.el.getStyle("z-index"), 10);
                    if (!isNaN(dialogZIndex)) {
                        this.highlight.zIndex = dialogZIndex + 1;
                    }
                }
            }, target);
            dialog.on("deactivate", function(dialog) {
                if (dialog && dialog.el && this.highlight) {
                    var dialogZIndex = parseInt(dialog.el.getStyle("z-index"), 10);
                    if (!isNaN(dialogZIndex)) {
                        this.highlight.zIndex = dialogZIndex + 1;
                    }
                }
            }, target);
            var editorKernel = dialog.getParameter("editorKernel");
            dialog.on("show", function() {
                editorKernel.fireUIEvent("preventdrop");
                CQ.WCM.registerDropTargetComponent(field);
            }, target);
            dialog.on("hide", function() {
                CQ.WCM.unregisterDropTargetComponent(field);
                editorKernel.fireUIEvent("reactivatedrop");
            }, target);

            for (var i = 0; i < this.ddGroups.length; i++) {
                target.addToGroup(this.ddGroups[i]);
            }
            target.removeFromGroup(CQ.wcm.EditBase.DD_GROUP_DEFAULT);
            this.dropTargets = [ target ];
        }
    },

    // overriding CQ.form.CompositeField#processPath
    processPath: function(path) {
        console.log("CustomWidget#processPath", path);
        this.allowField.processPath(path);
        //this.richtext.processPath(path);
        //this.pathField.processPath(path);
    },

    // overriding CQ.form.CompositeField#processRecord
    processRecord: function(record, path) {
        console.log("CustomWidget#processRecord", path, record);
        this.allowField.processRecord(record, path);
        //this.richtext.processRecord(record, path);
        //this.pathField.processRecord(record, path);
        //this.otherField.processRecord(record, path);
    },

    // overriding CQ.form.CompositeField#setValue
    setValue: function(value) {
        var parts = value.split("#===#");
        this.allowField.setValue(parts[0] );
        this.richtext.setValue(parts[1]);
        //this.pathField2.setValue(parts[1]);
        this.pathField.setValue(parts[2]);
        this.hiddenField.setValue(value);
    },

    // overriding CQ.form.CompositeField#getValue
    getValue: function() {
        return this.getRawValue();
    },

    // overriding CQ.form.CompositeField#getRawValue
    getRawValue: function() {
        if (!this.allowField) {
            return null;
        }
        
        return this.allowField.getValue() + "#===#" +
               this.richtext.getValue() + "#===#" +
               this.pathField.getValue();
    },

    // private
    updateHidden: function() {
        this.hiddenField.setValue(this.getValue());
    },
    validateLink: function() {
        var href = this.getFieldByName("href");
        if (!href) {
            return false;
        }
        href = href.getValue();
        var linkRules = this.getParameter("linkRules");
        if (!linkRules) {
            return (href.length > 0);
        }
        return linkRules.validateHref(href);
    }

});

// register xtype
CQ.Ext.reg('ejstcustom', Ejst.CustomWidget);

1 Accepted Solution

Avatar

Correct answer by
Employee
1 Reply

Avatar

Correct answer by
Employee

Such a widget is availalbe as part of ACS AEM Commons. See http://adobe-consulting-services.github.io/acs-aem-commons/features/widgets.html