/* This file is part of Ext JS 3.4 Copyright (c) 2011-2013 Sencha Inc Contact: http://www.sencha.com/contact GNU General Public License Usage This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html. If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact. Build date: 2013-04-03 15:07:25 */ Ext.onReady(function(){ Ext.QuickTips.init(); var xg = Ext.grid; // turn off default shadows which look funky in air xg.GridEditor.prototype.shadow = false; var conn = Ext.data.SqlDB.getInstance(); conn.open('tasks.db'); // the main grid store var taskStore = new TaskStore(conn); // Category store shared by category combos var catStore = new CategoryStore(); taskStore.load({ callback: function(){ // first time? if(taskStore.getCount() < 1){ Ext.Msg.confirm('Create Tasks?', 'Your database is currently empty. Would you like to insert some demo data?', function(btn){ if(btn == 'yes'){ loadDemoTasks(taskStore); } catStore.init(taskStore); }); }else{ catStore.init(taskStore); } } }); // custom event to notify when a new category is available taskStore.on('newcategory', catStore.addCategory, catStore); // set of event handlers shared by combos to allow them to share // the same local store var comboEvents = { focus: function(){ this.bindStore(catStore); }, blur: function(c){ catStore.purgeListeners(); } } var completeColumn = new CompleteColumn(); // custom template for the grid header var headerTpl = new Ext.Template( '', '{cells}', '', '', '', '', '', '', "
" ); var selections = new Ext.grid.RowSelectionModel(); // The main grid in all its configuration option glory var grid = new xg.EditorGridPanel({ id:'tasks-grid', store: taskStore, sm: selections, clicksToEdit: 'auto', enableColumnHide:false, enableColumnMove:false, border:false, title:'All Tasks', iconCls:'icon-show-all', region:'center', plugins: completeColumn, columns: [ completeColumn, { header: "Task", width:400, sortable: true, dataIndex: 'title', id:'task-title', editor: new Ext.form.TextField({ allowBlank: false }) }, { header: "Category", width:150, sortable: true, dataIndex: 'category', editor: new Ext.form.ComboBox({ displayField: 'text', triggerAction: 'all', mode:'local', selectOnFocus:true, listClass:'x-combo-list-small', listeners: comboEvents }) }, { header: "Due Date", width: 150, sortable: true, renderer: Ext.util.Format.dateRenderer('D m/d/Y'), dataIndex: 'dueDate', groupRenderer: textDate(), groupName: 'Due', editor: new Ext.form.DateField({ format : "m/d/Y" }) } ], view: new Ext.grid.GroupingView({ forceFit:true, ignoreAdd: true, emptyText: 'No Tasks to display', templates: { header: headerTpl }, 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 ''; } }) }); var viewPanel = new Ext.Panel({ frame:true, title: 'Views', collapsible:true, contentEl:'task-views', titleCollapse: true }); var taskActions = new Ext.Panel({ frame:true, title: 'Task Actions', collapsible:true, contentEl:'task-actions', titleCollapse: true }); var groupActions = new Ext.Panel({ frame:true, title: 'Task Grouping', collapsible:true, contentEl:'task-grouping', titleCollapse: true }); var actionPanel = new Ext.Panel({ id:'action-panel', region:'west', split:true, collapsible: true, collapseMode: 'mini', header: false, width:200, minWidth: 150, border: false, baseCls:'x-plain', items: [taskActions, viewPanel, groupActions] }); if(Ext.isAir){ // create AIR window var win = new Ext.air.MainWindow({ layout:'border', items: [actionPanel, grid], title: 'Simple Tasks', iconCls: 'icon-show-all' }).render(); }else{ var viewport = new Ext.Viewport({ layout:'border', items: [actionPanel, grid] }); } var ab = actionPanel.body; ab.on('mousedown', doAction, null, {delegate:'a'}); ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true}); grid.on('resize', syncFields); grid.on('columnresize', syncFields); grid.on('afteredit', function(e){ if(e.field == 'category'){ catStore.addCategory(e.value); } if(e.field == taskStore.getGroupState()){ taskStore.applyGrouping(); } }); grid.on('keydown', function(e){ if(e.getKey() == e.DELETE && !grid.editing){ actions['action-delete'](); } }); selections.on('selectionchange', function(sm){ var bd = taskActions.body, c = sm.getCount(); bd.select('li:not(#new-task)').setDisplayed(c > 0); bd.select('span.s').setDisplayed(c > 1); }); // The fields in the grid's header var ntTitle = new Ext.form.TextField({ renderTo: 'new-task-title', emptyText: 'Add a task...' }); var ntCat = new Ext.form.ComboBox({ renderTo: 'new-task-cat', disabled:true, displayField: 'text', triggerAction: 'all', mode:'local', selectOnFocus:true, listClass:'x-combo-list-small', listeners: comboEvents }); 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(){ focused = true; }, blur: function(){ focused = false; doBlur.defer(250); }, specialkey: function(f, e){ if(e.getKey()==e.ENTER){ 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; } }); // 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)){ taskStore.addTask({ taskId: Task.nextId(), title: title, dueDate: ntDue.getValue()||'', description: '', // ??? category: ntCat.getValue(), completed: false }); ntTitle.setValue(''); if(userTriggered){ // if the 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; } } var actions = { 'view-all' : function(){ taskStore.applyFilter('all'); grid.setTitle('All Tasks', 'icon-show-all'); }, 'view-active' : function(){ taskStore.applyFilter(false); grid.setTitle('Active Tasks', 'icon-show-active'); }, 'view-complete' : function(){ taskStore.applyFilter(true); grid.setTitle('Completed Tasks', 'icon-show-complete'); }, 'action-new' : function(){ ntTitle.focus(); }, 'action-complete' : function(){ selections.each(function(s){ s.set('completed', true); }); taskStore.applyFilter(); }, 'action-active' : function(){ selections.each(function(s){ s.set('completed', false); }); taskStore.applyFilter(); }, 'action-delete' : function(){ Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?', function(btn){ if(btn == 'yes'){ selections.each(function(s){ taskStore.remove(s); }); } }); }, 'group-date' : function(){ taskStore.groupBy('dueDate'); }, 'group-cat' : function(){ taskStore.groupBy('category'); }, 'no-group' : function(){ taskStore.clearGrouping(); } }; function doAction(e, t){ e.stopEvent(); actions[t.id](); } // generates a renderer function to be used for textual date groups function textDate(){ // create the cache of ranges to be reused var today = new Date().clearTime(true); var year = today.getFullYear(); var todayTime = today.getTime(); var yesterday = today.add('d', -1).getTime(); var tomorrow = today.add('d', 1).getTime(); var weekDays = today.add('d', 6).getTime(); var lastWeekDays = today.add('d', -6).getTime(); return function(date){ if(!date) { return '(No Date)'; } var notime = date.clearTime(true).getTime(); if (notime == todayTime) { return 'Today'; } if(notime > todayTime){ if (notime == tomorrow) { return 'Tomorrow'; } if (notime <= weekDays) { return date.format('l'); } }else { if(notime == yesterday) { return 'Yesterday'; } if(notime >= lastWeekDays) { return 'Last ' + date.format('l'); } } return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y'); } } }); /* This is used to laod some demo tasks if the task database is empty */ function loadDemoTasks(store){ var s = new Date(); // hardcoded demo tasks store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false}); store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false}); store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false}); store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false}); store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false}); store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true}); store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false}); store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true}); }