New Example – Combo with Remote Store
3. April 2009 – 13:58Hi,
I’ve just uploaded a full-fledged example of combo with remote store at http://examples.extjs.eu.
Enjoy!
For good of all productive developers
Hi,
I’ve just uploaded a full-fledged example of combo with remote store at http://examples.extjs.eu.
Enjoy!
You know, I’m not very big fan of factory functions, nevertheless, I’m aware of the fact that they may be necessary in some situations. Here is the file pattern that works (briefly tested).
Keep each factory function in a separate file name of which should be Namespace.Factory.functionName.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | // vim: ts=4:sw=4:nu:fdc=4:nospell /*global Ext, MyNamespace */ /** * @class MyNamespace.Factory * * A Factory function pattern * * @author Ing. Jozef Sakáloš * @copyright (c) 2009, by Ing. Jozef Sakáloš * @date 17. March 2009 * @version 0.1 * @revision $Id$ * * @license MyNamespace.Factory.myPanel.js is licensed under the terms of * the Open Source LGPL 3.0 license. Commercial use is permitted to the extent * that the code/component(s) do NOT become part of another Open Source or * Commercially licensed development library or toolkit * without explicit permission. * * <p>License details: <a href="http://www.gnu.org/licenses/lgpl.html" * target="_blank">http://www.gnu.org/licenses/lgpl.html</a></p> */ // create namespace Ext.ns('MyNamespace.Factory'); /** * @method myPanel * @param {Object} config * A config object * @return {Ext.Panel} */ MyNamespace.Factory.myPanel = function(config) { // pre-instantiation code var defaults = { // put your defaults here // but avoid id, el, contentEl, renderTo, applyTo, or similar }; // eo defaults object // create config object var cfg = Ext.apply({}, config, defaults); // instantiate var cmp = new Ext.Panel(cfg); // post-instantiation code // return the created component return cmp; } // eo function MyNamespace.Factory.myPanel // eof |
If you have not already done so, study Writing a Big Application in Ext (Part 1) and Writing a Big Application in Ext (Part 2)before you read this article. It would be very hard, if not impossible, to understand concepts explained here before you fully understand the first and second part.
Helping on the forum and reading code of others that failed to extend Ext classes, revealed more errors that users, especially beginners, commonly make. Therefore, I’ve decided to start this article that will collect these errors and will explain why the errors are errors. I mean it as loosely ended as I may discover more errors and ways of avoiding them so I plan just to add them to this article, not endlessly create parts 4, 5, etc…
Here we go:
The main reasons for extending are:
so we extend if we need a re-usable component or we need to add a functionality (new methods) or both. If we are after re-usability the extension can be as simple as:
1 2 3 4 5 | MyPortlet = Ext.extend(Ext.Panel, { anchor:'100%' ,draggable:true ,defaultType:'mygraph' }); |
You see what happens? We are going to use MyPortlet many times so instead of scatter the above configuration in 10,000 lines application code 100 times, we create this simple extension and we save 297 lines of code.
The other aspect is that if we upgrade our ‘mygraph’ to ‘mygraph_new’ the only place where to change it is our extension saving us searching out code for all occurrences of ‘mygraph’ (100 times) and replacing it with ‘mygraph_new’ 100 times.
(Well, 100 is exaggerated, but you get the point, right?)
If we are after adding functionality, which can be also simple, we add some “logic”:
1 2 3 4 5 6 | MyPanel = Ext.extend(Ext.Panel, { onRender:function() { MyPanel.superclass.onRender.apply(this, arguments); alert('Rendered'); } }); |
Here we add some logic to Panel, it does more that it did before.
There is no need to extend in all other cases.
Run this code first:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css"> <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="ext/ext-all-debug.js"></script> <title id="page-title">Extending Error: Object in prototype</title> <script type="text/javascript"> Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif'; Ext.onReady(function() { MyPanel = Ext.extend(Ext.Panel, { layout:'fit' ,panelConfig: { bodyBg:'red' } ,initComponent:function() { var config = { bodyStyle:'background-color:' + this.panelConfig.bodyBg }; // eo config object // apply config Ext.apply(this, Ext.apply(this.initialConfig, config)); MyPanel.superclass.initComponent.apply(this, arguments); } // eo function initComponent ,applyBackground:function(color) { this.panelConfig.bodyBg = color; this.body.applyStyles({'background-color':color}); } // eo function applyBackground }); // eo extend var p1 = new MyPanel({ title:'Panel with Blue Background' ,renderTo:Ext.getBody() ,width:240 ,height:160 }); p1.applyBackground('blue'); var p2 = new MyPanel({ title:'Panel with Red Background' ,renderTo:Ext.getBody() ,width:240 ,height:160 }); }); </script> </head> <body></body> </html>
What do we expect? It is written in titles of panels: Top panel (p1) should have blue body background because we set it to it after it is created. And bottom panel (p2) should have red because we just create default MyPanel.
But it is blue too!!! Why? The reason is simple: panelConfig is object that is created during class definition and it is added to MyPanel prototype. Objects (arrays too) are accessed by reference so p1 and p2 share the same instance of panelConfig. Setting bodyBg property in applyBackground method changes this single instance of panelConfig object. So we create p2 with blue background too.
You see, here it is clearly and immediately visible that something went wrong but making this error can lead to weeks of wasted debugging time in real applications. Imagine you have a store in prototype…
Very simple, but deadly mistake is to set ids in the extension either to the main extension object or on its items, toolbars, buttons, etc. If a hard coded ids are set we cannot create two or more instances of our extension, can we?
That’s all for now but if I discover more errors I will add them above.
Stay tuned!
Do not forget to read Part 1 and Part 2 of this article.
Follow up: Factory Functions in Ext Extensions (Abstract Classes)
This example shows how to easily add tabs to a TabPanel without any layout issues of the newly added tab.
Enjoy!
Suppose we want to remove all children of the node node:
while(node.firstChild) { node.removeChild(node.firstChild); }
That’s all there is to it
Hi,
I’ve just uploaded the complex example of data binding of grid record to another two components.
Enjoy!
Hi,
I’ve just uploaded the example of dragging from a tree and dropping on a div.
Enjoy!
Hi,
I’ve just uploaded the example of populating a combo with data loaded from server on form load.
Enjoy!
Hi all,
I’ve just posted new example at http://examples.extjs.eu
This example shows how to setup dragging of items within a container to reposition them.
Items positions are saved using Ext state management and CookieProvider.
The example also shows:
Enjoy!
Hi all,
I’ve just uploaded new example, Handling Item Clicks, that shows how to handle clicks on items contained in a container in one event handler with possibility to disable items and thus ignore click on them.
Enjoy!