Search code examples
extjsdrag-and-dropextjs3

How to build draggable field sets in ExtJS 3.x


I'd like to build an ExtJS FormPanel that allows the user to reorder a list of field sets using drag and drop.

I see it's very easy to make the field sets moveable by using draggable: true, but how do I set up the dropzone? I've tried to follow a number of examples, but not had much luck.

MyApp.FormPanel = Ext.extend(Ext.FormPanel,{
    title: 'Fields',

    fieldSetCount: 0,

    constructor: function(config){
        Ext.apply(this, config);

        this.tbar = [{
            text: 'Add Field Set',
            handler: this.addFieldSet,
            scope: this
        }];

        MyApp.FormPanel.superclass.constructor.call(this, config);
    },

    addFieldSet: function(){
        this.add({
            xtype: 'fieldset',
            title: 'Fieldset ' + this.fieldSetCount++,
            draggable: true
        });
        this.doLayout();
    },
});

Solution

  • You need to implement Ext.dd.DropZone to archive this! See the Ext.JS 3.x API for more details on this

    The following example is untested, but it should show you the trick!

    FormDropZone = function (form, config) {
        this.form = form;
        FormDropZone.superclass.constructor.call(this, form.view.scroller.dom, config);
    };
    
    
    Ext.extend(FormDropZone, Ext.dd.DropZone, {
        onContainerOver: function (dd, e, data) {
            return dd.form !== this.form ? this.dropAllowed : this.dropNotAllowed;
        },
        onContainerDrop: function (dd, e, data) {
            if (dd.form !== this.form) {
                this.form.onFormDrop(this.form, data.selections, dd.form);
                return true;
            }
            else {
                return false;
            }
        },
        containerScroll: true
    });
    
    
    DDform = Ext.extend(Ext.form.formPanel, {
        // configuration
        initComponent: function () {
            var config = {};
            Ext.apply(this, Ext.apply(this.initialConfig, config));
            DDform.superclass.initComponent.apply(this, arguments);
        },
        onRender: function () {
            DDform.superclass.onRender.apply(this, arguments);
            this.dz = new FormDropZone(this, { ddGroup: this.ddGroup || 'formDD' });
        },  
        onFormDrop: Ext.emptyFn
    });
    

    Hope this helps you!