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