Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / examples / forum / forum.js
1 /*!
2  * Ext JS Library 3.3.1
3  * Copyright(c) 2006-2010 Sencha Inc.
4  * licensing@sencha.com
5  * http://www.sencha.com/license
6  */
7 var Forum = {};
8
9 //////////////////////////////////////////////////////////////////////////////////////////////
10 // The data store for topics
11 Forum.TopicStore = function(){
12     Forum.TopicStore.superclass.constructor.call(this, {
13         remoteSort: true,
14
15         proxy: new Ext.data.ScriptTagProxy({
16             url: 'http://extjs.com/forum/topics-browse-remote.php'
17         }),
18
19         reader: new Ext.data.JsonReader({
20             root: 'topics',
21             totalProperty: 'totalCount',
22             id: 'threadid'
23         }, [
24             'title', 'forumtitle', 'forumid', 'author',
25             {name: 'replycount', type: 'int'},
26             {name: 'lastpost', mapping: 'lastpost', type: 'date', dateFormat: 'timestamp'},
27             'lastposter', 'excerpt'
28         ])
29     });
30
31     this.setDefaultSort('lastpost', 'desc');
32 };
33 Ext.extend(Forum.TopicStore, Ext.data.Store, {
34     loadForum : function(forumId){
35         this.baseParams = {
36             forumId: forumId
37         };
38         this.load({
39             params: {
40                 start:0,
41                 limit:25
42             }
43         });
44     }
45 });
46
47 //////////////////////////////////////////////////////////////////////////////////////////////
48
49 // some renderers
50 Forum.Renderers = {
51     topic : function(value, p, record){
52         return String.format(
53                 '<div class="topic"><b>{0}</b><span class="author">{1}</span></div>',
54                 value, record.data.author, record.id, record.data.forumid);
55     },
56
57     lastPost : function(value, p, r){
58         return String.format('<span class="post-date">{0}</span><br/>by {1}', value.dateFormat('M j, Y, g:i a'), r.data['lastposter']);
59     }
60 };
61
62 //////////////////////////////////////////////////////////////////////////////////////////////
63
64 Forum.SearchView = function(search){
65
66     this.preview = new Ext.Panel({
67         region:'south',
68         height:250,
69         title:'View Message',
70         split:true
71     });
72
73     this.store = new Ext.data.Store({
74         remoteSort: true,
75         proxy: new Ext.data.ScriptTagProxy({
76             url: 'http://extjs.com/forum/topics-browse-remote.php'
77         }),
78         reader: new Ext.data.JsonReader({
79             root: 'topics',
80             totalProperty: 'totalCount',
81             id: 'post_id'
82         }, [
83             {name: 'postId', mapping: 'post_id'},
84             {name: 'title', mapping: 'topic_title'},
85             {name: 'topicId', mapping: 'topic_id'},
86             {name: 'author', mapping: 'author'},
87             {name: 'lastPost', mapping: 'post_time', type: 'date', dateFormat: 'timestamp'},
88             {name: 'excerpt', mapping: 'post_text'}
89         ])
90     });
91     this.store.setDefaultSort('lastpost', 'desc');
92
93
94     this.grid = new Ext.grid.GridPanel({
95         region:'center',
96
97         store: this.store,
98
99         cm: new Ext.grid.ColumnModel([{
100            id: 'topic',
101            header: "Post Title",
102            dataIndex: 'title',
103            width: 420,
104            renderer: Forum.Renderers.topic
105         },{
106            id: 'last',
107            header: "Date Posted",
108            dataIndex: 'lastpost',
109            width: 150,
110            renderer: Ext.util.Format.dateRenderer('M j, Y, g:i a')
111         }]),
112
113         sm: new Ext.grid.RowSelectionModel({
114             singleSelect:true
115         }),
116
117         trackMouseOver:false,
118
119         loadMask: {msg:'Searching...'},
120
121         viewConfig: {
122             forceFit:true,
123             enableRowBody:true,
124             showPreview:true,
125             getRowClass : function(record, rowIndex, p, ds){
126                 if(this.showPreview){
127                     p.body = '<p>'+record.data.excerpt+'</p>';
128                     return 'x-grid3-row-expanded';
129                 }
130                 return 'x-grid3-row-collapsed';
131             }
132         },
133
134         bbar: new Ext.PagingToolbar({
135             pageSize: 25,
136             store: ds,
137             displayInfo: true,
138             displayMsg: 'Displaying results {0} - {1} of {2}',
139             emptyMsg: "No results to display"
140         })
141     });
142
143     Forum.SearchView.superclass.constructor.call(this, {
144         layout:'border',
145         title:'Search: '+Ext.util.Format.htmlEncode('"'+search+'"'),
146         items:[ this.grid, this.preview ]
147      });
148
149     this.store.baseParams = {
150         query: search
151     };
152
153     this.store.load({params:{start:0, limit: 25}});
154 };
155
156 Ext.extend(Forum.SearchView, Ext.Panel);
157
158
159
160 Ext.onReady(function(){
161
162     Ext.QuickTips.init();
163
164     var ds = new Forum.TopicStore();
165
166     var cm = new Ext.grid.ColumnModel([{
167            id: 'topic',
168            header: "Topic",
169            dataIndex: 'title',
170            width: 420,
171            renderer: Forum.Renderers.topic
172         },{
173            header: "Author",
174            dataIndex: 'author',
175            width: 100,
176            hidden: true
177         },{
178            header: "Replies",
179            dataIndex: 'replycount',
180            width: 70,
181            align: 'right'
182         },{
183            id: 'last',
184            header: "Last Post",
185            dataIndex: 'lastpost',
186            width: 150,
187            renderer: Forum.Renderers.lastPost
188         }]);
189
190     cm.defaultSortable = true;
191
192     var viewport = new Ext.Viewport({
193         layout:'border',
194         items:[
195             new Ext.BoxComponent({ // raw
196                 region:'north',
197                 el: 'header',
198                 height:32
199             }),
200             new Ext.tree.TreePanel({
201                 id:'forum-tree',
202                 region:'west',
203                 title:'Forums',
204                 split:true,
205                 width: 325,
206                 minSize: 175,
207                 maxSize: 400,
208                 collapsible: true,
209                 margins:'0 0 5 5',
210                 loader: new Forum.TreeLoader(),
211                 rootVisible:false,
212                 lines:false,
213                 autoScroll:true,
214                 root: new Ext.tree.AsyncTreeNode({
215                           text: 'Forums',
216                           expanded:true
217                       })
218             }),
219             new Ext.TabPanel({
220                 id:'main-tabs',
221                 activeTab:0,
222                 region:'center',
223                 margins:'0 5 5 0',
224                 resizeTabs:true,
225                 tabWidth:150,
226                 items: {
227                     id:'main-view',
228                     layout:'border',
229                     title:'Loading...',
230                     items:[
231                         new Ext.grid.GridPanel({
232                             region:'center',
233                             id:'topic-grid',
234                             store: ds,
235                             cm: cm,
236                             sm:new Ext.grid.RowSelectionModel({
237                                 singleSelect:true,
238                                 listeners: {
239                                     selectionchange: function(sel){
240                                         var rec = sel.getSelected();
241                                         if(rec){
242                                             Ext.getCmp('preview').body.update('<b><u>' + rec.get('title') + '</u></b><br /><br />Post details here.');
243                                         }
244                                     }
245                                 }
246                             }),
247                             trackMouseOver:false,
248                             loadMask: {msg:'Loading Topics...'},
249                             viewConfig: {
250                                 forceFit:true,
251                                 enableRowBody:true,
252                                 showPreview:true,
253                                 getRowClass : function(record, rowIndex, p, ds){
254                                     if(this.showPreview){
255                                         p.body = '<p>'+record.data.excerpt+'</p>';
256                                         return 'x-grid3-row-expanded';
257                                     }
258                                     return 'x-grid3-row-collapsed';
259                                 }
260                             },
261                             tbar:[
262                                 {
263                                     text:'New Topic',
264                                     iconCls: 'new-topic',
265                                     handler:function(){alert('Not implemented.');}
266                                 },
267                                 '-',
268                                 {
269                                     pressed: true,
270                                     enableToggle:true,
271                                     text:'Preview Pane',
272                                     tooltip: {title:'Preview Pane',text:'Show or hide the Preview Pane'},
273                                     iconCls: 'preview',
274                                     toggleHandler: togglePreview
275                                 },
276                                 ' ',
277                                 {
278                                     pressed: true,
279                                     enableToggle:true,
280                                     text:'Summary',
281                                     tooltip: {title:'Post Summary',text:'View a short summary of each post in the list'},
282                                     iconCls: 'summary',
283                                     toggleHandler: toggleDetails
284                                 }
285                             ],
286                             bbar: new Ext.PagingToolbar({
287                                 pageSize: 25,
288                                 store: ds,
289                                 displayInfo: true,
290                                 displayMsg: 'Displaying topics {0} - {1} of {2}',
291                                 emptyMsg: "No topics to display"
292                             })
293                         }), {
294                             id:'preview',
295                             region:'south',
296                             height:250,
297                             title:'View Topic',
298                             split:true,
299                             bodyStyle: 'padding: 10px; font-family: Arial; font-size: 12px;'
300                         }
301                      ]
302                  }
303               })
304          ]
305     });
306
307     var tree = Ext.getCmp('forum-tree');
308     tree.on('append', function(tree, p, node){
309        if(node.id == 40){
310            node.select.defer(100, node);
311        }
312     });
313     var sm = tree.getSelectionModel();
314     sm.on('beforeselect', function(sm, node){
315          return node.isLeaf();
316     });
317     sm.on('selectionchange', function(sm, node){
318         ds.loadForum(node.id);
319         Ext.getCmp('main-view').setTitle(node.text);
320     });
321
322
323      var searchStore = new Ext.data.Store({
324         proxy: new Ext.data.ScriptTagProxy({
325             url: 'http://extjs.com/forum/topics-browse-remote.php'
326         }),
327         reader: new Ext.data.JsonReader({
328             root: 'topics',
329             totalProperty: 'totalCount',
330             id: 'threadid'
331         }, [
332             'title', 'author',
333             {name: 'lastpost', type: 'date', dateFormat: 'timestamp'}
334         ])
335     });
336
337     // Custom rendering Template
338     var resultTpl = new Ext.XTemplate(
339         '<tpl for=".">',
340             '<div class="x-combo-list-item search-item">{title} by <b>{author}</b></div>',
341         '</tpl>'
342     );
343
344     var search = new Ext.form.ComboBox({
345         store: searchStore,
346         applyTo: 'search',
347         displayField:'title',
348         typeAhead: false,
349         loadingText: 'Searching...',
350         width: 200,
351         pageSize:10,
352         listWidth:550,
353         hideTrigger:true,
354         tpl: resultTpl,
355         minChars:3,
356         emptyText:'Quick Search',
357         onSelect: function(record){ // override default onSelect to do redirect
358             window.location =
359                 String.format('http://extjs.com/forum/showthread.php?t={0}&p={1}', record.data.topicId, record.id);
360         }
361     });
362     // apply it to the exsting input element
363     //search.applyTo('search');
364
365
366
367     function toggleDetails(btn, pressed){
368         var view = Ext.getCmp('topic-grid').getView();
369         view.showPreview = pressed;
370         view.refresh();
371     }
372
373     function togglePreview(btn, pressed){
374         var preview = Ext.getCmp('preview');
375         preview[pressed ? 'show' : 'hide']();
376         preview.ownerCt.doLayout();
377     }
378 });
379
380 Forum.TreeLoader = function(){
381     Forum.TreeLoader.superclass.constructor.call(this);
382     this.proxy = new Ext.data.ScriptTagProxy({
383         url : this.dataUrl
384     });
385 };
386 Ext.extend(Forum.TreeLoader, Ext.tree.TreeLoader, {
387     dataUrl: 'http://extjs.com/forum/forums-remote.php',
388     requestData : function(node, cb){
389         this.proxy.request('read', null, {}, {
390             readRecords : function(o){
391                 return o;
392             }
393         }, this.addNodes, this, {node:node, cb:cb});
394     },
395
396     addNodes : function(o, arg){
397         var node = arg.node;
398         for(var i = 0, len = o.length; i < len; i++){
399             var n = this.createNode(o[i]);
400             if(n){
401                 node.appendChild(n);
402             }
403         }
404         arg.cb(this, node);
405     }
406 });