3 * Copyright(c) 2006-2009 Ext JS, LLC
5 * http://www.extjs.com/license
7 Ext.onReady(function(){
\r
8 Ext.QuickTips.init();
\r
11 // turn off default shadows which look funky in air
\r
12 xg.GridEditor.prototype.shadow = false;
\r
14 var conn = Ext.data.SqlDB.getInstance();
\r
15 conn.open('tasks.db');
\r
17 // the main grid store
\r
18 var taskStore = new TaskStore(conn);
\r
20 // Category store shared by category combos
\r
21 var catStore = new CategoryStore();
\r
24 callback: function(){
\r
26 if(taskStore.getCount() < 1){
\r
27 Ext.Msg.confirm('Create Tasks?', 'Your database is currently empty. Would you like to insert some demo data?',
\r
30 loadDemoTasks(taskStore);
\r
32 catStore.init(taskStore);
\r
35 catStore.init(taskStore);
\r
40 // custom event to notify when a new category is available
\r
41 taskStore.on('newcategory', catStore.addCategory, catStore);
\r
43 // set of event handlers shared by combos to allow them to share
\r
44 // the same local store
\r
47 this.bindStore(catStore);
\r
50 catStore.purgeListeners();
\r
54 var completeColumn = new CompleteColumn();
\r
56 // custom template for the grid header
\r
57 var headerTpl = new Ext.Template(
\r
58 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
\r
59 '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
\r
60 '<tbody><tr class="new-task-row">',
\r
61 '<td><div id="new-task-icon"></div></td>',
\r
62 '<td><div class="x-small-editor" id="new-task-title"></div></td>',
\r
63 '<td><div class="x-small-editor" id="new-task-cat"></div></td>',
\r
64 '<td><div class="x-small-editor" id="new-task-due"></div></td>',
\r
69 var selections = new Ext.grid.RowSelectionModel();
\r
71 // The main grid in all its configuration option glory
\r
72 var grid = new xg.EditorGridPanel({
\r
76 clicksToEdit: 'auto',
\r
77 enableColumnHide:false,
\r
78 enableColumnMove:false,
\r
81 iconCls:'icon-show-all',
\r
84 plugins: completeColumn,
\r
94 editor: new Ext.form.TextField({
\r
102 dataIndex: 'category',
\r
103 editor: new Ext.form.ComboBox({
\r
104 displayField: 'text',
\r
105 triggerAction: 'all',
\r
107 selectOnFocus:true,
\r
108 listClass:'x-combo-list-small',
\r
109 listeners: comboEvents
\r
113 header: "Due Date",
\r
116 renderer: Ext.util.Format.dateRenderer('D m/d/Y'),
\r
117 dataIndex: 'dueDate',
\r
118 groupRenderer: textDate(),
\r
120 editor: new Ext.form.DateField({
\r
126 view: new Ext.grid.GroupingView({
\r
129 emptyText: 'No Tasks to display',
\r
135 getRowClass : function(r){
\r
138 return 'task-completed';
\r
140 if(d.dueDate && d.dueDate.getTime() < new Date().clearTime().getTime()){
\r
141 return 'task-overdue';
\r
148 var viewPanel = new Ext.Panel({
\r
152 contentEl:'task-views',
\r
153 titleCollapse: true
\r
156 var taskActions = new Ext.Panel({
\r
158 title: 'Task Actions',
\r
160 contentEl:'task-actions',
\r
161 titleCollapse: true
\r
164 var groupActions = new Ext.Panel({
\r
166 title: 'Task Grouping',
\r
168 contentEl:'task-grouping',
\r
169 titleCollapse: true
\r
172 var actionPanel = new Ext.Panel({
\r
177 collapseMode: 'mini',
\r
183 items: [taskActions, viewPanel, groupActions]
\r
186 if(Ext.isAir){ // create AIR window
\r
187 var win = new Ext.air.MainWindow({
\r
189 items: [actionPanel, grid],
\r
190 title: 'Simple Tasks',
\r
191 iconCls: 'icon-show-all'
\r
194 var viewport = new Ext.Viewport({
\r
196 items: [actionPanel, grid]
\r
200 var ab = actionPanel.body;
\r
201 ab.on('mousedown', doAction, null, {delegate:'a'});
\r
202 ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true});
\r
204 grid.on('resize', syncFields);
\r
205 grid.on('columnresize', syncFields);
\r
207 grid.on('afteredit', function(e){
\r
208 if(e.field == 'category'){
\r
209 catStore.addCategory(e.value);
\r
211 if(e.field == taskStore.getGroupState()){
\r
212 taskStore.applyGrouping();
\r
217 grid.on('keydown', function(e){
\r
218 if(e.getKey() == e.DELETE && !grid.editing){
\r
219 actions['action-delete']();
\r
223 selections.on('selectionchange', function(sm){
\r
224 var bd = taskActions.body, c = sm.getCount();
\r
225 bd.select('li:not(#new-task)').setDisplayed(c > 0);
\r
226 bd.select('span.s').setDisplayed(c > 1);
\r
229 // The fields in the grid's header
\r
230 var ntTitle = new Ext.form.TextField({
\r
231 renderTo: 'new-task-title',
\r
232 emptyText: 'Add a task...'
\r
235 var ntCat = new Ext.form.ComboBox({
\r
236 renderTo: 'new-task-cat',
\r
238 displayField: 'text',
\r
239 triggerAction: 'all',
\r
241 selectOnFocus:true,
\r
242 listClass:'x-combo-list-small',
\r
243 listeners: comboEvents
\r
246 var ntDue = new Ext.form.DateField({
\r
247 renderTo: 'new-task-due',
\r
253 // syncs the header fields' widths with the grid column widths
\r
254 function syncFields(){
\r
255 var cm = grid.getColumnModel();
\r
256 ntTitle.setSize(cm.getColumnWidth(1)-2);
\r
257 ntCat.setSize(cm.getColumnWidth(2)-4);
\r
258 ntDue.setSize(cm.getColumnWidth(3)-4);
\r
262 var editing = false, focused = false, userTriggered = false;
\r
271 specialkey: function(f, e){
\r
272 if(e.getKey()==e.ENTER){
\r
273 userTriggered = true;
\r
282 ntTitle.on(handlers);
\r
283 ntCat.on(handlers);
\r
284 ntDue.on(handlers);
\r
286 ntTitle.on('focus', function(){
\r
296 // when a field in the add bar is blurred, this determines
\r
297 // whether a new task should be created
\r
299 if(editing && !focused){
\r
300 var title = ntTitle.getValue();
\r
301 if(!Ext.isEmpty(title)){
\r
302 taskStore.addTask({
\r
303 taskId: Task.nextId(),
\r
305 dueDate: ntDue.getValue()||'',
\r
306 description: '', // ???
\r
307 category: ntCat.getValue(),
\r
310 ntTitle.setValue('');
\r
311 if(userTriggered){ // if the entered to add the task, then go to a new add automatically
\r
312 userTriggered = false;
\r
313 ntTitle.focus.defer(100, ntTitle);
\r
323 'view-all' : function(){
\r
324 taskStore.applyFilter('all');
\r
325 grid.setTitle('All Tasks', 'icon-show-all');
\r
328 'view-active' : function(){
\r
329 taskStore.applyFilter(false);
\r
330 grid.setTitle('Active Tasks', 'icon-show-active');
\r
333 'view-complete' : function(){
\r
334 taskStore.applyFilter(true);
\r
335 grid.setTitle('Completed Tasks', 'icon-show-complete');
\r
338 'action-new' : function(){
\r
342 'action-complete' : function(){
\r
343 selections.each(function(s){
\r
344 s.set('completed', true);
\r
346 taskStore.applyFilter();
\r
349 'action-active' : function(){
\r
350 selections.each(function(s){
\r
351 s.set('completed', false);
\r
353 taskStore.applyFilter();
\r
356 'action-delete' : function(){
\r
357 Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?',
\r
360 selections.each(function(s){
\r
361 taskStore.remove(s);
\r
367 'group-date' : function(){
\r
368 taskStore.groupBy('dueDate');
\r
371 'group-cat' : function(){
\r
372 taskStore.groupBy('category');
\r
375 'no-group' : function(){
\r
376 taskStore.clearGrouping();
\r
380 function doAction(e, t){
\r
386 // generates a renderer function to be used for textual date groups
\r
387 function textDate(){
\r
388 // create the cache of ranges to be reused
\r
389 var today = new Date().clearTime(true);
\r
390 var year = today.getFullYear();
\r
391 var todayTime = today.getTime();
\r
392 var yesterday = today.add('d', -1).getTime();
\r
393 var tomorrow = today.add('d', 1).getTime();
\r
394 var weekDays = today.add('d', 6).getTime();
\r
395 var lastWeekDays = today.add('d', -6).getTime();
\r
397 return function(date){
\r
399 return '(No Date)';
\r
401 var notime = date.clearTime(true).getTime();
\r
403 if (notime == todayTime) {
\r
406 if(notime > todayTime){
\r
407 if (notime == tomorrow) {
\r
410 if (notime <= weekDays) {
\r
411 return date.format('l');
\r
414 if(notime == yesterday) {
\r
415 return 'Yesterday';
\r
417 if(notime >= lastWeekDays) {
\r
418 return 'Last ' + date.format('l');
\r
421 return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y');
\r
426 /* This is used to laod some demo tasks if the task database is empty */
\r
427 function loadDemoTasks(store){
\r
428 var s = new Date();
\r
429 // hardcoded demo tasks
\r
430 store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false});
\r
431 store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
\r
432 store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false});
\r
433 store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
\r
434 store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false});
\r
435 store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true});
\r
436 store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false});
\r
437 store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true});
\r