0

I have an extjs form panel. Based on the value selected in the combo box, I need to display a fieldset multiple times. That is,display the field set once if value chosen is 1, twice if value chosen is 2.

The problem that I am facing is that, the field set is being displayed only once. Since, I am changing the title of the fieldset, I can tell more clearly that the fieldset being displayed is the one in the last iteration of the for loop.

However,I can see the log messages in the js console for all the iterations of the for loop which means that the loop is being executed properly.

Here is my code:

 Ext.define('ELM.view.cl.Edit', {
    extend : 'Ext.form.Panel',
    alias : 'widget.cform',
    addMode : false,
    layout : 'fit',
    autoShow : true,
    initComponent : function() {
        this.items = this.buildItems();
        this.callParent(arguments);
    },
    buildItems : function() {
        return [ {
            xtype : 'form',
            id : 'details',
            items : [
                    {
                    xtype : 'fieldset',
                    columnWidth : 0.5,
                    title : 'Details',
                    items : [
                            {
                                    fieldLabel : 'Number Of Scripts Required',
                                    xtype : 'combo',
                                    name : 'noOfScriptsRequired',
                                    id : 'noOfScriptsRequired',
                                    store : new Ext.data.SimpleStore({
                                    fields : [ 'no', 'val' ],
                                    data : [['1','1'],['2','2'],['3','3']]
                                    }),
                                    displayField : 'no',
                                    valueField : 'val',
                                    listeners : {
                                        select : function(combo, value) {
                                            var formpanel = Ext.widget('cform');
                                            var sd = this.up('form').getComponent(
                                                            'scriptdetails');
                                            for ( var i=1; i<=combo.getValue();i++){
                                                console.log(i);
                                                var title="Script details "+i;
                                                sd.setTitle(title);
                                                sd.show();
                                                sd.hidden = false;
                                                console.log(sd);
                                            }
                                        }
                                    }
                                }, ]
                    }, {
                        xtype : 'fieldset',
                        id : 'scriptdetails',
                        columnWidth : '0.5',
                        hidden : true,
                        title : 'Script Details',
                        items : [ {
                            xtype : 'textfield',
                            fieldLabel : 'Script Name',
                            name : 'scriptName'
                        } ]
                    }

            ]
        } ];
    }

});

UPDATE: Here is the working code:

