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
182 items: [taskActions, viewPanel, groupActions]
\r
185 if(Ext.isAir){ // create AIR window
\r
186 var win = new Ext.air.MainWindow({
\r
188 items: [actionPanel, grid],
\r
189 title: 'Simple Tasks',
\r
190 iconCls: 'icon-show-all'
\r
193 var viewport = new Ext.Viewport({
\r
195 items: [actionPanel, grid]
\r
199 var ab = actionPanel.body;
\r
200 ab.on('mousedown', doAction, null, {delegate:'a'});
\r
201 ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true});
\r
203 grid.on('resize', syncFields);
\r
204 grid.on('columnresize', syncFields);
\r
206 grid.on('afteredit', function(e){
\r
207 if(e.field == 'category'){
\r
208 catStore.addCategory(e.value);
\r
210 if(e.field == taskStore.getGroupState()){
\r
211 taskStore.applyGrouping();
\r
216 grid.on('keydown', function(e){
\r
217 if(e.getKey() == e.DELETE && !grid.editing){
\r
218 actions['action-delete']();
\r
222 selections.on('selectionchange', function(sm){
\r
223 var bd = taskActions.body, c = sm.getCount();
\r
224 bd.select('li:not(#new-task)').setDisplayed(c > 0);
\r
225 bd.select('span.s').setDisplayed(c > 1);
\r
228 // The fields in the grid's header
\r
229 var ntTitle = new Ext.form.TextField({
\r
230 renderTo: 'new-task-title',
\r
231 emptyText: 'Add a task...'
\r
234 var ntCat = new Ext.form.ComboBox({
\r
235 renderTo: 'new-task-cat',
\r
237 displayField: 'text',
\r
238 triggerAction: 'all',
\r
240 selectOnFocus:true,
\r
241 listClass:'x-combo-list-small',
\r
242 listeners: comboEvents
\r
245 var ntDue = new Ext.form.DateField({
\r
246 renderTo: 'new-task-due',
\r
252 // syncs the header fields' widths with the grid column widths
\r
253 function syncFields(){
\r
254 var cm = grid.getColumnModel();
\r
255 ntTitle.setSize(cm.getColumnWidth(1)-2);
\r
256 ntCat.setSize(cm.getColumnWidth(2)-4);
\r
257 ntDue.setSize(cm.getColumnWidth(3)-4);
\r
261 var editing = false, focused = false, userTriggered = false;
\r
270 specialkey: function(f, e){
\r
271 if(e.getKey()==e.ENTER){
\r
272 userTriggered = true;
\r
281 ntTitle.on(handlers);
\r
282 ntCat.on(handlers);
\r
283 ntDue.on(handlers);
\r
285 ntTitle.on('focus', function(){
\r
295 // when a field in the add bar is blurred, this determines
\r
296 // whether a new task should be created
\r
298 if(editing && !focused){
\r
299 var title = ntTitle.getValue();
\r
300 if(!Ext.isEmpty(title)){
\r
301 taskStore.addTask({
\r
302 taskId: Task.nextId(),
\r
304 dueDate: ntDue.getValue()||'',
\r
305 description: '', // ???
\r
306 category: ntCat.getValue(),
\r
309 ntTitle.setValue('');
\r
310 if(userTriggered){ // if the entered to add the task, then go to a new add automatically
\r
311 userTriggered = false;
\r
312 ntTitle.focus.defer(100, ntTitle);
\r
322 'view-all' : function(){
\r
323 taskStore.applyFilter('all');
\r
324 grid.setTitle('All Tasks', 'icon-show-all');
\r
327 'view-active' : function(){
\r
328 taskStore.applyFilter(false);
\r
329 grid.setTitle('Active Tasks', 'icon-show-active');
\r
332 'view-complete' : function(){
\r
333 taskStore.applyFilter(true);
\r
334 grid.setTitle('Completed Tasks', 'icon-show-complete');
\r
337 'action-new' : function(){
\r
341 'action-complete' : function(){
\r
342 selections.each(function(s){
\r
343 s.set('completed', true);
\r
345 taskStore.applyFilter();
\r
348 'action-active' : function(){
\r
349 selections.each(function(s){
\r
350 s.set('completed', false);
\r
352 taskStore.applyFilter();
\r
355 'action-delete' : function(){
\r
356 Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?',
\r
359 selections.each(function(s){
\r
360 taskStore.remove(s);
\r
366 'group-date' : function(){
\r
367 taskStore.groupBy('dueDate');
\r
370 'group-cat' : function(){
\r
371 taskStore.groupBy('category');
\r
374 'no-group' : function(){
\r
375 taskStore.clearGrouping();
\r
379 function doAction(e, t){
\r
385 // generates a renderer function to be used for textual date groups
\r
386 function textDate(){
\r
387 // create the cache of ranges to be reused
\r
388 var today = new Date().clearTime(true);
\r
389 var year = today.getFullYear();
\r
390 var todayTime = today.getTime();
\r
391 var yesterday = today.add('d', -1).getTime();
\r
392 var tomorrow = today.add('d', 1).getTime();
\r
393 var weekDays = today.add('d', 6).getTime();
\r
394 var lastWeekDays = today.add('d', -6).getTime();
\r
396 return function(date){
\r
398 return '(No Date)';
\r
400 var notime = date.clearTime(true).getTime();
\r
402 if (notime == todayTime) {
\r
405 if(notime > todayTime){
\r
406 if (notime == tomorrow) {
\r
409 if (notime <= weekDays) {
\r
410 return date.format('l');
\r
413 if(notime == yesterday) {
\r
414 return 'Yesterday';
\r
416 if(notime >= lastWeekDays) {
\r
417 return 'Last ' + date.format('l');
\r
420 return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y');
\r
425 /* This is used to laod some demo tasks if the task database is empty */
\r
426 function loadDemoTasks(store){
\r
427 var s = new Date();
\r
428 // hardcoded demo tasks
\r
429 store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false});
\r
430 store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
\r
431 store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false});
\r
432 store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
\r
433 store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false});
\r
434 store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true});
\r
435 store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false});
\r
436 store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true});
\r