1. #1
    Ext JS Premium Member
    Join Date
    Apr 2010
    Location
    Omaha, NE
    Posts
    588
    Vote Rating
    30
    estesbubba has a spectacular aura about estesbubba has a spectacular aura about

      0  

    Default Help converting custom Form.Field from 1.1 to 2.0

    So we have a custom form field that is read-only and optionally displays an icon which shows the full text when clicked (known internally as the "lawyer widget"). In 1.1 we used renderTpl, initRenderData, and applyRenderSelectors and I'm struggling how exactly to convert this to 2.0. Looking at 2.0 source code it appears I might need to use ui: or might need to use getElementConfig() but I don't know how these work.

    Here is the 1.1 code. Any direction or examples would be appreciated. Seems like it should be simple but I'm struggling.

    Code:
    Ext.namespace('Csg.view');
    
    
    Csg.view.DisplayField = Ext.extend(Ext.form.Field, {
    
    
        iconCls: 'search',
        cls: 'c-display-field',
        displayTextCls: 'c-display-text',
        wrapCls: 'c-wrap',
        showIcon: true,
        wrapText: false,
        
        renderTpl: [
            '<tpl if="label">',
                '<div class="x-form-label"><span>{label}</span></div>',
            '</tpl>',
            '<tpl if="fieldEl">',
                '<div class="x-form-field-container"><div class="{fieldContainerCls}">{displayText}</div></div>',
    
    
                '<tpl if="showIcon">',
                    '<div class="x-button x-button-plain">',
                        '<img src="{blankSrc}" class="{iconCls} x-icon-mask">',
                    '</div>',
                '</tpl>',
            '</tpl>'
        ],
    
    
        initComponent: function() {
            
            var config = {};
            
             Ext.apply(this, Ext.apply(this.initialConfig, config));
            Csg.view.DisplayField.superclass.initComponent.call(this, arguments);
            
        },
    
    
        initRenderData: function() {
            Csg.view.DisplayField.superclass.initRenderData.apply(this, arguments);
            
            Ext.applyIf(this.renderData, {
                displayText: this.displayText,
                iconCls: this.iconCls,
                fieldContainerCls: this.displayTextCls + (this.wrapText ? ' ' + this.wrapCls : ''),
                blankSrc: Ext.BLANK_IMAGE_URL,
                showIcon: this.showIcon
            });
            
            return this.renderData;
        },
        
        afterRender: function() {
            
            Csg.view.DisplayField.superclass.afterRender.apply(this, arguments);
        },
        
        applyRenderSelectors: function() {
            this.renderSelectors = Ext.applyIf(this.renderSelectors || {}, {
                iconEl: '.x-button',
                fieldContainerEl: '.x-form-field-container'
            });
            
            Csg.view.DisplayField.superclass.applyRenderSelectors.call(this);
        },
        
        initEvents: function() {
            Csg.view.DisplayField.superclass.initEvents.call(this);
    
    
            if (this.iconEl) {
                this.mon(this.iconEl, {
                    scope: this,
                    tap: this.onMoreTap
                });
                this.mon(this.fieldContainerEl, {
                    scope: this,
                    tap: this.onMoreTap
                });
            }
        },
        
        onMoreTap: function() {
            if (!this.popup) {
                this.popup = new Ext.Panel({
                    floating: true,
                    modal: true,
                    centered: Ext.is.Phone ? true : false,
                    width: Ext.is.Phone ? 260 : 400,
                    height: Ext.is.Phone ? 320 : 400,
                    styleHtmlContent: true,
                    scroll: 'vertical',
                    html: this.displayText
                })
            }
            
            if (Ext.is.Phone) {
                this.popup.show('fade');
            }
            else {
                this.popup.showBy(this.iconEl, 'fade', false);
            }
        }
        
    });
    
    
    Ext.reg('displayField', Csg.view.DisplayField);

  2. #2
    Sencha - Sr Software Engineer mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    38,582
    Vote Rating
    1136
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default

    getElementConfig is a Dom helper structure to create the structure of elements you want to use.

    This is what Container's looks like:

    Code:
        getElementConfig: function() {
            return {
                reference: 'element',
                className: 'x-container',
                children: [{
                    reference: 'innerElement',
                    className: 'x-inner'
                }]
            };
        },
    And then Panel extends it but adds:

    Code:
        getElementConfig: function() {
            var config = this.callParent();
    
            config.children.push({
                reference: 'tipElement',
                className: 'x-anchor',
                hidden: true
            });
    
            return config;
        },
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Software Engineer
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Ext JS Premium Member
    Join Date
    Apr 2010
    Location
    Omaha, NE
    Posts
    588
    Vote Rating
    30
    estesbubba has a spectacular aura about estesbubba has a spectacular aura about

      0  

    Default

    I still can't figure out the new way to doing what I used renderTpl, initRenderData, and applyRenderSelectors for in Touch 1.1. Should I be able to do all that in the getElementConfig() function? Looking at Form.Field it has:

    Code:
        getElementConfig: function() {
            var prefix = Ext.baseCSSPrefix;
    
    
            return {
                reference: 'element',
                className: 'x-container',
                children: [
                    {
                        reference: 'label',
                        cls: prefix + 'form-label',
                        children: [{
                            reference: 'labelspan',
                            tag: 'span'
                        }]
                    },
                    {
                        reference: 'innerElement',
                        cls: prefix + 'component-outer'
                    }
                ]
            };
        }
    How does the content get placed into innerElement? My component is a text field with an optional icon placed on the end. That's where the renderTpl was used in 1.1.

  4. #4
    Ext JS Premium Member
    Join Date
    Apr 2010
    Location
    Omaha, NE
    Posts
    588
    Vote Rating
    30
    estesbubba has a spectacular aura about estesbubba has a spectacular aura about

      0  

    Default

    Here is what I came up with. Definitely a first cut as we use this all over the place and need to test it.

    Code:
    Ext.define('Csg.view.DisplayField', {
        
        extend: 'Ext.field.Field',
        xtype: 'displayField',
        
        config: {
            iconCls: 'search',
            cls: 'c-display-field',
            displayText: null,
            displayTextCls: 'c-display-text',
            wrapCls: 'c-wrap',
            showIcon: true,
            wrapText: false,
            component: {
                xtype: 'displayFieldComponent'
            }
        },
        
    
    
        initialize: function() {
            var me = this,
                comp = me.getComponent();
            
            me.callParent();
            
            if (this.getShowIcon()) {
                comp.iconElement.on({
                    scope: this,
                    tap: this.onMoreTap
                });
                comp.displayElement.on({
                    scope: this,
                    tap: this.onMoreTap
                });
            }
            
        },
        
        updateDisplayText: function(value) {
            var me = this,
                comp = me.getComponent();
                
            comp.displayElement.setHtml(value);
        },
        
        updateDisplayTextCls: function(newCls, oldCls) {
            var me = this,
                comp = me.getComponent();
            
            comp.displayElement.replaceCls(oldCls, newCls);
        },
        
        updateWrapText: function(value) {
            var me = this,
                comp = me.getComponent();
            
            if (value) {
                comp.displayElement.addCls(me.getWrapCls());
            }
            else {
                comp.displayElement.removeCls(me.getWrapCls());
            }
        },
        
        updateIconCls: function(newCls, oldCls) {
            var me = this,
                comp = me.getComponent();
            
            comp.imgElement.addCls('x-button-icon');
            comp.imgElement.replaceCls(oldCls, newCls);
            comp.imgElement.addCls('x-icon-mask');
        },
        
        updateShowIcon: function(value) {
            var me = this,
                comp = me.getComponent();
            
            comp.iconElement.setStyle('display', value ? 'block' : 'none');
        },
        
        onMoreTap: function() {
            if (!this.popup) {
                this.popup = new Ext.Panel({
                    floating: true,
                    modal: true,
                    hideOnMaskTap: true,
                    centered: Ext.os.is.Phone ? true : false,
                    width: Ext.os.is.Phone ? 260 : 400,
                    height: Ext.os.is.Phone ? 320 : 400,
                    styleHtmlContent: true,
                    scrollable: 'vertical',
                    showAnimation: 'fadeIn',
                    hideAnimation: 'fadeOut',
                    html: this.getDisplayText()
                })
            }
            
            if (Ext.is.Phone) {
                this.popup.show();
            }
            else {
                this.popup.showBy(this.getComponent().iconElement);
            }
        }
        
    });
    
    
    Ext.define('Csg.view.DisplayFieldComponent', {
        
        extend: 'Ext.Component',
        xtype: 'displayFieldComponent',
        
        config: {
            cls: 'x-field-input'
        },
        
        getTemplate: function() {
            return [{
                reference: 'displayElement',
                cls: 'c-display-text',
                tag: 'div'
            }, {
                reference: 'iconElement',
                cls: 'x-button x-button-plain',
                children: [{
                    reference: 'imgElement',
                    tag: 'div'
                }]
            }]
        }
        
    });

Thread Participants: 1