Upgrade to ExtJS 3.1.0 - Released 12/16/2009
[extjs.git] / src / widgets / layout / CardLayout.js
1 /*!
2  * Ext JS Library 3.1.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**\r
8  * @class Ext.layout.CardLayout\r
9  * @extends Ext.layout.FitLayout\r
10  * <p>This layout manages multiple child Components, each fitted to the Container, where only a single child Component can be\r
11  * visible at any given time.  This layout style is most commonly used for wizards, tab implementations, etc.\r
12  * This class is intended to be extended or created via the layout:'card' {@link Ext.Container#layout} config,\r
13  * and should generally not need to be created directly via the new keyword.</p>\r
14  * <p>The CardLayout's focal method is {@link #setActiveItem}.  Since only one panel is displayed at a time,\r
15  * the only way to move from one Component to the next is by calling setActiveItem, passing the id or index of\r
16  * the next panel to display.  The layout itself does not provide a user interface for handling this navigation,\r
17  * so that functionality must be provided by the developer.</p>\r
18  * <p>In the following example, a simplistic wizard setup is demonstrated.  A button bar is added\r
19  * to the footer of the containing panel to provide navigation buttons.  The buttons will be handled by a\r
20  * common navigation routine -- for this example, the implementation of that routine has been ommitted since\r
21  * it can be any type of custom logic.  Note that other uses of a CardLayout (like a tab control) would require a\r
22  * completely different implementation.  For serious implementations, a better approach would be to extend\r
23  * CardLayout to provide the custom functionality needed.  Example usage:</p>\r
24  * <pre><code>\r
25 var navHandler = function(direction){\r
26     // This routine could contain business logic required to manage the navigation steps.\r
27     // It would call setActiveItem as needed, manage navigation button state, handle any\r
28     // branching logic that might be required, handle alternate actions like cancellation\r
29     // or finalization, etc.  A complete wizard implementation could get pretty\r
30     // sophisticated depending on the complexity required, and should probably be\r
31     // done as a subclass of CardLayout in a real-world implementation.\r
32 };\r
33 \r
34 var card = new Ext.Panel({\r
35     title: 'Example Wizard',\r
36     layout:'card',\r
37     activeItem: 0, // make sure the active item is set on the container config!\r
38     bodyStyle: 'padding:15px',\r
39     defaults: {\r
40         // applied to each contained panel\r
41         border:false\r
42     },\r
43     // just an example of one possible navigation scheme, using buttons\r
44     bbar: [\r
45         {\r
46             id: 'move-prev',\r
47             text: 'Back',\r
48             handler: navHandler.createDelegate(this, [-1]),\r
49             disabled: true\r
50         },\r
51         '->', // greedy spacer so that the buttons are aligned to each side\r
52         {\r
53             id: 'move-next',\r
54             text: 'Next',\r
55             handler: navHandler.createDelegate(this, [1])\r
56         }\r
57     ],\r
58     // the panels (or "cards") within the layout\r
59     items: [{\r
60         id: 'card-0',\r
61         html: '&lt;h1&gt;Welcome to the Wizard!&lt;/h1&gt;&lt;p&gt;Step 1 of 3&lt;/p&gt;'\r
62     },{\r
63         id: 'card-1',\r
64         html: '&lt;p&gt;Step 2 of 3&lt;/p&gt;'\r
65     },{\r
66         id: 'card-2',\r
67         html: '&lt;h1&gt;Congratulations!&lt;/h1&gt;&lt;p&gt;Step 3 of 3 - Complete&lt;/p&gt;'\r
68     }]\r
69 });\r
70 </code></pre>\r
71  */\r
72 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {\r
73     /**\r
74      * @cfg {Boolean} deferredRender\r
75      * True to render each contained item at the time it becomes active, false to render all contained items\r
76      * as soon as the layout is rendered (defaults to false).  If there is a significant amount of content or\r
77      * a lot of heavy controls being rendered into panels that are not displayed by default, setting this to\r
78      * true might improve performance.\r
79      */\r
80     deferredRender : false,\r
81     \r
82     /**\r
83      * @cfg {Boolean} layoutOnCardChange\r
84      * True to force a layout of the active item when the active card is changed. Defaults to false.\r
85      */\r
86     layoutOnCardChange : false,\r
87 \r
88     /**\r
89      * @cfg {Boolean} renderHidden @hide\r
90      */\r
91     // private\r
92     renderHidden : true,\r
93     \r
94     constructor: function(config){\r
95         Ext.layout.CardLayout.superclass.constructor.call(this, config);\r
96       //  this.forceLayout = (this.deferredRender === false);\r
97     },\r
98 \r
99     /**\r
100      * Sets the active (visible) item in the layout.\r
101      * @param {String/Number} item The string component id or numeric index of the item to activate\r
102      */\r
103     setActiveItem : function(item){\r
104         var ai = this.activeItem;\r
105         item = this.container.getComponent(item);\r
106         if(ai != item){\r
107             if(ai){\r
108                 ai.hide();\r
109                 ai.fireEvent('deactivate', ai);\r
110             }\r
111             var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);\r
112             this.activeItem = item;\r
113             if(item){\r
114                 item.show();\r
115             }\r
116             this.layout();\r
117             if(item && layout){\r
118                 item.doLayout();\r
119             }\r
120             item.fireEvent('activate', item);\r
121         }\r
122     },\r
123 \r
124     // private\r
125     renderAll : function(ct, target){\r
126         if(this.deferredRender){\r
127             this.renderItem(this.activeItem, undefined, target);\r
128         }else{\r
129             Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);\r
130         }\r
131     }\r
132 });\r
133 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;