1. #1
    Sencha User
    Join Date
    Nov 2007
    Posts
    243
    Vote Rating
    0
    JamesC is on a distinguished road

      0  

    Default [3.1] Ext.ux.layout.TableFormLayout - table layout with form field labels

    [3.1] Ext.ux.layout.TableFormLayout - table layout with form field labels


    Code below, use layout: "tableform" and the items then support standard anchor configuration as well as being layed out in a table.

    Example usage:
    PHP Code:
    layout"tableform",
    layoutConfig: {
         
    columns2,
         
    columnWidths: [0.4,0.6]

    ColumnWidths is optional, if left out each column will have an even size.

    3.1.0 compatible version:
    Code:
    Ext.namespace("Ext.ux.layout");
    
    Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, {
        monitorResize: true,
        trackLabels: Ext.layout.FormLayout.prototype.trackLabels,
        setContainer: function() {
            Ext.layout.FormLayout.prototype.setContainer.apply(this, arguments);
            this.currentRow = 0;
            this.currentColumn = 0;
            this.cells = [];
        },
        renderItem : function(c, position, target) {
            if (c && !c.rendered) {
                var cell = Ext.get(this.getNextCell(c));
                cell.addClass("x-table-layout-column-" + this.currentColumn);
                Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, cell);
            }
        },
        getAnchorViewSize : Ext.layout.AnchorLayout.prototype.getAnchorViewSize,
        parseAnchor : Ext.layout.AnchorLayout.prototype.parseAnchor,
        getTemplateArgs : Ext.layout.FormLayout.prototype.getTemplateArgs,
        isValidParent : Ext.layout.FormLayout.prototype.isValidParent,
        onRemove : Ext.layout.FormLayout.prototype.onRemove,
        isHide : Ext.layout.FormLayout.prototype.isHide,
        onFieldShow : Ext.layout.FormLayout.prototype.onFieldShow,
        onFieldHide : Ext.layout.FormLayout.prototype.onFieldHide,
        adjustWidthAnchor : Ext.layout.FormLayout.prototype.adjustWidthAnchor,
        adjustHeightAnchor : Ext.layout.FormLayout.prototype.adjustHeightAnchor,
        getLabelStyle : Ext.layout.FormLayout.prototype.getLabelStyle,
        onLayout : function(ct, target) {
            Ext.ux.layout.TableFormLayout.superclass.onLayout.call(this, ct, target);
            if (!target.hasClass("x-table-form-layout-ct")) {
                target.addClass("x-table-form-layout-ct");
            }
            var viewSize = this.getAnchorViewSize(ct, target);
            var aw, ah;
            if (ct.anchorSize) {
                if (typeof ct.anchorSize == "number") {
                    aw = ct.anchorSize;
                } else {
                    aw = ct.anchorSize.width;
                    ah = ct.anchorSize.height;
                }
            } else {
                aw = ct.initialConfig.width;
                ah = ct.initialConfig.height;
            }
            var cs = ct.items.items, len = cs.length, i, j, c, a, cw, ch;
            var x, w, h, col, colWidth, offset;
            for (i = 0; i < len; i++) {
                c = cs[i];
                // get table cell
                x = c.getEl().parent(".x-table-layout-cell");
                if (this.columnWidths) {
                    // get column
                    col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
                    // get cell width (based on column widths)
                    colWidth = 0, offset = 0;
                    for (j = col; j < (col + (c.colspan || 1)); j++) {
                        colWidth += this.columnWidths[j];
                        offset += 10;
                    }
                    w = (viewSize.width * colWidth) - offset;
                } else {
                    // get cell width
                    w = (viewSize.width / this.columns) * (c.colspan || 1);
                }
                // set table cell width
                x.setWidth(w);
                // get cell width (-10 for spacing between cells) & height to be base width of anchored component
                w = w - 10;
                h = x.getHeight();
                // perform anchoring
                if (c.anchor) {
                    a = c.anchorSpec;
                    if (!a) {
                        var vs = c.anchor.split(" ");
                        c.anchorSpec = a = {
                            right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
                            bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
                        };
                    }
                    cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
                    ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
                    if (cw || ch) {
                        c.setSize(cw || undefined, ch || undefined);
                    }
                }
            }
        }
    });
    
    Ext.Container.LAYOUTS["tableform"] = Ext.ux.layout.TableFormLayout;
    3.1.1 compatible version:
    Code:
    Ext.namespace("Ext.ux.layout");
    
    Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, {
        monitorResize: true,
        trackLabels: Ext.layout.FormLayout.prototype.trackLabels,
        setContainer: function() {
            Ext.layout.FormLayout.prototype.setContainer.apply(this, arguments);
            this.currentRow = 0;
            this.currentColumn = 0;
            this.cells = [];
        },
        renderItem : function(c, position, target) {
            if (c && !c.rendered) {
                var cell = Ext.get(this.getNextCell(c));
                cell.addClass("x-table-layout-column-" + this.currentColumn);
                Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, cell);
            }
        },
        getLayoutTargetSize : Ext.layout.AnchorLayout.prototype.getLayoutTargetSize,
        parseAnchor : Ext.layout.AnchorLayout.prototype.parseAnchor,
        getTemplateArgs : Ext.layout.FormLayout.prototype.getTemplateArgs,
        isValidParent : Ext.layout.FormLayout.prototype.isValidParent,
        onRemove : Ext.layout.FormLayout.prototype.onRemove,
        isHide : Ext.layout.FormLayout.prototype.isHide,
        onFieldShow : Ext.layout.FormLayout.prototype.onFieldShow,
        onFieldHide : Ext.layout.FormLayout.prototype.onFieldHide,
        adjustWidthAnchor : Ext.layout.FormLayout.prototype.adjustWidthAnchor,
        adjustHeightAnchor : Ext.layout.FormLayout.prototype.adjustHeightAnchor,
        getLabelStyle : Ext.layout.FormLayout.prototype.getLabelStyle,
        onLayout : function(ct, target) {
            Ext.ux.layout.TableFormLayout.superclass.onLayout.call(this, ct, target);
            if (!target.hasClass("x-table-form-layout-ct")) {
                target.addClass("x-table-form-layout-ct");
            }
            var viewSize = this.getLayoutTargetSize();
            var aw, ah;
            if (ct.anchorSize) {
                if (typeof ct.anchorSize == "number") {
                    aw = ct.anchorSize;
                } else {
                    aw = ct.anchorSize.width;
                    ah = ct.anchorSize.height;
                }
            } else {
                aw = ct.initialConfig.width;
                ah = ct.initialConfig.height;
            }
            var cs = this.getRenderedItems(ct), len = cs.length, i, j, c, a, cw, ch;
            var x, w, h, col, colWidth, offset;
            for (i = 0; i < len; i++) {
                c = cs[i];
                // get table cell
                x = c.getEl().parent(".x-table-layout-cell");
                if (this.columnWidths) {
                    // get column
                    col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
                    // get cell width (based on column widths)
                    colWidth = 0, offset = 0;
                    for (j = col; j < (col + (c.colspan || 1)); j++) {
                        colWidth += this.columnWidths[j];
                        offset += 10;
                    }
                    w = (viewSize.width * colWidth) - offset;
                } else {
                    // get cell width
                    w = (viewSize.width / this.columns) * (c.colspan || 1);
                }
                // set table cell width
                x.setWidth(w);
                // get cell width (-10 for spacing between cells) & height to be base width of anchored component
                w = w - 10;
                h = x.getHeight();
                // perform anchoring
                if (c.anchor) {
                    a = c.anchorSpec;
                    if (!a) {
                        var vs = c.anchor.split(" ");
                        c.anchorSpec = a = {
                            right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
                            bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
                        };
                    }
                    cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
                    ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
                    if (cw || ch) {
                        c.setSize(cw || undefined, ch || undefined);
                    }
                }
            }
        }
    });
    
    Ext.Container.LAYOUTS["tableform"] = Ext.ux.layout.TableFormLayout;
    Last edited by JamesC; 10 Feb 2010 at 3:05 PM. Reason: 3.1.1 Update

  2. #2
    Ext JS Premium Member
    Join Date
    Aug 2008
    Posts
    93
    Vote Rating
    0
    Stephan Schrade is on a distinguished road

      0  

    Default


    Hi,
    have you tested this with IE as well ?
    So far it looks like it only works with FF.
    IE6 and IE7 fail. The second column is displayed at the end of the label of the first column.

    Here is my code (using ExtJS 3.0)
    PHP Code:
              layout: 'tableform',
                layoutConfig: {
                columns: 2,
                columnWidths: [0.75,0.25] //0.75,0.25
                },           
              defaults: {width: 300, msgTarget: 'side', colspan: 2},

              items:[{
                name: 'lufftid',
                xtype: 'hidden',
                value: <?=$this->lufftid?>,
                allowBlank: false,
                blankText: 'Bitte Standort ausfüllen'
                },{  
                fieldLabel: 'Kalibrierzyklus',
                xtype: 'textfield',
                vtype: 'Numbers',
                name: 'kalibrierzyklus',
                allowBlank: false,
                blankText: 'Bitte Kalibrierzyklus ausfüllen',
                width: 40,
                colspan: 1
                },{
                fieldLabel: '&nbsp;&nbsp;Monate',
                xtype: 'box',
                width: 40,
                // autoEl: {tag: 'div', html: ''},
                colspan: 1
    etc........

    The text "Monate" is displayed right after the text "Kalibrierzyklus".


    Any ideas ?

    TIA Stephan

  3. #3
    Sencha User
    Join Date
    Nov 2007
    Posts
    243
    Vote Rating
    0
    JamesC is on a distinguished road

      0  

    Default


    Normally what fixes those kind of issues is anchor: "100%" in every field (since the form layout handles the anchoring essentially ext needs to know how to size the field). Let me know if this fixes it!

  4. #4
    Ext JS Premium Member
    Join Date
    Aug 2008
    Posts
    93
    Vote Rating
    0
    Stephan Schrade is on a distinguished road

      0  

    Default


    Hi,
    many thanks, that helped.
    Now the form looks nice.
    It doesn't work with IE 6, but I don't care about this any more.

    CU Stephan

  5. #5
    Sencha User
    Join Date
    Nov 2007
    Posts
    243
    Vote Rating
    0
    JamesC is on a distinguished road

      0  

    Default


    I have tested this (and use it in my application) in IE6 so it should work. Additionally check any fieldsets above have 100% anchoring as well!

  6. #6
    Sencha User
    Join Date
    Jun 2008
    Posts
    18
    Vote Rating
    0
    raphac is on a distinguished road

      0  

    Default error

    error


    if I use this version:
    http://www.extjs.com/forum/showthrea...566#post330566

    the code works

    Code:
    var cadastroForm = {
                xtype: 'form',
                defaultType: 'textfield',
                labelAlign: 'top',
                labelWidth: 55,
                layout: 'tableform',
                layoutConfig: {
                    columns: 3,
                    columnWidths: [0.25,0.5,0.25]
                },
                items:[{
                    fieldLabel: 'Send From',
                    anchor:'100%',
                    labelStyle: 'font-weight:bold;',
                },{
                    fieldLabel: 'Send To',
                    anchor:'100%'
                },{
                    fieldLabel: 'Check me',
                    xtype: 'checkbox',
                    anchor:'100%'
                },{
                    fieldLabel: 'Subject',
                    anchor:'100%',
                    colspan: 3
                },{
                    xtype: 'textarea',
                    anchor: '100%',
                    colspan: 3
                }]
    }
    If I use this version 3.0, the code not works.

    If I commented this line:
    columnWidths: [0.25,0.5,0.25]
    works...
    Attached Images

  7. #7
    Ext User
    Join Date
    Apr 2008
    Location
    Santa Clara, CA
    Posts
    28
    Vote Rating
    0
    rtikku is on a distinguished road

      0  

    Default


    I have been using this ux with Ext 3.0 and it has been working fine. Upgraded to 3.1.0 and started getting the following error :

    c.getPositionEl().up("table", 5) is null

    return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target); ext-all-debug.js (line 13349)

    Tried debugging with firebug. c is the first field in my tableform, and c.getPositionEl().up('table', 5) is indeed null.

    Has anyone tried this ux with Ext 3.1.0 ? Does it work for you?

  8. #8
    Ext JS Premium Member
    Join Date
    Mar 2007
    Location
    NL
    Posts
    608
    Vote Rating
    1
    mdissel is on a distinguished road

      0  

    Default


    Quick workaround, add this to the TableFormLayout component

    Code:
    isValidParent :function(c, target){ 
    		return true;
    	}

  9. #9
    Sencha User
    Join Date
    Nov 2007
    Posts
    243
    Vote Rating
    0
    JamesC is on a distinguished road

      0  

    Default


    Sorry guys been a bit slow with my 3.1 upgrade, code for isValidParent I'm using is:

    Code:
        isValidParent : Ext.layout.FormLayout.prototype.isValidParent,
    I'll post a full update soon including handling for the new formlayout 'trackLabels' setting!

  10. #10
    Sencha User
    Join Date
    Nov 2007
    Posts
    243
    Vote Rating
    0
    JamesC is on a distinguished road

      0  

    Default


    I have updated the original post with the latest version compatible with 3.1 (which includes trackLabels functionality, using the config value of FormLayout trackLabels).