5
votes

I have a form where i have a radiogroup 'yes', 'no'.

When i click on 'yes' i got a textfield added to a fieldset on the form with the config option: allowBlank: false. So there is validation on the field. When I click on 'no' all fields are removed from the fieldset that is present on the form.

The problem is when the validation is active, so when you go inside the textfield and you click away from it without entering any characters into it and i click on the radiobutton 'no' the textfield disappears and gives me the following error when i catch it:

Element.alignToXY with an element that doesn't exist

When i click afterwards on the radiobutton 'yes', the textfield is shown again BUT i get an error:

TypeError: dom is undefined

I could catch these errors and do nothing with it because in fact the form seems to be working, the textfields got added and removed like it should, there are only errors present and i don't like the concept of it. Does anyone has a clue why this error occurs and how to get rid of it so it's working 100% properly?

Here is an example of the code:

var radiogroup = new Ext.form.RadioGroup({
    fieldLabel: 'Radio group test',
    allowBlank: false,
    anchor: '85%',
    items: [{
        boxLabel: 'Yes',
        name: 'radio',
        inputValue: 1
    }, {
        boxLabel: 'No',
        name: 'radio',
        inputValue: 2
    }],
    listeners: {
        change: function (rg, radio) {

            if (radio.inputValue == 1) {
                var textfield_test = new Ext.form.TextField({
                    fieldLabel: 'Test',
                    allowBlank: false,
                    id: 'test',
                    name: 'test',
                    anchor: '85%',
                    width: 320,
                    helpText: 'test'
                });
                textfield_fieldset.insert(textfield_fieldset.items.length, textfield_test);
            } else {
                try {
                    txt_test = Ext.getCmp('test');
                    if (txt_test) {
                        textfield_fieldset.remove(txt_test);
                    }
                    textfield_fieldset.doLayout();
                } catch (err) {
                    alert(err);
                }
            }
        }
    }
});
3
It might be more useful to put a more complete example together on jsfiddle.net and link to it.TML
It is an example. Just removing a textfield from a fieldset and adding to a fieldset on a formpanel... The radiogroup is inside the same textfield_fieldset... What do you need more?Hein
I am also running into this issue. I am needing to dynamically create a FormPanel from scratch upon an AJAX response, in accordance to the data returned. Sadly, this error is completely ruining an otherwise interesting endeavor.Aaron Ransley
Please check my answer below. I've encountered similar issue a few times and that is more or less how I workaround it.jaycode

3 Answers

5
votes

I've done this successfully not just for one textbox, but for an entire panel, and it works pretty well. In my case, any number of panel can be added and removed dynamically and it works pretty well. The relevant code that I used were:

panel.insert(medIndex,getNewPanel());
panel.doLayout();

And for remove i used,

var cmp = Ext.getCmp('Panel-' + Id);
   if (cmp) {
     treatment.remove(cmp, true); // True is the autoDestroy option.
   }

These two in combination works for me. Though I would suggest that if you're doing this only for one textbox, then convert it into a hidden field and disable it. When you disable a field, it does not get submitted in a post, or ajax post request.

Hope this helps.

2
votes

first, why did you re-add/re-remove a component like that?,..
if i was you... i will use the hide / show method of textfield class..

after read your code, i assuming that you are make a formPanel with 2 items (radiogroup and fieldset) where in the fieldset, there is a textfield... so, guestly.. mybe like this ??

var radiogroup = new Ext.form.RadioGroup({
    fieldLabel: 'Radio group test',
    allowBlank: false,
    anchor: '85%',
    items: [
        {
        boxLabel: 'Yes',
        name: 'radio',
        inputValue: 1},
    {
        boxLabel: 'No',
        name: 'radio',
        inputValue: 2}
    ],
    listeners: {
        change : function(a,b){
            if (b.inputValue==1){
                Ext.getCmp("textfield").enable();
                Ext.getCmp("textfield").show();
            }else{
                Ext.getCmp("textfield").disable(); // set disable to prevent send empty data
                Ext.getCmp("textfield").hide();
            }                
        }
    }
});

var formPanel = new Ext.form.FormPanel({
    url : 'www.google.com',
    method : "GET",
    layout:'column',
    frame :true,
    border : false,
    items : [
                radiogroup,
                {
                xtype:'fieldset',
                id : 'test',
                title: 'Fieldset',
                collapsible: true,
                height : 200,
                width : 350,
                items :[{
                        xtype : "textfield",
                        id : 'textfield',
                        fieldLabel : "input data",
                        name : "text",
                        hidden:true,
                        disabled:true
                       }]
                }
            ]
});

var win = new Ext.Window({
    title : "holla",
    width : 400,
    height: 300,
    border : false,
    layout:'fit',
    items  : [formPanel]
});
win.show();
1
votes

I created a jsfiddle to answer this question. The textfield seemed to get added / removed properly there: http://jsfiddle.net/jaycode/PGSb7/4/

Cheers.

Edit: For completeness, I guess I'll just post the code here as well


HTML

<div id="radios"></div>
<div id="textfield_fieldset"></div>

JS

var textfield_fieldset = new Ext.form.FieldSet({
    renderTo: 'textfield_fieldset',
});

var radiogroup = new Ext.form.RadioGroup({
    renderTo: 'radios',
    width: 200,
    height: 60,
    fieldLabel: 'Radio group test',
    allowBlank: false,
    layout: {
        type: 'vbox'
    },
    items: [
        {
            boxLabel: 'Yes',
            name: 'radio',
            inputValue: 1
        },
        {
            boxLabel: 'No',
            name: 'radio',
            inputValue: 2
        }
    ],
    listeners: {
        change: function(rg, radio) {
            if (rg.lastValue.radio == 1) {
                var textfield_test = new Ext.form.TextField({
                    fieldLabel: 'Test',
                    allowBlank: false,
                    id: 'test',
                    name: 'test',
                    anchor: '85%',
                    width: 320,
                    helpText: 'test'
                });
                textfield_fieldset.insert(textfield_fieldset.items.length, textfield_test);
            } else {
                    txt_test = Ext.getCmp('test');
                    if (txt_test) {
                        textfield_fieldset.remove(txt_test);
                    }
                    textfield_fieldset.doLayout();

            }
        }
    }
});