(最新修改:覆盖renderAll方法,使得hidden类型的控件不布局)
通过不懈的google,终于还是在Extjs上找到了tableform 布局的代码,这可以终结网上大部分通过hbox,或者column来布局form 的代码例子了。
先看一个例子
var form = new Ext.form.FormPanel({
renderTo:'content',
layout:'tableform',
width:600,
frame:true,
title:'test',
layoutConfig: { columns: 2 },
items: [
{ fieldLabel: 'Created By:', xtype: 'textfield'
},
{ fieldLabel: 'Author:', xtype: 'textfield'
},
{ fieldLabel: 'Creation Date:', xtype: 'datefield' },
{ fieldLabel: 'to', xtype: 'datefield' },
{ fieldLabel: 'Modified By', xtype: 'textfield',colspan: 2},
{ fieldLabel: 'Modified Date:', xtype: 'datefield' },
{ fieldLabel: 'to', xtype: 'datefield' },
})
tableform的好处是你可以一直增加表单还不用考虑布局。这个有点类似我8年前swing布局中写的一个布局管理器
代码如下,也可以在此链接找到最新更新:http://www.sencha.com/forum/showthread.php?59897-Ext.layout.TableFormLayout-%28v2%29/page3
Ext.namespace("Ext.ux.layout"); Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, { monitorResize: true, 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, getTemplateArgs : Ext.layout.FormLayout.prototype.getTemplateArgs, 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(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 = this.getRenderedItems(ct), len = cs.length, i, c, a, cw, ch, el, vs, boxes = []; 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(); // If a child container item has no anchor and no specific width, set the child to the default anchor size if (!c.anchor && c.items && !Ext.isNumber(c.width) && !(Ext.isIE6 && Ext.isStrict)){ c.anchor = this.defaultAnchor; } if(c.anchor){ a = c.anchorSpec; if(!a){ // cache all anchor values 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){ boxes.push({ comp: c, width: cw || undefined, height: ch || undefined }); } } } for (i = 0, len = boxes.length; i < len; i++) { c = boxes[i]; c.comp.setSize(c.width, c.height); } }, parseAnchor : function(a, start, cstart) { if (a && a != "none") { var last; if (/^(r|right|b|bottom)$/i.test(a)) { 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; return function(v) { if (v !== last) { last = v; return Math.floor(v * ratio); } }; } else { a = parseInt(a, 10); if (!isNaN(a)) { return function(v) { if (v !== last) { last = v; return v + a; } }; } } } return false; }, renderAll : function(ct, target){ var items = ct.items.items, i, c, len = items.length; for(i = 0; i < len; i++) { c = items[i]; if(c.xtype=="hidden"){ continue; } if(c && (!c.rendered || !this.isValidParent(c, target))){ this.renderItem(c, i, target); } } }, adjustWidthAnchor : function(value, comp) { return value - (comp.isFormField ? (comp.hideLabel ? 0 : this.labelAdjust) : 0); }, adjustHeightAnchor : function(value, comp) { return value; }, // private isValidParent : function(c, target){ return c.getPositionEl().up('table', 6).dom.parentNode === (target.dom || target); }, getLabelStyle : Ext.layout.FormLayout.prototype.getLabelStyle, labelSeparator : Ext.layout.FormLayout.prototype.labelSeparator, trackLabels: Ext.layout.FormLayout.prototype.trackLabels }); Ext.Container.LAYOUTS['tableform'] = Ext.ux.layout.TableFormLayout; code]1 楼 xietaomlzs 2010-07-30呵呵,本想给你评论下,结果那么麻烦,还要我测试,搞的想说的话也不说了。2 楼 qingtianxl 2011-01-19本人试用下3.3版本的 tableform 发现一个小bug
当试用panel当做面板装载 form时 xtype=hidden的控件能被隐藏掉 但是当用window弹出窗口装载 form时 会报错:
this.getLayoutTargetSize is not a function
[在此错误处中断] var viewSize = this.getLayoutTargetSize(ct, target);
错误出现再 26行出
getLayoutTargetSize : Ext.layout.AnchorLayout.prototype.getLayoutTargetSize,
应该是getLayoutTargetSize 取不到值 但是我不知道这句话是什么意思 请大家帮忙解决一下