1. #1
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default [2.0.1/2.1] Field.destroy() on Fields rendered by FormLayout does not clean up.

    [2.0.1/2.1] Field.destroy() on Fields rendered by FormLayout does not clean up.


    When an Ext.form.Field is rendered by a FormLayout, it adds a label, and wraps it in a <div class='x-form-item'>

    If you then call myFormPanel.remove(myField, true), or myField.destroy(), the Field itself only knows how to remove its own DOM structure, not that added by the FormLayout.

    The FormLayout needs to add handlers to remove its extra elements.

    This becomes important if you have a very dynamic UI and are adding and removing fields as I have to in a specific use case like dynamically building a filter for a server query:



    The following override fixes it:

    Code:
    Ext.override(Ext.layout.FormLayout, {
        renderItem : function(c, position, target){
            if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
                var args = [
                       c.id, c.fieldLabel,
                       c.labelStyle||this.labelStyle||'',
                       this.elementStyle||'',
                       typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
                       (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
                       c.clearCls || 'x-form-clear-left' 
                ];
                if(typeof position == 'number'){
                    position = target.dom.childNodes[position] || null;
                }
                if(position){
                    c.formItem = this.fieldTpl.insertBefore(position, args, true);
                }else{
                    c.formItem = this.fieldTpl.append(target, args, true);
                }
    
    //          Remove the form layout wrapper on Field destroy.
                c.on('destroy', c.formItem.remove, c.formItem, {single: true});
                c.render('x-form-el-'+c.id);
            }else {
                Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
            }
        }
    });

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    87
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    I prefer this override (Ext 2.x):
    Code:
    Ext.override(Ext.layout.FormLayout, {
    	renderItem : function(c, position, target){
    		if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
    			var args = [
    				   c.id, c.fieldLabel,
    				   c.labelStyle||this.labelStyle||'',
    				   this.elementStyle||'',
    				   typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
    				   (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
    				   c.clearCls || 'x-form-clear-left' 
    			];
    			if(typeof position == 'number'){
    				position = target.dom.childNodes[position] || null;
    			}
    			if(position){
    				c.itemCt = this.fieldTpl.insertBefore(position, args, true);
    			}else{
    				c.itemCt = this.fieldTpl.append(target, args, true);
    			}
    			c.actionMode = 'itemCt';
    			c.render('x-form-el-'+c.id);
    			c.container = c.itemCt;
    			c.actionMode = 'container';
    		}else {
    			Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
    		}
    	},
    });
    Ext.override(Ext.form.TriggerField, {
    	actionMode: 'wrap',
    	onShow: Ext.form.TriggerField.superclass.onShow,
    	onHide: Ext.form.TriggerField.superclass.onHide
    });
    Ext.override(Ext.form.Checkbox, {
    	actionMode: 'wrap',
    	getActionEl: Ext.form.Checkbox.superclass.getActionEl
    });
    Ext.override(Ext.form.HtmlEditor, {
    	actionMode: 'wrap'
    });
    This not only makes destroy(), but also show(), hide(), disable() and enable() act on the label too.

    For Ext 3.0.0 you need to change the override slightly:
    Code:
    Ext.override(Ext.layout.FormLayout, {
    	renderItem : function(c, position, target){
    		if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
    			var args = this.getTemplateArgs(c);
    			if(typeof position == 'number'){
    				position = target.dom.childNodes[position] || null;
    			}
    			if(position){
    				c.itemCt = this.fieldTpl.insertBefore(position, args, true);
    			}else{
    				c.itemCt = this.fieldTpl.append(target, args, true);
    			}
    			c.actionMode = 'itemCt';
    			c.render('x-form-el-'+c.id);
    			c.container = c.itemCt;
    			c.actionMode = 'container';
    		}else {
    			Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
    		}
    	}
    });
    Ext.override(Ext.form.Field, {
    	getItemCt : function(){
    		return this.itemCt;
    	}
    });
    For Ext 3.0.1 and up you only need:
    Code:
    Ext.layout.FormLayout.prototype.trackLabels = true;
    Last edited by Condor; 26 Aug 2009 at 10:13 PM. Reason: Fixed in Ext 3.0.1

  3. #3
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    I checked that. The container element is not the .x-form-item, it is the .x-form-element which wraps the input field.

    The .x-form-item, whcih contains the label and the "clear" div is still there when the container is removed.

  4. #4
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Setting the container to the .x-form-item and then actionMode = 'container' makes destroy work.

    I don't know what the other implications are of having the container that "far out" on the actionMode, but this fixes my cleanup problem:

    Code:
    Ext.override(Ext.layout.FormLayout, {
        renderItem : function(c, position, target){
            if(c && !c.rendered && c.isFormField && c.inputType != 'hidden'){
                var args = [
                       c.id, c.fieldLabel,
                       c.labelStyle||this.labelStyle||'',
                       this.elementStyle||'',
                       typeof c.labelSeparator == 'undefined' ? this.labelSeparator : c.labelSeparator,
                       (c.itemCls||this.container.itemCls||'') + (c.hideLabel ? ' x-hide-label' : ''),
                       c.clearCls || 'x-form-clear-left' 
                ];
                if(typeof position == 'number'){
                    position = target.dom.childNodes[position] || null;
                }
                if(position){
                    c.formItem = this.fieldTpl.insertBefore(position, args, true);
                }else{
                    c.formItem = this.fieldTpl.append(target, args, true);
                }
                c.actionMode = 'formItem';
                c.render('x-form-el-'+c.id);
                c.container = c.formItem;
                c.actionMode = 'container';
            }else {
                Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
            }
        }
    });
    
    Ext.override(Ext.form.TriggerField, {
    	actionMode: 'wrap',
    	onShow: Ext.form.TriggerField.superclass.onShow,
    	onHide: Ext.form.TriggerField.superclass.onHide
    });

  5. #5
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    That makes hide and show work fully if you also set hideParent to true.

    Perhaps FormLayout should set hidParent to true so that hide/show acts on the full Field, label included? I know people have posted a bug report that Field.hide does not hide the Field's label.

    What does the Ext core team think?

  6. #6
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    87
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Setting actionMode:'container' already makes ExtJS show and hide the container (getActionEl() == container), so there is no need to set hideParent:true.

    Where you referring to this post?

    ps. Aren't you missing a Ext.get() (see other post) ?

  7. #7
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Yes, but the label is not in the container, the label is in the parent. There are multiple layers of wrapping.

  8. #8
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Ex.get()? The return from Template.append and Template.insertBefore si an Ext.ELement if you pass the last arguments as true.

  9. #9
    Sencha - Ext JS Dev Team Animal's Avatar
    Join Date
    Mar 2007
    Location
    Notts/Redwood City
    Posts
    30,499
    Vote Rating
    46
    Animal has a spectacular aura about Animal has a spectacular aura about

      0  

    Default


    Yikes! That's uncanny that I came up with the exact same code as you!

  10. #10
    Sencha User
    Join Date
    Mar 2007
    Location
    Austria
    Posts
    118
    Vote Rating
    1
    Carina is on a distinguished road

      0  

    Default


    Thanks a lot for this posting this! We were having the very same problem and I kept thinking that we missed something when destroying the form items.

    Will this fix be included in the Ext source? I don't really want to override such a big part of the core code.

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..." hd porno faketaxi