TaskGrid = function(){ // custom columns var completeColumn = new CompleteColumn(); var reminderColumn = new ReminderColumn(); TaskGrid.superclass.constructor.call(this, { id:'tasks-grid', store: tx.data.tasks, sm: new Ext.grid.RowSelectionModel({moveEditorOnEnter: false}), clicksToEdit: 'auto', enableColumnHide:false, enableColumnMove:false, autoEncode: true, title:'All Tasks', iconCls:'icon-folder', region:'center', plugins: [completeColumn, reminderColumn], margins:'3 3 3 0', columns: [ completeColumn, { header: "Task", width:400, sortable: true, dataIndex: 'title', id:'task-title', editor: new Ext.form.TextField({ allowBlank: false }) }, { header: "List", width:150, sortable: true, dataIndex: 'listId', editor: new ListSelector({ store:tx.data.lists }), renderer : function(v){ return tx.data.lists.getName(v); } }, { id:'dueDate', header: "Due Date", width: 150, sortable: true, renderer: Ext.util.Format.dateRenderer('D m/d/Y'), dataIndex: 'dueDate', groupRenderer: Ext.util.Format.createTextDateRenderer(), groupName: 'Due', editor: new Ext.form.DateField({ format : "m/d/Y" }) }, reminderColumn ], view: new TaskView() }); // Keep the visible date groups in the grid accurate Ext.TaskMgr.start({ run: function(){ var col = this.getColumnModel().getColumnById('dueDate'); if(col.groupRenderer.date.getTime() != new Date().clearTime().getTime()){ col.groupRenderer = Ext.util.Format.createTextDateRenderer(); tx.data.tasks.applyGrouping(); } }, interval: 60000, scope: this }); this.on('rowcontextmenu', this.onRowContext, this); }; Ext.extend(TaskGrid, Ext.grid.EditorGridPanel, { onCellDblClick: function(g, row){ clearTimeout(this.autoEditTimer); // allow dbl click without starting edit var id = this.store.getAt(row).id; Ext.air.NativeWindowManager.getTaskWindow(id); }, // private onAutoEditClick : function(e, t){ clearTimeout(this.autoEditTimer); if(e.button !== 0){ return; } var row = this.view.findRowIndex(t); var col = this.view.findCellIndex(t); if(row !== false && col !== false){ if(this.selModel.isSelected(row) && this.selModel.getCount() === 1){ this.autoEditTimer = this.startEditing.defer(300, this, [row, col]); } } }, onRowContext : function(grid, row, e){ if(!this.menu){ // create context menu on first right click this.menu = new Ext.menu.Menu({ id:'tasks-ctx', listWidth: 200, items: [{ text:'Open', scope: this, handler:function(){ Ext.each(this.selModel.getSelections(), function(r){ Ext.air.NativeWindowManager.getTaskWindow(r.id); }); } },'-', tx.actions.complete, tx.actions.deleteTask ] }); } if(!this.selModel.isSelected(row)){ this.selModel.selectRow(row); } this.menu.showAt(e.getXY()); } }) TaskView = Ext.extend(Ext.grid.GroupingView, { forceFit:true, ignoreAdd: true, emptyText: 'There are no tasks to show in this list.', templates: { header: Templates.gridHeader }, getRowClass : function(r){ var d = r.data; if(d.completed){ return 'task-completed'; } if(d.dueDate && d.dueDate.getTime() < new Date().clearTime().getTime()){ return 'task-overdue'; } return ''; } }); TaskHeader = function(grid){ grid.on('resize', syncFields); grid.on('columnresize', syncFields); // The fields in the grid's header var ntTitle = this.ntTitle = new Ext.form.TextField({ renderTo: 'new-task-title', emptyText: 'Add a task...' }); var ntCat = new ListSelector({ renderTo: 'new-task-cat', disabled:true, store:tx.data.lists, listenForLoad: true }); var ntDue = new Ext.form.DateField({ renderTo: 'new-task-due', value: new Date(), disabled:true, format : "m/d/Y" }); // syncs the header fields' widths with the grid column widths function syncFields(){ var cm = grid.getColumnModel(); ntTitle.setSize(cm.getColumnWidth(1)-2); ntCat.setSize(cm.getColumnWidth(2)-4); ntDue.setSize(cm.getColumnWidth(3)-4); } syncFields(); var editing = false, focused = false, userTriggered = false; var handlers = { focus: function(){ setFocus.defer(20, window, [true]); }, blur: function(){ focused = false; doBlur.defer(250); }, specialkey: function(f, e){ if(e.getKey()==e.ENTER && (!f.isExpanded || !f.isExpanded())){ userTriggered = true; e.stopEvent(); f.el.blur(); if(f.triggerBlur){ f.triggerBlur(); } } } } ntTitle.on(handlers); ntCat.on(handlers); ntDue.on(handlers); ntTitle.on('focus', function(){ focused = true; if(!editing){ ntCat.enable(); ntDue.enable(); syncFields(); editing = true; ntCat.setValue(tx.data.getActiveListId()); } }); function setFocus(v){ focused = v; } // when a field in the add bar is blurred, this determines // whether a new task should be created function doBlur(){ if(editing && !focused){ var title = ntTitle.getValue(); if(!Ext.isEmpty(title)){ tx.data.tasks.createTask(title, ntCat.getRawValue(), ntDue.getValue()); ntTitle.setValue(''); if(userTriggered){ // if they entered to add the task, then go to a new add automatically userTriggered = false; ntTitle.focus.defer(100, ntTitle); } } ntCat.disable(); ntDue.disable(); editing = false; } } };