-
23 Jun 2008 6:48 AM #1
Ext.ux.layout.TableFormLayout
Ext.ux.layout.TableFormLayout
I've seen a number of posts by users wishing field labels rendered in the table layout (they do in the column layout for example). A common response is to wrap each field with a container/panel with the form layout. This does work, but requires a lot of nested containers.
I created a very simple table-form layout which automatically wraps each item with an Ext.Panel with a form layout so that field labels are rendered as well (for some reason I couldn't get this to work with an Ext.Container):
Source:
Sample:Code:Ext.namespace('Ext.ux.layout'); Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, { renderAll : function(ct, target) { var items = ct.items.items; for (var i = 0, len = items.length; i < len; i++) { var c = items[0]; // use 0 index because the array shrinks by one after each call to renderItem() if (c && (!c.rendered || !this.isValidParent(c, target))) { this.renderItem(c, i, target); } } }, renderItem : function(c, position, target){ if (c && !c.rendered) { var td = this.getNextCell(c); var p = new Ext.Panel(Ext.apply(this.container.formConfig, { layout: 'form', // this is the tableform layout so force each cell panel to have a form layout items: c, renderTo: td })); } } }); Ext.Container.LAYOUTS['tableform'] = Ext.ux.layout.TableFormLayout;
Demo:Code:Ext.onReady(function() { Ext.QuickTips.init(); var p = new Ext.Panel( { layout: 'tableform', title: 'Table-Form Layout', bodyStyle: 'padding:6px', renderTo: Ext.getBody(), layoutConfig: {columns:3}, formConfig: // config options to be applied to each panel in each table cell { layoutConfig: { labelSeparator: '' }, bodyStyle: 'padding:0 3px', labelAlign: 'top', border: false }, items: [ { xtype: 'textfield', fieldLabel: 'Field 1', name: 'Field1', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 2', name: 'Field2', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 3', name: 'Field3', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 4', name: 'Field4', width: 115 }, { colspan: 2, xtype: 'textfield', fieldLabel: 'Field 5', name: 'Field5', width: 236 } ] }); });
http://www.innovativetechsolutions.n.../tableform.htm
-
23 Jun 2008 10:23 AM #2
Very nice! it fixes two "errors":
- tab order
- anchoring when using multiple columns (and col spanning)
-
23 Jun 2008 10:40 AM #3
One issue when using anchoring.. The size of the fields is not correct when i changed your sample using this config:
Code:layoutConfig: {columns:3}, formConfig: // config options to be applied to each panel in each table cell { layoutConfig: { labelSeparator: '', anchor: '88%' }, defaults:{ msgTarget: 'side' }, bodyStyle: 'padding:0px 3px', labelAlign: 'top', border: false },
-
30 Jun 2008 2:51 AM #4
ok for ext 2.0 but failure in ext 2.1
ok for ext 2.0 but failure in ext 2.1
It is great extension!
In my environment, it is ok for ext 2.0 library...but when I switch to 2.1 library, it show:
A.container has no properties
[IMG]chrome://firebug/content/blank.gif[/IMG]Ext.FormPanel=Ext.extend(Ext.Panel,{buttonAlign:"center",minButtonWidth:75,label...
Could you please to tell me how to fix this?
-
30 Jun 2008 4:45 AM #5
Bit heavyweight to use a Panel as the inner Container. You don't need all the machinery of Panel, it's only a Container, and you can use the existing <td> as the element for it, so no need for any deep DOM nesting...:
try this, and let us know how it goes:
Code:renderItem : function(c, position, target) { if (c && !c.rendered) { var td = this.getNextCell(c) new Ext.Container(Ext.apply(this.container.formConfig, { el: td, renderTo: td.parentNode, layout: 'form', // this is the tableform layout so force each cell to have a form layout items: c })); } }Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
30 Jun 2008 6:10 AM #6
OK, how about this version?
Code:<html> <head> <title>Absolute Forms</title> <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css"/> <!-- GC --> <!-- LIBS --> <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script> <!-- ENDLIBS --> <script type="text/javascript" src="../../ext-all-debug.js"></script> <link rel="stylesheet" type="text/css" href="forms.css"/> <!-- Common Styles for the examples --> <link rel="stylesheet" type="text/css" href="../examples.css"/> </head> <script type="text/javascript"> Ext.override(Ext.layout.FormLayout, { fieldTpl: (function() { var t = new Ext.Template( '<div class="x-form-item {5}" tabIndex="-1">', '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>', '<div class="x-form-element" id="x-form-el-{0}" style="{3}">', '</div><div class="{6}"></div>', '</div>' ); t.disableFormats = true; return t.compile(); })() }); Ext.namespace('Ext.ux.layout'); Ext.ux.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, { fieldTpl: Ext.layout.FormLayout.prototype.fieldTpl, renderItem : function(c, position, target) { if (c && !c.rendered) { Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, Ext.get(this.getNextCell(c))); } } }); Ext.Container.LAYOUTS['tableform'] = Ext.ux.layout.TableFormLayout; Ext.onReady(function() { Ext.QuickTips.init(); var p = new Ext.Panel( { layout: 'tableform', title: 'Table-Form Layout', bodyStyle: 'padding:6px', renderTo: Ext.getBody(), layoutConfig: {columns:3}, formConfig: // config options to be applied to each panel in each table cell { layoutConfig: { labelSeparator: '' }, bodyStyle: 'padding:0 3px', labelAlign: 'top', border: false }, items: [ { xtype: 'textfield', fieldLabel: 'Field 1', name: 'Field1', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 2', name: 'Field2', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 3', name: 'Field3', width: 115 }, { xtype: 'textfield', fieldLabel: 'Field 4', name: 'Field4', width: 115 }, { colspan: 2, xtype: 'textfield', fieldLabel: 'Field 5', name: 'Field5', width: 236 } ] }); }); </script> <body> </body> </html>Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
30 Jun 2008 7:17 AM #7
What's the reason of the override of Ext.layout.FormLayout.fieldTpl?
-
30 Jun 2008 8:00 AM #8
Because Ext.layout.FormLayout.prototype.renderItem uses this.fieldTpl which is only available in Ext.layout.FormLayout - and then, only after it has been invoked once - hence the override to ensure its always there in the prototype.
Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
30 Jun 2008 11:39 AM #9
I think we need to update the setContainer method also for tableform layout to be able to use properties such as labelWidth etc.
Code:/** * Needed for tableform layout **/ Ext.override(Ext.layout.FormLayout, { fieldTpl: (function() { var t = new Ext.Template( '<div class="x-form-item {5}" tabIndex="-1">', '<label for="{0}" style="{2}" class="x-form-item-label">{1}{4}</label>', '<div class="x-form-element" id="x-form-el-{0}" style="{3}">', '</div><div class="{6}"></div>', '</div>' ); t.disableFormats = true; return t.compile(); })() }); /** * Table form layout **/ Ext.layout.TableFormLayout = Ext.extend(Ext.layout.TableLayout, { setContainer : function(ct){ Ext.layout.TableFormLayout.superclass.setContainer.call(this, ct); if(ct.labelAlign){ ct.addClass('x-form-label-'+ct.labelAlign); } if(ct.hideLabels){ this.labelStyle = "display:none"; this.elementStyle = "padding-left:0;"; this.labelAdjust = 0; }else{ this.labelSeparator = ct.labelSeparator || this.labelSeparator; ct.labelWidth = ct.labelWidth || 100; if(typeof ct.labelWidth == 'number'){ var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5); this.labelAdjust = ct.labelWidth+pad; this.labelStyle = "width:"+ct.labelWidth+"px;"; this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px'; } if(ct.labelAlign == 'top'){ this.labelStyle = "width:auto;"; this.labelAdjust = 0; this.elementStyle = "padding-left:0;"; } } }, fieldTpl: Ext.layout.FormLayout.prototype.fieldTpl, renderItem : function(c, position, target) { if (c && !c.rendered) { Ext.layout.FormLayout.prototype.renderItem.call(this, c, 0, Ext.get(this.getNextCell(c))); } } }); Ext.Container.LAYOUTS['tableform'] = Ext.layout.TableFormLayout;
-
30 Jun 2008 1:36 PM #10
Label Options
Label Options
Animal,
Thanks for posting an alternative solution. However, I'm not sure how to make it work with labels on top. Ultimately, I'm not sure why Ext JS doesn't render labels with form fields in all layouts, but it is probably because it is relatively complex to handle all of the options for labels.
In the forums, the response to attempting to use form fields in a table layout is always that you have to put an extra layer of containers specifying the "form" layout in each one and then putting the form fields in those containers. My approach was to just automate this so that each table/form didn't need so many nested containers in the code. I'm not sure why I had to make it a Panel, but my approach didn't work with the generic Container object.
I would be interested in using a robust table/form layout if it is workable. Can you expand your solution to work with the various label options?


Reply With Quote