gabi
gabi

Reputation: 1376

ExtJS4: clone Fieldset in a form

I have a form with anchor layout which contains a fieldset with combobox items. In the when I click a buttom, a new Fieldset will be created with cloneConfig() method and it will be inserted into bottom of the form.

Now I have two problems: First, when I add a new Fieldset, it will be placed under my forms toolbar buttons while it should be inserted above that.

Secondly, how can I insert a new Fieldset in between two Feildsets (in the pic child tag3 should be inserted between child1 and child2).

How can I add order to my form items?

jsfiddle

It looks like this now enter image description here

Here is my form code :

Ext.define('APP.MyForm', {
    extend: 'Ext.form.Panel',
    xtype: 'tform',
    requires: ['Ext.form.FieldSet', 'Ext.form.field.Text', 'Ext.toolbar.Toolbar'],
    layout: {
        type: 'anchor'
    },
    bodyPadding: 10,
    store: 'Tag',
    border: false,
    autoScroll: true,
    initComponent: function() {
        var me = this;
        Ext.applyIf(me, {
            items: [{
                    xtype: 'fieldset',
                    hidden: false,
                    padding: 10,
                    fieldDefaults: {
                        anchor: '100%'
                    },
                    title: 'Definition Type Entry',
                    items: [{
                            xtype: 'textfield',
                            name: 'tagName',
                         },
                        {
                            xtype: 'textareafield',
                            height: 40,
                            name: 'description',
                        }, {
                            xtype: 'combobox',
                            name: 'basetype',
                        }, {
                            xtype: 'combobox',
                            name: 'dt',
                        }, {
                            xtype: 'numberfield',
                        }, {
                            xtype: 'button',
                            iconCls: 'addnew',
                            itemId: 'addChildBtn',
                            disabled: false,
                             }]
                }, {
                    xtype:'container',
                    region:'south',
                    items:[         
                {
                    xtype: 'toolbar',
                    ui: 'footer',
                    layout: {
                        pack: 'end',
                        type: 'hbox'
                    },
                    items: [{
                            xtype: 'button',
                            iconCls: 'delete',
                            itemId: 'deleteBtn',
                            disabled: true,
                            text: 'Delete',
                            tooltip: 'delete the selected definition type'
                        }, {
                            xtype: 'button',
                            iconCls: 'save',
                            itemId: 'saveBtn',
                            text: 'Save'
                        }]}]},]});
        me.callParent(arguments);
    }
});

Upvotes: 1

Views: 1293

Answers (1)

Rob Schmuecker
Rob Schmuecker

Reputation: 8954

To clone and prevent the insert method not thinking it's already a component within the form, you will need to give it a unique itemId each time. Otherwise the insert method moves the element rather than adds it : Here is a snippet of the ExtJS source responsible

insert : function(index, comp) {
    var compIdx;
    if (comp && comp.isComponent) {
        compIdx = this.items.indexOf(comp);
        if (compIdx !== -1) {
            return this.move(compIdx, index);
        }
    }
    return this.add(index, comp);
}

So by making sure we increment the itemId we are able to successfully add/insert the new component wherever you like. Change the index of the insert method to suit your needs.

Code:

Ext.application({
    name: 'Fiddle',

    launch: function() {
        myForm = Ext.create('Ext.form.Panel', {
            title: 'Simple Form',
            layout: 'auto',
            bodyPadding: 5,
            items: [{
                xtype: 'fieldset',
                itemId: 's1',
                hidden: false,
                padding: 10,
                fieldDefaults: {
                    anchor: '100%'
                },
                title: 'Entry',
                items: [{
                    xtype: 'textfield',
                    name: 'tagName',
                    fieldLabel: 'Name'
                }, , {
                    xtype: 'button',
                    itemId: 'addChildBtn',
                    disabled: false,
                    text: 'Clone fieldset',
                    handler: function() {
                        // Count the fieldsets
                        countedFieldsets = Ext.ComponentQuery.query('fieldset').length;
                        // Clone field set 
                        var newFieldset = Ext.ComponentQuery.query('fieldset')[0].cloneConfig({
                            itemId: 's' + (countedFieldsets + 1),
                            title: "Entry " + countedFieldsets,
                        });
                        myForm.insert(countedFieldsets, newFieldset);
                    }
                }]
            }, ],
            dockedItems: [{
                xtype: 'toolbar',
                ui: 'footer',
                dock: 'bottom',
                layout: {
                    pack: 'end',
                    type: 'hbox'
                },
                items: [{
                    xtype: 'button',
                    itemId: 'saveBtn',
                    text: 'Save'

                }]
            }],
            renderTo: Ext.getBody()
        });

    }
});

Demo: https://fiddle.sencha.com/#fiddle/gb1

As for the toolbar and inserting at arbitrary positions you can specify the toolbar as a dockedItem (as above) and give it appropriate properties. Or you could always insert before the toolbar (or at any other arbitrary index position) e.g. in this demo: https://fiddle.sencha.com/#fiddle/gb2

Code for demo:

Ext.application({
    name: 'Fiddle',

    launch: function() {
        myForm = Ext.create('Ext.form.Panel', {
            title: 'Simple Form',
            layout: 'auto',
            bodyPadding: 5,
            items: [{
                xtype: 'fieldset',
                itemId: 's1',
                hidden: false,
                padding: 10,
                fieldDefaults: {
                    anchor: '100%'
                },
                title: 'Entry',
                items: [{
                    xtype: 'textfield',
                    name: 'tagName',
                    fieldLabel: 'Name'
                }, , {
                    xtype: 'button',
                    itemId: 'addChildBtn',
                    disabled: false,
                    text: 'Clone fieldset',
                    handler: function() {
                        // Count the fieldsets
                        countedFieldsets = Ext.ComponentQuery.query('fieldset').length;
                        // Clone field set 
                        var newFieldset = Ext.ComponentQuery.query('fieldset')[0].cloneConfig({
                            itemId: 's' + (countedFieldsets + 1),
                            title: "Entry " + countedFieldsets,
                        });

                        // here we will count the items of the form
                        var formItemsCount = myForm.items.length;
                        // now insert it at the total lenght -1
                        myForm.insert(formItemsCount - 1, newFieldset);
                    }
                }]
            }, {
                xtype: 'toolbar',
                ui: 'footer',
                layout: {
                    pack: 'end',
                    type: 'hbox'
                },
                items: [{
                    xtype: 'button',
                    itemId: 'saveBtn',
                    text: 'Save'

                }]
            }],
            renderTo: Ext.getBody()
        });

    }
});

Upvotes: 1

Related Questions