Tabla de Contenidos
Proposal: Ext widget meta-constructor-configurator
(Página creada 2007/06/29; movida a esta ubicación 2009/05/06.)
Each Ext widget (tree, grid, resizable, dialog, tab panel, etc) has a constructor function that accepts a configuration object as a parameter. A configuration object consists of a variable number of configuration properties (or options), and each of these options is assigned a default value by Ext if not explicitely set in the config object.
We need a practical and quick tool that allows to explore the many combinations of config options for every single widget. For each widget constructor, we should have a form (an Ext.form, I guess) that offers all the available options, and a “Create” button that will invoke the corresponding constructor function passing it the given options. Or better yet, a single form which permits the selection of a specific widget type, and then presents the corresponding constructor options.
Every widget that is created this way should be easily removed/destroyed/recreated (freeing the associated memory resources!).
This tool could in principle be used in a stand-alone (i.e. isolated) page, just for playing and testing with the Ext family of widgets. But it could also be useful as a widget in itself, “pluggable” in any Ext page, so that you could test different widget creation options within the context of your own application, and without having to touch your code and reload the page every time an option is changed.
(For those properties who take numeric values (e.g. heights and widths), we could use a control like that used to specify the number of copies to print in print dialogs, that is, a textbox with two little arrow buttons that allow to increment or decrement the value. How can we do that in Ext?)
Should we allow creation of multiple simultaneous instances of a given widget? It could be useful for side by side comparisons.
Methods needed
- construct: takes the form's current values, builds the corresponding config object, and calls the constructor of the widget. In some cases, construction is not enough to make the widget appear on the screen; some render() or show() method must be invoked next. What about existing instances?
- reset: globally resets all the options to their default values, or just one specific property.
- destroy: destroys instances of this widget created using this tool. What about destroying a specific instance?
Example case
Let's take as an example Ext.BasicDialog. Its constructor receives 2 parameters:
- String/HTMLElement/Ext.Element el
- Object config
and this is the set of config options:
property | type | description | default | form control |
---|---|---|---|---|
animateTarget | String/Element | Id or element from which the dialog should animate while opening | null with no animation | |
autoCreate | Boolean/DomHelper | True to auto create from scratch, or using a DomHelper Object | false | checkbox |
autoScroll | Boolean | True to allow the dialog body contents to overflow and display scrollbars | false | checkbox |
autoTabs | Boolean | If true, all elements with class 'x-dlg-tab' will get automatically converted to tabs | false | checkbox |
buttonAlign | String | Valid values are “left,” “center” and “right” | 'right' | radio or combobox |
closable | Boolean | False to remove the built-in top-right corner close button | true | checkbox |
collapsible | Boolean | False to remove the built-in top-right corner collapse button | true | checkbox |
constraintoviewport | Boolean | True to keep the dialog constrained within the visible viewport boundaries | true | checkbox |
draggable | Boolean | False to disable dragging of the dialog within the viewport | true | checkbox |
fixedcenter | Boolean | True to ensure that anytime the dialog is shown or resized it gets centered | false | checkbox |
height | Number | Height of the dialog in pixels (can also be set via CSS). | Determined by browser | textbox (inc/dec) |
minButtonWidth | Number | Minimum width of all dialog buttons | 75 | textbox (inc/dec) |
minHeight | Number | The minimum allowable height for a resizable dialog | 80 | textbox (inc/dec) |
minWidth | Number | The minimum allowable width for a resizable dialog | 200 | textbox (inc/dec) |
modal | Boolean | True to show the dialog modally, preventing user interaction with the rest of the page | false | checkbox |
proxyDrag | Boolean | True to drag a lightweight proxy element rather than the dialog itself, used when draggable = true | false | checkbox |
resizable | Boolean | False to disable manual dialog resizing | true | checkbox |
resizeHandles | String | Which resize handles to display - see the Ext.Resizable handles config property for valid values | 'all' | combobox? |
shadow | Boolean/String | True or “sides” for the default effect, “frame” for 4-way shadow, and “drop” for bottom-right shadow | false | checkbox |
shadowOffset | Number | The number of pixels to offset the shadow if displayed | 5 | textbox (inc/dec) |
shim | Boolean | True to create an iframe shim that prevents selects from showing through | false | checkbox |
syncHeightBeforeShow | Boolean | True to cause the dimensions to be recalculated before the dialog is shown | false | checkbox |
tabTag | String | The tag name of tab elements, used when autoTabs = true | 'div' | combobox (html tags) |
title | String | Default text to display in the title bar | null | textbox |
width | Number | Width of the dialog in pixels (can also be set via CSS). | Determined by browser | textbox (inc/dec) |
x | Number | The default left page coordinate of the dialog | center screen | textbox (inc/dec) |
y | Number | The default top page coordinate of the dialog | center screen | textbox (inc/dec) |
Code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Ext configurator</title> <link rel="stylesheet" type="text/css" href="../ext-1.1-beta2/resources/css/ext-all.css" /> <script type="text/javascript" src="../ext-1.1-beta2/adapter/yui/yui-utilities.js"></script> <script type="text/javascript" src="../ext-1.1-beta2/adapter/yui/ext-yui-adapter.js"></script> <script type="text/javascript" src="../ext-1.1-beta2/ext-all.js"></script> <script> Ext.onReady(function(){ var widgetName = 'BasicDialog'; var container = 'container'; var widgetData = { BasicDialog : { options: [ // options should be in the order specified for the @cfg tags in the source {'name': 'title', 'type': 'String', 'default': ''}, {'name': 'width', 'type': 'Number', 'default': 'browser dependent'}, {'name': 'height', 'type': 'Number', 'default': 'browser dependent'}, {'name': 'modal', 'type': 'Boolean', 'default': false} ], renderMethod: 'show' } }; function create(widgetName){ // gather form data, build config object config = form.getValues(); // checkboxes "on" are ok? console.dir(config); // invoke widget constructor var widgetInstance = new Ext[widgetName](container, config); // render method if needed (can be passed as a parameter) widgetInstance.show(); }; var form = new Ext.form.Form(); var options = widgetData[widgetName].options; for (var i=0, len=options.length; i < len; i++){ switch(options[i].type) { case 'String': case 'Number': form.add( new Ext.form.TextField({ fieldLabel: options[i].name, name: options[i].name, width: 175 }) ); break; case 'Boolean': form.add( new Ext.form.Checkbox({ name: options[i].name, boxLabel: options[i].name, checked: options[i]['default'] === true, value: true }) ); break; default: console.log('unknown type'); } } form.addButton('Create',function(){create(widgetName)}); form.addButton('Reset', function(){this.reset()}, form); form.render('my-form'); }); </script> </head> <body> <div id="my-form"></div> <div id="container"></div> </body> </html>
extjs