provide installation instructions
[extjs.git] / air / samples / tasks / js / TaskGrid.js
1 /*\r
2  * Ext JS Library 0.30\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 TaskGrid = function(){\r
10         \r
11         // custom columns\r
12         var completeColumn = new CompleteColumn();\r
13         var reminderColumn = new ReminderColumn();\r
14         \r
15         TaskGrid.superclass.constructor.call(this, {\r
16                 id:'tasks-grid',\r
17         store: tx.data.tasks,\r
18         sm: new Ext.grid.RowSelectionModel({moveEditorOnEnter: false}),\r
19         clicksToEdit: 'auto',\r
20         enableColumnHide:false,\r
21         enableColumnMove:false,\r
22                 autoEncode: true,\r
23         title:'All Tasks',\r
24         iconCls:'icon-folder',\r
25         region:'center',\r
26         plugins: [completeColumn, reminderColumn],\r
27                 margins:'3 3 3 0',\r
28         columns: [\r
29             completeColumn,\r
30             {\r
31                 header: "Task",\r
32                 width:400,\r
33                 sortable: true,\r
34                 dataIndex: 'title',\r
35                 id:'task-title',\r
36                 editor: new Ext.form.TextField({\r
37                     allowBlank: false\r
38                 })\r
39             },\r
40             {\r
41                 header: "List",\r
42                 width:150,\r
43                 sortable: true,\r
44                 dataIndex: 'listId',\r
45                 editor: new ListSelector({\r
46                                 store:tx.data.lists\r
47                             }),\r
48                                 renderer : function(v){\r
49                                         return tx.data.lists.getName(v);\r
50                                 }\r
51             },\r
52             {\r
53                                 id:'dueDate',\r
54                 header: "Due Date",\r
55                 width: 150,\r
56                 sortable: true,\r
57                 renderer: Ext.util.Format.dateRenderer('D m/d/Y'),\r
58                 dataIndex: 'dueDate',\r
59                 groupRenderer: Ext.util.Format.createTextDateRenderer(),\r
60                 groupName: 'Due',\r
61                 editor: new Ext.form.DateField({\r
62                     format : "m/d/Y"\r
63                 })\r
64             },\r
65                         reminderColumn\r
66         ],\r
67 \r
68         view: new TaskView()\r
69         });\r
70         \r
71         // Keep the visible date groups in the grid accurate\r
72         Ext.TaskMgr.start({\r
73                 run: function(){\r
74                         var col = this.getColumnModel().getColumnById('dueDate');\r
75                         if(col.groupRenderer.date.getTime() != new Date().clearTime().getTime()){\r
76                                 col.groupRenderer = Ext.util.Format.createTextDateRenderer();\r
77                                 tx.data.tasks.applyGrouping();\r
78                         }\r
79                 },\r
80                 interval: 60000,\r
81                 scope: this\r
82         });\r
83         \r
84         this.on('rowcontextmenu', this.onRowContext, this);\r
85 };\r
86 \r
87 Ext.extend(TaskGrid, Ext.grid.EditorGridPanel, {\r
88         onCellDblClick: function(g, row){\r
89                 clearTimeout(this.autoEditTimer); // allow dbl click without starting edit\r
90                 var id = this.store.getAt(row).id;\r
91                 \r
92                 Ext.air.NativeWindowManager.getTaskWindow(id);\r
93         },\r
94 \r
95     // private\r
96     onAutoEditClick : function(e, t){\r
97                 clearTimeout(this.autoEditTimer);\r
98         if(e.button !== 0){\r
99             return;\r
100         }\r
101         var row = this.view.findRowIndex(t);\r
102         var col = this.view.findCellIndex(t);\r
103         if(row !== false && col !== false){\r
104                 if(this.selModel.isSelected(row) && this.selModel.getCount() === 1){\r
105                                 this.autoEditTimer = this.startEditing.defer(300, this, [row, col]);\r
106             }\r
107         }\r
108     },\r
109         \r
110         onRowContext : function(grid, row, e){\r
111         if(!this.menu){ // create context menu on first right click\r
112             this.menu = new Ext.menu.Menu({\r
113                 id:'tasks-ctx',\r
114                                 listWidth: 200,\r
115                 items: [{\r
116                     text:'Open',\r
117                     scope: this,\r
118                     handler:function(){\r
119                                                 Ext.each(this.selModel.getSelections(), function(r){\r
120                                                         Ext.air.NativeWindowManager.getTaskWindow(r.id);\r
121                                                 });\r
122                     }\r
123                 },'-',\r
124                                         tx.actions.complete,\r
125                                         tx.actions.deleteTask\r
126                 ]\r
127             });\r
128         }\r
129                 if(!this.selModel.isSelected(row)){\r
130                         this.selModel.selectRow(row);\r
131                 }\r
132                 \r
133                 this.menu.showAt(e.getXY());\r
134     }\r
135 })\r
136 \r
137 \r
138 TaskView = Ext.extend(Ext.grid.GroupingView, {\r
139         forceFit:true,\r
140     ignoreAdd: true,\r
141     emptyText: 'There are no tasks to show in this list.',\r
142 \r
143     templates: {\r
144         header: Templates.gridHeader\r
145     },\r
146     getRowClass : function(r){\r
147         var d = r.data;\r
148         if(d.completed){\r
149             return 'task-completed';\r
150         }\r
151         if(d.dueDate && d.dueDate.getTime() < new Date().clearTime().getTime()){\r
152             return 'task-overdue';\r
153         }\r
154         return '';\r
155     }\r
156 });\r
157 \r
158 \r
159 TaskHeader = function(grid){\r
160         grid.on('resize', syncFields);\r
161         grid.on('columnresize', syncFields);\r
162                 \r
163     // The fields in the grid's header\r
164     var ntTitle = this.ntTitle = new Ext.form.TextField({\r
165         renderTo: 'new-task-title',\r
166         emptyText: 'Add a task...'\r
167     });\r
168 \r
169     var ntCat = new ListSelector({\r
170         renderTo: 'new-task-cat',\r
171         disabled:true,\r
172         store:tx.data.lists,\r
173                 listenForLoad: true\r
174     });\r
175 \r
176     var ntDue = new Ext.form.DateField({\r
177         renderTo: 'new-task-due',\r
178         value: new Date(),\r
179         disabled:true,\r
180         format : "m/d/Y"\r
181     });\r
182 \r
183     // syncs the header fields' widths with the grid column widths\r
184     function syncFields(){\r
185         var cm = grid.getColumnModel();\r
186         ntTitle.setSize(cm.getColumnWidth(1)-2);\r
187         ntCat.setSize(cm.getColumnWidth(2)-4);\r
188         ntDue.setSize(cm.getColumnWidth(3)-4);\r
189     }\r
190     syncFields();\r
191 \r
192     var editing = false, focused = false, userTriggered = false;\r
193     var handlers = {\r
194         focus: function(){\r
195             setFocus.defer(20, window, [true]);\r
196         },\r
197         blur: function(){\r
198             focused = false;\r
199             doBlur.defer(250);\r
200         },\r
201         specialkey: function(f, e){\r
202             if(e.getKey()==e.ENTER && (!f.isExpanded || !f.isExpanded())){\r
203                 userTriggered = true;\r
204                 e.stopEvent();\r
205                 f.el.blur();\r
206                 if(f.triggerBlur){\r
207                     f.triggerBlur();\r
208                 }\r
209             }\r
210         }\r
211     }\r
212     ntTitle.on(handlers);\r
213     ntCat.on(handlers);\r
214     ntDue.on(handlers);\r
215 \r
216     ntTitle.on('focus', function(){\r
217         focused = true;\r
218         if(!editing){\r
219             ntCat.enable();\r
220             ntDue.enable();\r
221             syncFields();\r
222             editing = true;\r
223                         \r
224                         ntCat.setValue(tx.data.getActiveListId());\r
225         }\r
226     });\r
227 \r
228     function setFocus(v){\r
229                 focused = v;\r
230         }\r
231     // when a field in the add bar is blurred, this determines\r
232     // whether a new task should be created\r
233     function doBlur(){\r
234         if(editing && !focused){\r
235                         var title = ntTitle.getValue();\r
236             if(!Ext.isEmpty(title)){\r
237                                 tx.data.tasks.createTask(title, ntCat.getRawValue(), ntDue.getValue());\r
238                 ntTitle.setValue('');\r
239                 if(userTriggered){ // if they entered to add the task, then go to a new add automatically\r
240                     userTriggered = false;\r
241                     ntTitle.focus.defer(100, ntTitle);\r
242                 }\r
243             }\r
244             ntCat.disable();\r
245             ntDue.disable();\r
246             editing = false;\r
247         }\r
248     }\r
249 };\r