PDA

View Full Version : [3.0] Ext.ux.layout.TableFormLayout - table layout with form field labels



JamesC
14 Aug 2009, 12:34 AM
Code below, use layout: "tableform" and the items then support standard anchor configuration as well as being layed out in a table.

Example usage:


layout: "tableform",
layoutConfig: {
columns: 2,
columnWidths: [0.4,0.6]
}


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

3.1.0 compatible version:


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:


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;

Stephan Schrade
2 Sep 2009, 4:50 AM
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)


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

JamesC
4 Sep 2009, 12:05 PM
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!

Stephan Schrade
7 Sep 2009, 12:44 AM
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

JamesC
7 Sep 2009, 1:45 AM
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!

raphac
20 Nov 2009, 5:40 AM
if I use this version:
http://www.extjs.com/forum/showthread.php?p=330566#post330566

the code works



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...

rtikku
21 Dec 2009, 12:39 AM
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?

mdissel
24 Dec 2009, 5:56 AM
Quick workaround, add this to the TableFormLayout component


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

JamesC
31 Dec 2009, 4:10 AM
Sorry guys been a bit slow with my 3.1 upgrade, code for isValidParent I'm using is:




isValidParent : Ext.layout.FormLayout.prototype.isValidParent,



I'll post a full update soon including handling for the new formlayout 'trackLabels' setting!

JamesC
31 Dec 2009, 5:23 AM
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).

javaman
13 Jan 2010, 11:10 AM
if I use this version:
http://www.extjs.com/forum/showthread.php?p=330566#post330566

the code works



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...

I have the same problem, but if I use the old version: http://www.extjs.com/forum/showthread.php?p=330566#post330566 everything works with 3.1 oO

JamesC
14 Jan 2010, 5:56 AM
So your not using the new version and it works? Hmm strange I'm using the new version with no problems... check the first post again and let me know!

javaman
14 Jan 2010, 7:12 AM
yeah, exactly

If I use the old version everything works, but If I use the version of the first post and use columnWidths, I have a problem, like the photo posted by raphac

Like I quoted, if I comment that line, everythings works ok

I used the example code posted by raphac

[]'s

javaman
15 Jan 2010, 12:31 AM
Well, the old version has a problem, if I put a FormPanel in a window and resize the window, the window disapear..

I simply copy and past this part above of the old version on the new and everything works, something in this part is wrong, I guess




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;
// 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);
}
}
}




EDIT