{
    fieldLabel : 'Name :',
    xtype : 'textfield',
    name : 'name'
},{
    fieldLabel : 'Number Of Scripts Required',
    xtype : 'combo',
    name : 'noOfScriptsRequired',
    id : 'noOfScriptsRequired',
    store : new Ext.data.SimpleStore({
        fields : [ 'no', 'val' ],
        data : [ [ '1', '1' ],  [ '2', '2' ],[ '3', '3' ] ]
        }),
    displayField : 'no',
    valueField : 'val',
    listeners : {
        select : function(combo, value) {
            var dynamicPanel = Ext.getCmp("dynamicPanel");
            var scriptField = {
                xtype : 'fieldset',
                items : [
                    {
                    xtype : 'textfield',
                    fieldLabel : 'Script Name',
                    name : 'scriptName'
                    },
                    {
                    xtype : 'textfield',
                    fieldLabel : 'Script Parameters',
                    name : 'scriptParameters'
                    } ]
                    };
            dynamicPanel.removeAll(true);
            for ( var i = 0; i < combo.getValue(); i++) {
                var index = dynamicPanel.items.length;
                var j = i + 1;
                scriptField.title = "Script Details "+ j;
                dynamicPanel.insert(index,scriptField);
                dynamicPanel.doLayout();
            }
        }
        }

Thanks in advance

user777777
  • 228
  • 4
  • 25

2 Answers2

1

You are using id:'scriptdetails' in fieldset. In web pages each component or element should have an unique id. If there are elements with same id then there will be problems in rendering the elements like single element is rendered with errors or element may not be rendered.

In your case as you have to repeat the field set, don't not use fixed id. Use a random generated id from server or use 'itemId' which ExtJS provides.

Refer: here and here

Update: Working fiddle is here

Ext.onReady(function() {

    var store = new Ext.data.ArrayStore({
        id: 0,
        fields: [
            'myId',
            'displayText'
        ],
        data: [
            [1, '1'],
            [2, '2'],
            [3, '3'],
        ]
    });

    var scriptField = {
        xtype: 'fieldset',
        columnWidth: '0.5',
        title: 'Script Details',
        items: [{
            xtype: 'textfield',
            fieldLabel: 'Script Name',
            hiddenName: 'scriptName'
        }]
    };

    var container = new Ext.Panel({
        layout: 'hbox',
        height: '700px',
        items: [{
            xtype: 'panel',
            id: 'parentContainer',
            height: '700px',
            layout: 'form',
            items: [{
                xtype: 'combo',
                editable: false,
                triggerAction: 'all',
                mode: 'local',
                store: store,
                valueField: 'myId',
                displayField: 'displayText',
                fieldLabel: 'Show Number of Items',
                listeners: {
                    select: function(combo, value) {
                        var dynamicPanel = Ext.getCmp("dynamicPanel");
                        dynamicPanel.removeAll(true);
                        for (var i = 0; i < combo.getValue(); i++) {
                            scriptField.title = "Script Details " + i;
                            dynamicPanel.add(scriptField);
                            dynamicPanel.doLayout();
                            dynamicPanel.ownerCt.doLayout();
                            dynamicPanel.ownerCt.ownerCt.doLayout();
                        }
                    }
                }
            }, {
                xtype: 'panel',
                id: 'dynamicPanel',
                items: []
            }]
        }]
    });

    container.render(Ext.getBody());

});
Community
  • 1
  • 1
AJJ
  • 3,570
  • 7
  • 43
  • 76
  • Changing id to itemId does not help..I have tried it. And I am not sure how to use a random id from server..Could you please tell more about how that can be done? – user777777 Oct 14 '14 at 12:46
  • @user3604227 I misses something in my answer. You are justing calling the show() of fieldset within the iteration. Ideally this will not add multiple fieldset to the form. You have to add the fieldset to the form. – AJJ Oct 15 '14 at 05:14
  • @user3604227 updated my answer which will help you as per your requirement – AJJ Oct 15 '14 at 06:57
  • Thank u..!!that is working... But could you please tell me how am I supposed to update the fieldset title? – user777777 Oct 16 '14 at 11:15
  • 1
    @user3604227 just do scriptField.title = "Script Details " + i; inside the for loop. I have updated the fiddle and answer. – AJJ Oct 16 '14 at 11:32
  • I have a question...what does dynamicPanel.ownerCt refer to? Is it the parent of dynamicPanel and so on,tracked till the root container? – user777777 Oct 16 '14 at 11:50
  • 1
    @user3604227 yes dyanmicPanel.ownerCt refers to the immediate parent of the dynamic Panel alone. It does not refer to the root container. – AJJ Oct 17 '14 at 06:06
  • How to access the comboBox item within the panel when there is no id/itemId assigned to it? – user777777 Nov 18 '14 at 16:52
  • @Shruthi If you want to get the comboBox item inside the conboBox listener, then it is pretty easy as you will have comboBox DOM inside its listener (Refer the answer above for comboBox DOM in the listener). If you want to get the comboBox item outside the comboBox listener and within the panel, you can use componentquery to get parent panel and get the childs (comboBox) from it. http://docs.sencha.com/extjs/4.0.7/#!/api/Ext.ComponentQuery – AJJ Nov 19 '14 at 06:14
1

Your buildItems code is executed once, at the beginning. Afterwards, you never really add any more items. Which you would want to do using this function: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.container.AbstractContainer-method-add

If you want to add an item, you have to create a new one. You can't add the same item into a container twice. So you would have to create them on the fly: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext-method-create

And for this, you should use some defined "blueprint", where you define that it is a fieldset, contains a textfield, and so on: http://docs.sencha.com/extjs/4.2.2/#!/api/Ext-method-define

A blueprint of an item should never contain an id. I would refer to all the items by using form.items[i], and omit the id entirely.

You still have one problem, though: Your items all contain a textfield by the same name. This won't work well with submit(). But that's another story entirely.

Alexander
  • 19,906
  • 19
  • 75
  • 162