Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / examples / forum / forum.js
index 7947c78..e56c854 100644 (file)
-/*\r
- * Ext JS Library 2.2.1\r
- * Copyright(c) 2006-2009, Ext JS, LLC.\r
- * licensing@extjs.com\r
- * \r
- * http://extjs.com/license\r
- */\r
-\r
-var Forum = {};\r
-\r
-//////////////////////////////////////////////////////////////////////////////////////////////\r
-// The data store for topics\r
-Forum.TopicStore = function(){\r
-    Forum.TopicStore.superclass.constructor.call(this, {\r
-        remoteSort: true,\r
-\r
-        proxy: new Ext.data.ScriptTagProxy({\r
-            url: 'http://extjs.com/forum/topics-browse-remote.php'\r
-        }),\r
-\r
-        reader: new Ext.data.JsonReader({\r
-            root: 'topics',\r
-            totalProperty: 'totalCount',\r
-            id: 'threadid'\r
-        }, [\r
-            'title', 'forumtitle', 'forumid', 'author',\r
-            {name: 'replycount', type: 'int'},\r
-            {name: 'lastpost', mapping: 'lastpost', type: 'date', dateFormat: 'timestamp'},\r
-            'lastposter', 'excerpt'\r
-        ])\r
-    });\r
-\r
-    this.setDefaultSort('lastpost', 'desc');\r
-};\r
-Ext.extend(Forum.TopicStore, Ext.data.Store, {\r
-    loadForum : function(forumId){\r
-        this.baseParams = {\r
-            forumId: forumId\r
-        };\r
-        this.load({\r
-            params: {\r
-                start:0,\r
-                limit:25\r
-            }\r
-        });\r
-    }\r
-});\r
-\r
-//////////////////////////////////////////////////////////////////////////////////////////////\r
-\r
-// some renderers\r
-Forum.Renderers = {\r
-    topic : function(value, p, record){\r
-        return String.format(\r
-                '<div class="topic"><b>{0}</b><span class="author">{1}</span></div>',\r
-                value, record.data.author, record.id, record.data.forumid);\r
-    },\r
-\r
-    lastPost : function(value, p, r){\r
-        return String.format('<span class="post-date">{0}</span><br/>by {1}', value.dateFormat('M j, Y, g:i a'), r.data['lastposter']);\r
-    }\r
-};\r
-\r
-//////////////////////////////////////////////////////////////////////////////////////////////\r
-\r
-Forum.SearchView = function(search){\r
-\r
-    this.preview = new Ext.Panel({\r
-        region:'south',\r
-        height:250,\r
-        title:'View Message',\r
-        split:true\r
-    });\r
-\r
-    this.store = new Ext.data.Store({\r
-        remoteSort: true,\r
-        proxy: new Ext.data.ScriptTagProxy({\r
-            url: 'http://extjs.com/forum/topics-remote.php'\r
-        }),\r
-        reader: new Ext.data.JsonReader({\r
-            root: 'topics',\r
-            totalProperty: 'totalCount',\r
-            id: 'post_id'\r
-        }, [\r
-            {name: 'postId', mapping: 'post_id'},\r
-            {name: 'title', mapping: 'topic_title'},\r
-            {name: 'topicId', mapping: 'topic_id'},\r
-            {name: 'author', mapping: 'author'},\r
-            {name: 'lastPost', mapping: 'post_time', type: 'date', dateFormat: 'timestamp'},\r
-            {name: 'excerpt', mapping: 'post_text'}\r
-        ])\r
-    });\r
-    this.store.setDefaultSort('lastpost', 'desc');\r
-\r
-\r
-    this.grid = new Ext.grid.GridPanel({\r
-        region:'center',\r
-\r
-        store: this.store,\r
-\r
-        cm: new Ext.grid.ColumnModel([{\r
-           id: 'topic',\r
-           header: "Post Title",\r
-           dataIndex: 'title',\r
-           width: 420,\r
-           renderer: Forum.Renderers.topic\r
-        },{\r
-           id: 'last',\r
-           header: "Date Posted",\r
-           dataIndex: 'lastpost',\r
-           width: 150,\r
-           renderer: Ext.util.Format.dateRenderer('M j, Y, g:i a')\r
-        }]),\r
-\r
-        sm: new Ext.grid.RowSelectionModel({\r
-            singleSelect:true\r
-        }),\r
-\r
-        trackMouseOver:false,\r
-\r
-        loadMask: {msg:'Searching...'},\r
-\r
-        viewConfig: {\r
-            forceFit:true,\r
-            enableRowBody:true,\r
-            showPreview:true,\r
-            getRowClass : function(record, rowIndex, p, ds){\r
-                if(this.showPreview){\r
-                    p.body = '<p>'+record.data.excerpt+'</p>';\r
-                    return 'x-grid3-row-expanded';\r
-                }\r
-                return 'x-grid3-row-collapsed';\r
-            }\r
-        },\r
-\r
-        bbar: new Ext.PagingToolbar({\r
-            pageSize: 25,\r
-            store: ds,\r
-            displayInfo: true,\r
-            displayMsg: 'Displaying results {0} - {1} of {2}',\r
-            emptyMsg: "No results to display"\r
-        })\r
-    });\r
-\r
-    Forum.SearchView.superclass.constructor.call(this, {\r
-        layout:'border',\r
-        title:'Search: '+Ext.util.Format.htmlEncode('"'+search+'"'),\r
-        items:[ this.grid, this.preview ]\r
-     });\r
-\r
-    this.store.baseParams = {\r
-        query: search\r
-    };\r
-\r
-    this.store.load({params:{start:0, limit: 25}});\r
-};\r
-\r
-Ext.extend(Forum.SearchView, Ext.Panel);\r
-\r
-\r
-\r
-Ext.onReady(function(){\r
-\r
-    Ext.QuickTips.init();\r
-\r
-    var ds = new Forum.TopicStore();\r
-\r
-    var cm = new Ext.grid.ColumnModel([{\r
-           id: 'topic',\r
-           header: "Topic",\r
-           dataIndex: 'title',\r
-           width: 420,\r
-           renderer: Forum.Renderers.topic\r
-        },{\r
-           header: "Author",\r
-           dataIndex: 'author',\r
-           width: 100,\r
-           hidden: true\r
-        },{\r
-           header: "Replies",\r
-           dataIndex: 'replycount',\r
-           width: 70,\r
-           align: 'right'\r
-        },{\r
-           id: 'last',\r
-           header: "Last Post",\r
-           dataIndex: 'lastpost',\r
-           width: 150,\r
-           renderer: Forum.Renderers.lastPost\r
-        }]);\r
-\r
-    cm.defaultSortable = true;\r
-\r
-    var viewport = new Ext.Viewport({\r
-        layout:'border',\r
-        items:[\r
-            new Ext.BoxComponent({ // raw\r
-                region:'north',\r
-                el: 'header',\r
-                height:32\r
-            }),\r
-            new Ext.tree.TreePanel({\r
-                id:'forum-tree',\r
-                region:'west',\r
-                title:'Forums',\r
-                split:true,\r
-                width: 225,\r
-                minSize: 175,\r
-                maxSize: 400,\r
-                collapsible: true,\r
-                margins:'0 0 5 5',\r
-                loader: new Forum.TreeLoader(),\r
-                rootVisible:false,\r
-                lines:false,\r
-                autoScroll:true,\r
-                root: new Ext.tree.AsyncTreeNode({\r
-                          text: 'Forums',\r
-                          expanded:true\r
-                      })\r
-            }),\r
-            new Ext.TabPanel({\r
-                id:'main-tabs',\r
-                activeTab:0,\r
-                region:'center',\r
-                margins:'0 5 5 0',\r
-                resizeTabs:true,\r
-                tabWidth:150,\r
-                items: {\r
-                    id:'main-view',\r
-                    layout:'border',\r
-                    title:'Loading...',\r
-                    items:[\r
-                        new Ext.grid.GridPanel({\r
-                            region:'center',\r
-                            id:'topic-grid',\r
-                            store: ds,\r
-                            cm: cm,\r
-                            sm:new Ext.grid.RowSelectionModel({singleSelect:true}),\r
-                            trackMouseOver:false,\r
-                            loadMask: {msg:'Loading Topics...'},\r
-                            viewConfig: {\r
-                                forceFit:true,\r
-                                enableRowBody:true,\r
-                                showPreview:true,\r
-                                getRowClass : function(record, rowIndex, p, ds){\r
-                                    if(this.showPreview){\r
-                                        p.body = '<p>'+record.data.excerpt+'</p>';\r
-                                        return 'x-grid3-row-expanded';\r
-                                    }\r
-                                    return 'x-grid3-row-collapsed';\r
-                                }\r
-                            },\r
-                            tbar:[\r
-                                {\r
-                                    text:'New Topic',\r
-                                    iconCls: 'new-topic',\r
-                                    handler:function(){alert('Not implemented.');}\r
-                                },\r
-                                '-',\r
-                                {\r
-                                    pressed: true,\r
-                                    enableToggle:true,\r
-                                    text:'Preview Pane',\r
-                                    tooltip: {title:'Preview Pane',text:'Show or hide the Preview Pane'},\r
-                                    iconCls: 'preview',\r
-                                    toggleHandler: togglePreview\r
-                                },\r
-                                ' ',\r
-                                {\r
-                                    pressed: true,\r
-                                    enableToggle:true,\r
-                                    text:'Summary',\r
-                                    tooltip: {title:'Post Summary',text:'View a short summary of each post in the list'},\r
-                                    iconCls: 'summary',\r
-                                    toggleHandler: toggleDetails\r
-                                }\r
-                            ],\r
-                            bbar: new Ext.PagingToolbar({\r
-                                pageSize: 25,\r
-                                store: ds,\r
-                                displayInfo: true,\r
-                                displayMsg: 'Displaying topics {0} - {1} of {2}',\r
-                                emptyMsg: "No topics to display"\r
-                            })\r
-                        }), {\r
-                            id:'preview',\r
-                            region:'south',\r
-                            height:250,\r
-                            title:'View Topic',\r
-                            split:true\r
-                        }\r
-                     ]\r
-                 }\r
-              })\r
-         ]\r
-    });\r
-\r
-    var tree = Ext.getCmp('forum-tree');\r
-    tree.on('append', function(tree, p, node){\r
-       if(node.id == 5){\r
-           node.select.defer(100, node);\r
-       }\r
-    });\r
-    var sm = tree.getSelectionModel();\r
-    sm.on('beforeselect', function(sm, node){\r
-         return node.isLeaf();\r
-    });\r
-    sm.on('selectionchange', function(sm, node){\r
-        ds.loadForum(node.id);\r
-        Ext.getCmp('main-view').setTitle(node.text);\r
-    });\r
-\r
-\r
-     var searchStore = new Ext.data.Store({\r
-        proxy: new Ext.data.ScriptTagProxy({\r
-            url: 'http://extjs.com/forum/topics-remote.php'\r
-        }),\r
-        reader: new Ext.data.JsonReader({\r
-            root: 'topics',\r
-            totalProperty: 'totalCount',\r
-            id: 'post_id'\r
-        }, [\r
-            {name: 'title', mapping: 'topic_title'},\r
-            {name: 'topicId', mapping: 'topic_id'},\r
-            {name: 'author', mapping: 'author'},\r
-            {name: 'lastPost', mapping: 'post_time', type: 'date', dateFormat: 'timestamp'},\r
-            {name: 'excerpt', mapping: 'post_text'}\r
-        ])\r
-    });\r
-\r
-    // Custom rendering Template\r
-    var resultTpl = new Ext.Template(\r
-        '<div class="search-item">',\r
-            '<h3><span>{lastPost:date("M j, Y")}<br />by {author}</span>{title}</h3>',\r
-            '{excerpt}',\r
-        '</div>'\r
-    );\r
-\r
-    var search = new Ext.form.ComboBox({\r
-        store: searchStore,\r
-        displayField:'title',\r
-        typeAhead: false,\r
-        loadingText: 'Searching...',\r
-        width: 200,\r
-        pageSize:10,\r
-        listWidth:550,\r
-        hideTrigger:true,\r
-        tpl: resultTpl,\r
-        minChars:3,\r
-        emptyText:'Quick Search',\r
-        onSelect: function(record){ // override default onSelect to do redirect\r
-            window.location =\r
-                String.format('http://extjs.com/forum/showthread.php?t={0}&p={1}', record.data.topicId, record.id);\r
-        }\r
-    });\r
-    // apply it to the exsting input element\r
-    search.applyTo('search');\r
-\r
-\r
-\r
-    function toggleDetails(btn, pressed){\r
-        var view = Ext.getCmp('topic-grid').getView();\r
-        view.showPreview = pressed;\r
-        view.refresh();\r
-    }\r
-\r
-    function togglePreview(btn, pressed){\r
-        var preview = Ext.getCmp('preview');\r
-        preview[pressed ? 'show' : 'hide']();\r
-        preview.ownerCt.doLayout();\r
-    }\r
-});\r
-\r
-Forum.TreeLoader = function(){\r
-    Forum.TreeLoader.superclass.constructor.call(this);\r
-    this.proxy = new Ext.data.ScriptTagProxy({\r
-        url : this.dataUrl\r
-    });\r
-};\r
-Ext.extend(Forum.TreeLoader, Ext.tree.TreeLoader, {\r
-    dataUrl: 'http://extjs.com/forum/forums-remote.php',\r
-    requestData : function(node, cb){\r
-        this.proxy.load({}, {\r
-            readRecords : function(o){\r
-                return o;\r
-            }\r
-        }, this.addNodes, this, {node:node, cb:cb});\r
-    },\r
-\r
-    addNodes : function(o, arg){\r
-        var node = arg.node;\r
-        for(var i = 0, len = o.length; i < len; i++){\r
-            var n = this.createNode(o[i]);\r
-            if(n){\r
-                node.appendChild(n);\r
-            }\r
-        }\r
-        arg.cb(this, node);\r
-    }\r
-});\r
+/*!
+ * Ext JS Library 3.0.0
+ * Copyright(c) 2006-2009 Ext JS, LLC
+ * licensing@extjs.com
+ * http://www.extjs.com/license
+ */
+var Forum = {};
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+// The data store for topics
+Forum.TopicStore = function(){
+    Forum.TopicStore.superclass.constructor.call(this, {
+        remoteSort: true,
+
+        proxy: new Ext.data.ScriptTagProxy({
+            url: 'http://extjs.com/forum/topics-browse-remote.php'
+        }),
+
+        reader: new Ext.data.JsonReader({
+            root: 'topics',
+            totalProperty: 'totalCount',
+            id: 'threadid'
+        }, [
+            'title', 'forumtitle', 'forumid', 'author',
+            {name: 'replycount', type: 'int'},
+            {name: 'lastpost', mapping: 'lastpost', type: 'date', dateFormat: 'timestamp'},
+            'lastposter', 'excerpt'
+        ])
+    });
+
+    this.setDefaultSort('lastpost', 'desc');
+};
+Ext.extend(Forum.TopicStore, Ext.data.Store, {
+    loadForum : function(forumId){
+        this.baseParams = {
+            forumId: forumId
+        };
+        this.load({
+            params: {
+                start:0,
+                limit:25
+            }
+        });
+    }
+});
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+// some renderers
+Forum.Renderers = {
+    topic : function(value, p, record){
+        return String.format(
+                '<div class="topic"><b>{0}</b><span class="author">{1}</span></div>',
+                value, record.data.author, record.id, record.data.forumid);
+    },
+
+    lastPost : function(value, p, r){
+        return String.format('<span class="post-date">{0}</span><br/>by {1}', value.dateFormat('M j, Y, g:i a'), r.data['lastposter']);
+    }
+};
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+Forum.SearchView = function(search){
+
+    this.preview = new Ext.Panel({
+        region:'south',
+        height:250,
+        title:'View Message',
+        split:true
+    });
+
+    this.store = new Ext.data.Store({
+        remoteSort: true,
+        proxy: new Ext.data.ScriptTagProxy({
+            url: 'http://extjs.com/forum/topics-browse-remote.php'
+        }),
+        reader: new Ext.data.JsonReader({
+            root: 'topics',
+            totalProperty: 'totalCount',
+            id: 'post_id'
+        }, [
+            {name: 'postId', mapping: 'post_id'},
+            {name: 'title', mapping: 'topic_title'},
+            {name: 'topicId', mapping: 'topic_id'},
+            {name: 'author', mapping: 'author'},
+            {name: 'lastPost', mapping: 'post_time', type: 'date', dateFormat: 'timestamp'},
+            {name: 'excerpt', mapping: 'post_text'}
+        ])
+    });
+    this.store.setDefaultSort('lastpost', 'desc');
+
+
+    this.grid = new Ext.grid.GridPanel({
+        region:'center',
+
+        store: this.store,
+
+        cm: new Ext.grid.ColumnModel([{
+           id: 'topic',
+           header: "Post Title",
+           dataIndex: 'title',
+           width: 420,
+           renderer: Forum.Renderers.topic
+        },{
+           id: 'last',
+           header: "Date Posted",
+           dataIndex: 'lastpost',
+           width: 150,
+           renderer: Ext.util.Format.dateRenderer('M j, Y, g:i a')
+        }]),
+
+        sm: new Ext.grid.RowSelectionModel({
+            singleSelect:true
+        }),
+
+        trackMouseOver:false,
+
+        loadMask: {msg:'Searching...'},
+
+        viewConfig: {
+            forceFit:true,
+            enableRowBody:true,
+            showPreview:true,
+            getRowClass : function(record, rowIndex, p, ds){
+                if(this.showPreview){
+                    p.body = '<p>'+record.data.excerpt+'</p>';
+                    return 'x-grid3-row-expanded';
+                }
+                return 'x-grid3-row-collapsed';
+            }
+        },
+
+        bbar: new Ext.PagingToolbar({
+            pageSize: 25,
+            store: ds,
+            displayInfo: true,
+            displayMsg: 'Displaying results {0} - {1} of {2}',
+            emptyMsg: "No results to display"
+        })
+    });
+
+    Forum.SearchView.superclass.constructor.call(this, {
+        layout:'border',
+        title:'Search: '+Ext.util.Format.htmlEncode('"'+search+'"'),
+        items:[ this.grid, this.preview ]
+     });
+
+    this.store.baseParams = {
+        query: search
+    };
+
+    this.store.load({params:{start:0, limit: 25}});
+};
+
+Ext.extend(Forum.SearchView, Ext.Panel);
+
+
+
+Ext.onReady(function(){
+
+    Ext.QuickTips.init();
+
+    var ds = new Forum.TopicStore();
+
+    var cm = new Ext.grid.ColumnModel([{
+           id: 'topic',
+           header: "Topic",
+           dataIndex: 'title',
+           width: 420,
+           renderer: Forum.Renderers.topic
+        },{
+           header: "Author",
+           dataIndex: 'author',
+           width: 100,
+           hidden: true
+        },{
+           header: "Replies",
+           dataIndex: 'replycount',
+           width: 70,
+           align: 'right'
+        },{
+           id: 'last',
+           header: "Last Post",
+           dataIndex: 'lastpost',
+           width: 150,
+           renderer: Forum.Renderers.lastPost
+        }]);
+
+    cm.defaultSortable = true;
+
+    var viewport = new Ext.Viewport({
+        layout:'border',
+        items:[
+            new Ext.BoxComponent({ // raw
+                region:'north',
+                el: 'header',
+                height:32
+            }),
+            new Ext.tree.TreePanel({
+                id:'forum-tree',
+                region:'west',
+                title:'Forums',
+                split:true,
+                width: 325,
+                minSize: 175,
+                maxSize: 400,
+                collapsible: true,
+                margins:'0 0 5 5',
+                loader: new Forum.TreeLoader(),
+                rootVisible:false,
+                lines:false,
+                autoScroll:true,
+                root: new Ext.tree.AsyncTreeNode({
+                          text: 'Forums',
+                          expanded:true
+                      })
+            }),
+            new Ext.TabPanel({
+                id:'main-tabs',
+                activeTab:0,
+                region:'center',
+                margins:'0 5 5 0',
+                resizeTabs:true,
+                tabWidth:150,
+                items: {
+                    id:'main-view',
+                    layout:'border',
+                    title:'Loading...',
+                    items:[
+                        new Ext.grid.GridPanel({
+                            region:'center',
+                            id:'topic-grid',
+                            store: ds,
+                            cm: cm,
+                            sm:new Ext.grid.RowSelectionModel({
+                                singleSelect:true,
+                                listeners: {
+                                    selectionchange: function(sel){
+                                        var rec = sel.getSelected();
+                                        if(rec){
+                                            Ext.getCmp('preview').body.update('<b><u>' + rec.get('title') + '</u></b><br /><br />Post details here.');
+                                        }
+                                    }
+                                }
+                            }),
+                            trackMouseOver:false,
+                            loadMask: {msg:'Loading Topics...'},
+                            viewConfig: {
+                                forceFit:true,
+                                enableRowBody:true,
+                                showPreview:true,
+                                getRowClass : function(record, rowIndex, p, ds){
+                                    if(this.showPreview){
+                                        p.body = '<p>'+record.data.excerpt+'</p>';
+                                        return 'x-grid3-row-expanded';
+                                    }
+                                    return 'x-grid3-row-collapsed';
+                                }
+                            },
+                            tbar:[
+                                {
+                                    text:'New Topic',
+                                    iconCls: 'new-topic',
+                                    handler:function(){alert('Not implemented.');}
+                                },
+                                '-',
+                                {
+                                    pressed: true,
+                                    enableToggle:true,
+                                    text:'Preview Pane',
+                                    tooltip: {title:'Preview Pane',text:'Show or hide the Preview Pane'},
+                                    iconCls: 'preview',
+                                    toggleHandler: togglePreview
+                                },
+                                ' ',
+                                {
+                                    pressed: true,
+                                    enableToggle:true,
+                                    text:'Summary',
+                                    tooltip: {title:'Post Summary',text:'View a short summary of each post in the list'},
+                                    iconCls: 'summary',
+                                    toggleHandler: toggleDetails
+                                }
+                            ],
+                            bbar: new Ext.PagingToolbar({
+                                pageSize: 25,
+                                store: ds,
+                                displayInfo: true,
+                                displayMsg: 'Displaying topics {0} - {1} of {2}',
+                                emptyMsg: "No topics to display"
+                            })
+                        }), {
+                            id:'preview',
+                            region:'south',
+                            height:250,
+                            title:'View Topic',
+                            split:true,
+                            bodyStyle: 'padding: 10px; font-family: Arial; font-size: 12px;'
+                        }
+                     ]
+                 }
+              })
+         ]
+    });
+
+    var tree = Ext.getCmp('forum-tree');
+    tree.on('append', function(tree, p, node){
+       if(node.id == 40){
+           node.select.defer(100, node);
+       }
+    });
+    var sm = tree.getSelectionModel();
+    sm.on('beforeselect', function(sm, node){
+         return node.isLeaf();
+    });
+    sm.on('selectionchange', function(sm, node){
+        ds.loadForum(node.id);
+        Ext.getCmp('main-view').setTitle(node.text);
+    });
+
+
+     var searchStore = new Ext.data.Store({
+        proxy: new Ext.data.ScriptTagProxy({
+            url: 'http://extjs.com/forum/topics-browse-remote.php'
+        }),
+        reader: new Ext.data.JsonReader({
+            root: 'topics',
+            totalProperty: 'totalCount',
+            id: 'threadid'
+        }, [
+            'title', 'author',
+            {name: 'lastpost', type: 'date', dateFormat: 'timestamp'}
+        ])
+    });
+
+    // Custom rendering Template
+    var resultTpl = new Ext.XTemplate(
+        '<tpl for=".">',
+            '<div class="x-combo-list-item search-item">{title} by <b>{author}</b></div>',
+        '</tpl>'
+    );
+
+    var search = new Ext.form.ComboBox({
+        store: searchStore,
+        applyTo: 'search',
+        displayField:'title',
+        typeAhead: false,
+        loadingText: 'Searching...',
+        width: 200,
+        pageSize:10,
+        listWidth:550,
+        hideTrigger:true,
+        tpl: resultTpl,
+        minChars:3,
+        emptyText:'Quick Search',
+        onSelect: function(record){ // override default onSelect to do redirect
+            window.location =
+                String.format('http://extjs.com/forum/showthread.php?t={0}&p={1}', record.data.topicId, record.id);
+        }
+    });
+    // apply it to the exsting input element
+    //search.applyTo('search');
+
+
+
+    function toggleDetails(btn, pressed){
+        var view = Ext.getCmp('topic-grid').getView();
+        view.showPreview = pressed;
+        view.refresh();
+    }
+
+    function togglePreview(btn, pressed){
+        var preview = Ext.getCmp('preview');
+        preview[pressed ? 'show' : 'hide']();
+        preview.ownerCt.doLayout();
+    }
+});
+
+Forum.TreeLoader = function(){
+    Forum.TreeLoader.superclass.constructor.call(this);
+    this.proxy = new Ext.data.ScriptTagProxy({
+        url : this.dataUrl
+    });
+};
+Ext.extend(Forum.TreeLoader, Ext.tree.TreeLoader, {
+    dataUrl: 'http://extjs.com/forum/forums-remote.php',
+    requestData : function(node, cb){
+        this.proxy.request('read', null, {}, {
+            readRecords : function(o){
+                return o;
+            }
+        }, this.addNodes, this, {node:node, cb:cb});
+    },
+
+    addNodes : function(o, arg){
+        var node = arg.node;
+        for(var i = 0, len = o.length; i < len; i++){
+            var n = this.createNode(o[i]);
+            if(n){
+                node.appendChild(n);
+            }
+        }
+        arg.cb(this, node);
+    }
+});