I think the problem is in this line (it was a "\")

Wrong:
col = parseInt(x.dom.className.replace(/.*x-table-layout-column-([d]+).*/, "$1"));

Write:
col = parseInt(x.dom.className.replace(/.*x-table-layout-column-([[I]\d]+).*/, "$1"));

mdissel
16 Jan 2010, 6:02 AM
I've added the fix from the previous post and make it compatible with the current 3.1* svn version (rev. 5899).. Not fully tested yet!


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(!this.table){
this.table = target.createChild(
Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
}
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 = 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;

javaman
16 Jan 2010, 6:35 AM
well, I tested and got this error: this.getLayoutTargetSize is not a function

The two codes above works with me. I really don't know If they are equal because I've tested many things and I'm completly lost in my versions....hehe
I've commented the 2 lines that had the error I said

Code 1:



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(!this.table){
this.table = target.createChild(
Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
}
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,
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.getLayoutTargetSize();
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;



Code 2:



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) {
if(c.isFormField && c.fieldLabel){
if(!c.allowBlank){
c.fieldLabel = (c.fieldLabel || '') + "<span class=\"required\">*</span>";
}
}
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];
x = c.getEl().parent(".x-table-layout-cell");

if (this.columnWidths) {

col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
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 {
w = (viewSize.width / this.columns) * (c.colspan || 1);
}

x.setWidth(w);
w = w - 10;
h = x.getHeight()

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;

mdissel
16 Jan 2010, 8:44 AM
are you using the latest rev. 5899 (or newer) from the svn trunk?

in that rev. Ext.layout.AnchorLayout.prototype.getAnchorViewSize doesn't exist anymore..

javaman
17 Jan 2010, 2:44 PM
Oh, that's it, sorry. I didn't read the rev. that you posted.
[]'s

javaman
18 Jan 2010, 4:46 PM
I used the rev you said and got the same error...

this.getLayoutTargetSize is not a function

[]'s

JamesC
9 Feb 2010, 1:28 AM
Guys, have hopefully fixed compatability with 3.1.1 now - let me know!

smit_al
10 Feb 2010, 8:37 AM
Installed the 3.1.1 version today. Had to change the parseInt line to match post 14 to get the columnWidths to work. Without it the columnWidths were ignored.

JamesC
10 Feb 2010, 10:50 AM
Ok apologies for those of you with issues with the parseint, the forum is stripping the \ from the code! Will update the code asap!

JamesC
10 Feb 2010, 3:06 PM
OK its fixed in the original post, issue was that the [ p h p ] tags were stripping the \ from the regex!

Iveco
12 Feb 2010, 12:01 PM
Awesome, exactly what I was needing right now. This is why I love the community here.

I was using the ExtJS TableLayout on a Formpanel and had several troubles with missing fieldLabels etc.

Just use this tablelayout function and all formpanel functionality is working again. Should be included by default in ExtJs IMHO.

Thx.

jukkajurvansuu
15 Feb 2010, 12:51 AM
Great extension! This should be standard layout in ExtJS imo.

TonySteele
8 Apr 2010, 7:05 AM
Just switched my app to ExtJs 3.2 for quick test and TableFormLayout is failing at:


c.anchorSpec = a = {
right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
};


calls parseAnchor(...) in ext-all-debug.js (20025) which fails at

if(this.parseAnchorRE.test(a)){

a='100%'
with: 'this.parseAnchorRE' is null or not an object

my code is :


items: [{
layout: 'tableform',
border: false,
layoutConfig: { columns: 2 },
labelAlign: 'top',
items: [{
xtype: 'textfield',
fieldLabel: 'Name',
name: 'name',
anchor: '100%',
colspan: 2
},{
xtype: 'combo',
fieldLabel: 'Layout',
name: 'layout',
anchor: '100%'
}, {
xtype: 'combo',
fieldLabel: 'Site',
name: 'site',
anchor: '100%'
}]
}

ReBorn
13 Apr 2010, 9:41 AM
Worked for me under 3.2.0


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 : function(a, start, cstart){
if(a && a != 'none'){
var last;
if(/^(r|right|b|bottom)$/i.test(a)){ // standard anchor
var diff = cstart - start;
return function(v){
if(v !== last){
last = v;
return v - diff;
}
}
}else if(a.indexOf('%') != -1){
var ratio = parseFloat(a.replace('%', ''))*.01; // percentage
return function(v){
if(v !== last){
last = v;
return Math.floor(v*ratio);
}
}
}else{
a = parseInt(a, 10);
if(!isNaN(a)){ // simple offset adjustment
return function(v){
if(v !== last){
last = v;
return v + a;
}
}
}
}
}
return false;
},
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;

JamesC
13 Apr 2010, 10:27 AM
This is currently untested in 3.2 will give it a go and try to get any fixes done asap!

ReBorn
18 Apr 2010, 2:34 PM
Well, for now I have two unresolved problems with my fix above:
1) Unable to set separators (or whitespaces) between columns -- with 100% width of elements label of the second element in the row is placed too near first element's border. Especially noted with colspann'ed elements.
2) It would be lovely to set individual labelWidth for each elements (like textboxes) without touching parent container (like form or tab). If I 'fix' label width with CSS (by labelStyle), render is broken, when width of the label exceeds the labelWidth of the parent container.

Can anybody advice something ?

pkullmann
22 Apr 2010, 7:52 AM
Nice work! Works well for me with 3.2.0 / IE8,FF,Chrome

However, I'd like to see the capability of auto-adjusting the labelWidth of each column to the longest label. In Principle this would be simple, if the labels were rendered into a separate columns of the underlying table. Another approach might be to do some postprocessing after the items have been layed out.
Any ideas on how to go about it, are welcome. I think I will give it a try....

pkullmann
23 Apr 2010, 7:33 AM
As announced in my previous post, I have made some additions:

1) For layoutConfig I added the option 'labelAutoWidth'. With it set to true, the width of the largest label in each column will be calculated and used for all labels in that column. The property 'labelWidth' will be used as the minimal label width.
I find it useful for getting lined up fields without wasting space. Especially if you use the code with different languages, the form will adjust to the labels. Of course, this feature is only useful, if you have the labels in front of the fields, not above.

2) For layoutConfig I added the option 'packFields'. With it set to true, the form will use the minimal space according to the field specs. In other words: the layout will not be streched to fill the form panel. If you use anchors, be sure to also set 'width' to '0'. Otherwise, it might not work correctly. columnWidths will be ignored when using packFields.

I have done some (basic) testing and it works well under FF and Chrome. There is a glitch with IE8 where anchoring ('100%') did not work as expected. Didn't have the time yet to dig into, though.

The code:

- UPDATED 4/26/2010, see post #32
- UPDATED 4/27/2010, see post #33
- UPDATED 4/27/2010, see post #34



Ext.namespace("Ext.ux.layout");

Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, {
monitorResize: true,
labelAutoWidth: false,
packFields: false,
trackLabels: Ext.layout.FormLayout.prototype.trackLabels,
setContainer: function(ct) {
Ext.layout.FormLayout.prototype.setContainer.apply(this, arguments);
if (ct.labelAlign == 'top') {
this.labelAutoWidth = false;
if (this.fieldSpacing)
this.elementStyle = 'padding-left: ' + this.fieldSpacing + 'px;';
} else {
if (this.labelAutoWidth)
this.labelStyle = 'width: auto;';
if (this.packFields && !ct.labelWidth)
ct.labelWidth = 1;
}
if (this.fieldSpacing)
this.labelStyle += 'padding-left: ' + this.fieldSpacing + 'px;';
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);
if (c.anchor)
c.width = 1;
Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, cell);
}
},
getLayoutTargetSize : Ext.layout.AnchorLayout.prototype.getLayoutTargetSize,
parseAnchorRE : Ext.layout.AnchorLayout.prototype.parseAnchorRE,
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();
if (this.fieldSpacing)
viewSize.width -= this.fieldSpacing;
var aw, ah;
if (ct.anchorSize) {
if (Ext.isNumber(ct.anchorSize)) {
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;
var x, col, columnWidthsPx, w;
// calculate label widths
if (this.labelAutoWidth) {
var labelWidths = new Array(this.columns);
var pad = ct.labelPad || 5;
for (i = 0; i < this.columns; i++)
labelWidths[i] = ct.labelWidth || 0;
// first pass: determine maximal label width for each column
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// set the label width
if (c.label && c.label.getWidth() > labelWidths[col])
labelWidths[col] = c.label.getWidth();
}
// second pass: set the label width
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// get label
if (c.label) {
// set the label width and the element padding
c.label.setWidth(labelWidths[col]);
c.getEl().parent(".x-form-element").setStyle('paddingLeft',(labelWidths[col] + pad - 3) + 'px');
}
}
}
if (!this.packFields) {
var rest = viewSize.width;
columnWidthsPx = new Array(this.columns);
// Calculate the widths in pixels
for (j = 0; j < this.columns; j++) {
if (this.columnWidths)
columnWidthsPx[j] = Math.floor(viewSize.width * this.columnWidths[j]);
else
columnWidthsPx[j] = Math.floor(viewSize.width / this.columns);
rest -= columnWidthsPx[j];
}
// Correct the last column width, if necessary
if (rest > 0)
columnWidthsPx[this.columns - 1] += rest;
}
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
if (!this.packFields) {
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// get cell width (based on column widths)
for (j = col, w = 0; j < (col + (c.colspan || 1)); j++)
w += columnWidthsPx[j];
// set table cell width
x.setWidth(w);
}
// perform anchoring
if (c.anchor) {
var a, h, cw, ch;
if (this.packFields)
w = x.getWidth();
// get cell width (subtract padding for label) & height to be base width of anchored component
this.labelAdjust = c.getEl().parent(".x-form-element").getPadding('l');
if (this.labelAdjust && ct.labelAlign == 'top')
w -= this.labelAdjust;
h = x.getHeight();
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;

pkullmann
26 Apr 2010, 7:40 AM
I have improved the code in my previous post (#31, get it from there) and fixed some errors:

- It is not anymore necessary to specify width if anchoring is used.
- The IE problems are solved.

I also rearranged the code a bit and made some (small) optimization, like moving code inside an if, where appropriate.

I did some more testing, however far from being extensive.
Above code is working (for me) under ExtJS 3.2.0 under

- IE 8
- FF 3.6.3
- Chrome 4.1.249.1059
- Safari 4.0.5
- Opera 10.51

If anyone is willing to test, I'd be glad to incorporate fixes and more features.
Next, I will tackle the issues mentioned by ReBorn in post #29

pkullmann
27 Apr 2010, 2:39 AM
I have again copied a new version to my post #31

I have fixed a couple of bugs, when using labelAlign: 'top'

I have added the layoutConfig option 'fieldSpacing', which allows to define the space between fields, thus solving the issue brought up by ReBorn in post #29
It was simple to implement, but has a disadvantage: The field spacing is added in front of all fields, also to those in the first column, which might not be desireable. A solution could be to simply reduce the view size accordingly, so that there is the same margin left and right. Ideas welcome.

Peter

pkullmann
27 Apr 2010, 2:49 AM
Ok, I made the change suggested in my previous post, it simply looks better.
If you use fieldSpacing and had a padding before for the form, you can simply reduce the padding accordingly, to get the same.

The new code is in post #31

JamesC
27 Apr 2010, 1:14 PM
Good work, will give it a test in my app soon - we use it in almost all our forms (~70 forms)!

pkullmann
28 Apr 2010, 6:48 AM
Just realized that labelWidth defaults to 100, if it is not set. This means, that if you use labelAutoWidth: true, you should set labelWidth to something small (e.g. 1) to get the full effect of minimizing the label spaces.
If labelWidth is not set, it will default to 100, which is then used as minimal label size...

persephone
21 May 2010, 1:38 PM
Has anyone tried using this layout with composite fields? I was hoping to use this layout to avoid issues with the 'table' layout not rendering composite fields properly. Of course it works fine when packFields is false, but when I set it to true,I get the exact same issue I did with the table layout (see http://www.extjs.com/forum/showthread.php?99235-CLOSED-Composite-field-in-table-layout-does-not-render-correctly)

gustavofranco
29 Sep 2010, 12:59 PM
Hi all!

This layout help me a lot, but I have a little problem with it.
When I use TableFormLayout and set a combo or datefield readonly, they're resizing like picture bellow.

In picture:
1º - Fields in a normal state
2º - Fields after setReadOnly(true)
3º - Fields after setReadOnly(false)

22621

Someone know why?

chevanton19
20 Oct 2010, 2:57 AM
I tryed usage of above posted code (thx for the job!) and saw it works nice under 3.2 and FF 3.6.3, failing with IE7...any clue of a solution?

thx in advance!
Daniele

Condor
20 Oct 2010, 3:17 AM
You will probably have to configure those triggerfields with a fixed width.

chevanton19
20 Oct 2010, 5:19 AM
i've discovered a bit more about the problem,i think it originates from the combination of form items colspan values

this is a piece of the code creating my form:


var o_form = new Ext.form.FormPanel({
autoScroll : true,
title : go_QLabels.get('SERVICEINFO'),
bodyStyle : 'padding:5px',
layout : 'tableform',
defaults : {labelSeparator : ''},
layoutConfig : {columns : 4},
labelWidth : 90,
items : [a_items],
getJSON : function(){
var oJSON = {
id : o_idhd.getValue(),
name : o_name.getValue(),
desc : o_desc.getValue(),
url : o_url.getValue(),
ico : o_ico.getValue(),
agroup : o_agroup_combo.getValue(),
mgroup : o_mgroup_combo.getValue(),
inputmode : o_inputmode.getValue(),
as400 : o_as400.getValue() == 'on' ? 1:0,
constrain : o_constrain.getValue() == 'on' ? 1:0
};
return oJSON;


the only field combination i found workign is



var a_items = [ /*colspan*/
o_name,o_idhd, /*2,2*/
o_url,o_ico, /*2,2*/
o_agroup_combo,o_mgroup_combo, /*2,2*/
o_as400,o_constrain,o_inputmode, /*1,1,2*/
o_desc /*4*/
];


any other attempts had a bad result, for example if u change o_as400,o_constrain,o_inputmode in o_inputmode,o_as400,o_constrain form's layout is broken.

luckily i can keep this field disposition even if it's not teh desired one!!
hope this can help a bit on debugging or fixing the stuff if someone want to!

using Ext 3.2.1 with explorer 7

Grolubao
6 Dec 2011, 5:21 AM
Thank you very much!

Grolubao
8 Dec 2011, 7:30 AM
I implemented a couple of nice modifications:

- minWidth/minHeight that each of the component will have before a scroll bar appears
- Dynamic height on the components



Ext.namespace("Ext.ux.layout");

Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, {
monitorResize: true,
labelAutoWidth: false,
packFields: false,
trackLabels: Ext.layout.FormLayout.prototype.trackLabels,
setContainer: function(ct) {
Ext.layout.FormLayout.prototype.setContainer.apply(this, arguments);
if (ct.labelAlign == 'top') {
this.labelAutoWidth = false;
if (this.fieldSpacing)
this.elementStyle = 'padding-left: ' + this.fieldSpacing + 'px;';
} else {
if (this.labelAutoWidth)
this.labelStyle = 'width: auto;';
if (this.packFields && !ct.labelWidth)
ct.labelWidth = 1;
}
if (this.fieldSpacing)
this.labelStyle += 'padding-left: ' + this.fieldSpacing + 'px;';
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);
if (c.anchor)
c.width = 1;
Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, cell);
}
},
getLayoutTargetSize : Ext.layout.AnchorLayout.prototype.getLayoutTargetSize,
parseAnchorRE : Ext.layout.AnchorLayout.prototype.parseAnchorRE,
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();
if (this.fieldSpacing)
viewSize.width -= this.fieldSpacing;
var aw, ah;
if (ct.anchorSize) {
if (Ext.isNumber(ct.anchorSize)) {
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;
var x, col, columnWidthsPx, columnHeightPx,w;
// calculate label widths
if (this.labelAutoWidth) {
var labelWidths = new Array(this.columns);
var pad = ct.labelPad || 5;
for (i = 0; i < this.columns; i++)
labelWidths[i] = ct.labelWidth || 0;
// first pass: determine maximal label width for each column
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// set the label width
if (c.label && c.label.getWidth() > labelWidths[col])
labelWidths[col] = c.label.getWidth();
}
// second pass: set the label width
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// get label
if (c.label) {
// set the label width and the element padding
c.label.setWidth(labelWidths[col]);
c.getEl().parent(".x-form-element").setStyle('paddingLeft',(labelWidths[col] + pad - 3) + 'px');
}
}
}
if (!this.packFields) {
var rest = viewSize.width;
var restHeight = viewSize.height;
columnWidthsPx = new Array(this.columns);
columnHeightPx = new Array(this.rows);
// Calculate the widths in pixels
for (j = 0; j < this.columns; j++) {
if (this.columnWidths)
columnWidthsPx[j] = Math.floor(viewSize.width * this.columnWidths[j]);
else
columnWidthsPx[j] = Math.floor(viewSize.width / this.columns);

rest -= columnWidthsPx[j];
}
for (j = 0; j < this.rows; j++) {
columnHeightPx[j] = Math.floor(viewSize.height / this.rows);

restHeight -= columnHeightPx[j];
}
// Correct the last column width, if necessary
if (rest > 0)
columnWidthsPx[this.columns - 1] += rest;
if (restHeight > 0)
columnHeightPx[this.rows - 1] += restHeight;
}
for (i = 0; i < len; i++) {
c = cs[i];
// get table cell
x = c.getEl().parent(".x-table-layout-cell");
if (!this.packFields) {
// get column
col = parseInt(x.dom.className.replace(/.*x\-table\-layout\-column\-([\d]+).*/, "$1"));
// get cell width (based on column widths)
for (j = col, w = 0; j < (col + (c.colspan || 1)); j++)
w += columnWidthsPx[j];

for (j = 0, h = 0; j < (c.rowspan || 1); j++){
h += columnHeightPx[j];
}

// set table cell width

x.setSize(w < this.minWidth ? this.minWidth : w, h < this.minHeight ? this.minHeight : h);
c.setSize(w < this.minWidth ? this.minWidth : w,h < this.minHeight ? this.minHeight : h);
}
// perform anchoring
if (c.anchor) {
var a, h, cw, ch;
if (this.packFields)
w = x.getWidth();
// get cell width (subtract padding for label) & height to be base width of anchored component
this.labelAdjust = c.getEl().parent(".x-form-element").getPadding('l');
if (this.labelAdjust && ct.labelAlign == 'top')
w -= this.labelAdjust;
h = x.getHeight();
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;