tasks.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:13k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.1.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ Ext.onReady(function(){
  2.     Ext.QuickTips.init();
  3.     var xg = Ext.grid;
  4.     // turn off default shadows which look funky in air
  5.     xg.GridEditor.prototype.shadow = false;
  6.     
  7.     var conn = Ext.data.SqlDB.getInstance();
  8. conn.open('tasks.db');
  9.     
  10.     // the main grid store
  11.     var taskStore = new TaskStore(conn);
  12.     
  13.     // Category store shared by category combos
  14.     var catStore = new CategoryStore();
  15.     
  16. taskStore.load({
  17. callback: function(){
  18. // first time?
  19. if(taskStore.getCount() < 1){
  20. Ext.Msg.confirm('Create Tasks?', 'Your database is currently empty. Would you like to insert some demo data?', 
  21. function(btn){
  22. if(btn == 'yes'){
  23. loadDemoTasks(taskStore);
  24. }
  25. catStore.init(taskStore);
  26. });
  27. }else{
  28. catStore.init(taskStore);
  29. }
  30. }
  31. });
  32.     // custom event to notify when a new category is available
  33.     taskStore.on('newcategory', catStore.addCategory, catStore);
  34.     // set of event handlers shared by combos to allow them to share
  35.     // the same local store
  36.     var comboEvents = {
  37.         focus: function(){
  38.             this.bindStore(catStore);
  39.         },
  40.         blur: function(c){
  41.             catStore.purgeListeners();
  42.         }
  43.     }
  44.     var completeColumn = new CompleteColumn();
  45.     // custom template for the grid header
  46.     var headerTpl = new Ext.Template(
  47.         '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
  48.         '<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
  49.         '<tbody><tr class="new-task-row">',
  50.             '<td><div id="new-task-icon"></div></td>',
  51.             '<td><div class="x-small-editor" id="new-task-title"></div></td>',
  52.             '<td><div class="x-small-editor" id="new-task-cat"></div></td>',
  53.             '<td><div class="x-small-editor" id="new-task-due"></div></td>',
  54.         '</tr></tbody>',
  55.         "</table>"
  56.     );
  57.     var selections = new Ext.grid.RowSelectionModel();
  58.     // The main grid in all its configuration option glory
  59.     var grid = new xg.EditorGridPanel({
  60.         id:'tasks-grid',
  61.         store: taskStore,
  62.         sm: selections,
  63.         clicksToEdit: 'auto',
  64.         enableColumnHide:false,
  65.         enableColumnMove:false,
  66. border:false,
  67. title:'All Tasks',
  68. iconCls:'icon-show-all',
  69. region:'center',
  70.         plugins: completeColumn,
  71.         columns: [
  72.             completeColumn,
  73.             {
  74.                 header: "Task",
  75.                 width:400,
  76.                 sortable: true,
  77.                 dataIndex: 'title',
  78.                 id:'task-title',
  79.                 editor: new Ext.form.TextField({
  80.                     allowBlank: false
  81.                 })
  82.             },
  83.             {
  84.                 header: "Category",
  85.                 width:150,
  86.                 sortable: true,
  87.                 dataIndex: 'category',
  88.                 editor: new Ext.form.ComboBox({
  89.                     displayField: 'text',
  90.                     triggerAction: 'all',
  91.                     mode:'local',
  92.                     selectOnFocus:true,
  93.                     listClass:'x-combo-list-small',
  94.                     listeners: comboEvents
  95.                 })
  96.             },
  97.             {
  98.                 header: "Due Date",
  99.                 width: 150,
  100.                 sortable: true,
  101.                 renderer: Ext.util.Format.dateRenderer('D m/d/Y'),
  102.                 dataIndex: 'dueDate',
  103.                 groupRenderer: textDate(),
  104.                 groupName: 'Due',
  105.                 editor: new Ext.form.DateField({
  106.                     format : "m/d/Y"
  107.                 })
  108.             }
  109.         ],
  110.         view: new Ext.grid.GroupingView({
  111.             forceFit:true,
  112.             ignoreAdd: true,
  113.             emptyText: 'No Tasks to display',
  114.             templates: {
  115.                 header: headerTpl
  116.             },
  117.             getRowClass : function(r){
  118.                 var d = r.data;
  119.                 if(d.completed){
  120.                     return 'task-completed';
  121.                 }
  122.                 if(d.dueDate && d.dueDate.getTime() < new Date().clearTime().getTime()){
  123.                     return 'task-overdue';
  124.                 }
  125.                 return '';
  126.             }
  127.         })
  128.     });
  129.     var viewPanel = new Ext.Panel({
  130.      frame:true,
  131.      title: 'Views',
  132.      collapsible:true,
  133.      contentEl:'task-views',
  134.      titleCollapse: true
  135.     });
  136.     
  137.     var taskActions = new Ext.Panel({
  138.      frame:true,
  139.      title: 'Task Actions',
  140.      collapsible:true,
  141.      contentEl:'task-actions',
  142.      titleCollapse: true
  143.     });
  144.     
  145.     var groupActions = new Ext.Panel({
  146.      frame:true,
  147.      title: 'Task Grouping',
  148.      collapsible:true,
  149.      contentEl:'task-grouping',
  150.      titleCollapse: true
  151.     });
  152.     
  153.     var actionPanel = new Ext.Panel({
  154.      id:'action-panel',
  155.      region:'west',
  156.      split:true,
  157.      collapsible: true,
  158.      collapseMode: 'mini',
  159.         header: false,
  160.      width:200,
  161.      minWidth: 150,
  162.      border: false,
  163.      baseCls:'x-plain',
  164.      items: [taskActions, viewPanel, groupActions]
  165.     });
  166.     if(Ext.isAir){ // create AIR window
  167.         var win = new Ext.air.MainWindow({
  168.             layout:'border',
  169.             items: [actionPanel, grid],
  170.             title: 'Simple Tasks',
  171.             iconCls: 'icon-show-all'
  172.         }).render();
  173. }else{
  174.         var viewport = new Ext.Viewport({
  175.             layout:'border',
  176.             items: [actionPanel, grid]
  177.         });
  178.     }
  179.     var ab = actionPanel.body;
  180.     ab.on('mousedown', doAction, null, {delegate:'a'});
  181. ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true});
  182.     grid.on('resize', syncFields);
  183. grid.on('columnresize', syncFields);
  184.     grid.on('afteredit', function(e){
  185.         if(e.field == 'category'){
  186.             catStore.addCategory(e.value);
  187.         }
  188.         if(e.field == taskStore.getGroupState()){
  189.             taskStore.applyGrouping();
  190.         }
  191.     });
  192.     grid.on('keydown', function(e){
  193.          if(e.getKey() == e.DELETE && !grid.editing){
  194.              actions['action-delete']();
  195.          }
  196.     });
  197.     selections.on('selectionchange', function(sm){
  198.      var bd = taskActions.body, c = sm.getCount();
  199.      bd.select('li:not(#new-task)').setDisplayed(c > 0);
  200.      bd.select('span.s').setDisplayed(c > 1);
  201.     });
  202.     // The fields in the grid's header
  203.     var ntTitle = new Ext.form.TextField({
  204.         renderTo: 'new-task-title',
  205.         emptyText: 'Add a task...'
  206.     });
  207.     var ntCat = new Ext.form.ComboBox({
  208.         renderTo: 'new-task-cat',
  209.         disabled:true,
  210.         displayField: 'text',
  211.         triggerAction: 'all',
  212.         mode:'local',
  213.         selectOnFocus:true,
  214.         listClass:'x-combo-list-small',
  215.         listeners: comboEvents
  216.     });
  217.     var ntDue = new Ext.form.DateField({
  218.         renderTo: 'new-task-due',
  219.         value: new Date(),
  220.         disabled:true,
  221.         format : "m/d/Y"
  222.     });
  223.     // syncs the header fields' widths with the grid column widths
  224.     function syncFields(){
  225.         var cm = grid.getColumnModel();
  226.         ntTitle.setSize(cm.getColumnWidth(1)-2);
  227.         ntCat.setSize(cm.getColumnWidth(2)-4);
  228.         ntDue.setSize(cm.getColumnWidth(3)-4);
  229.     }
  230.     syncFields();
  231.     var editing = false, focused = false, userTriggered = false;
  232.     var handlers = {
  233.         focus: function(){
  234.             focused = true;
  235.         },
  236.         blur: function(){
  237.             focused = false;
  238.             doBlur.defer(250);
  239.         },
  240.         specialkey: function(f, e){
  241.             if(e.getKey()==e.ENTER){
  242.                 userTriggered = true;
  243.                 e.stopEvent();
  244.                 f.el.blur();
  245.                 if(f.triggerBlur){
  246.                     f.triggerBlur();
  247.                 }
  248.             }
  249.         }
  250.     }
  251.     ntTitle.on(handlers);
  252.     ntCat.on(handlers);
  253.     ntDue.on(handlers);
  254.     ntTitle.on('focus', function(){
  255.         focused = true;
  256.         if(!editing){
  257.             ntCat.enable();
  258.             ntDue.enable();
  259.             syncFields();
  260.             editing = true;
  261.         }
  262.     });
  263.     // when a field in the add bar is blurred, this determines
  264.     // whether a new task should be created
  265.     function doBlur(){
  266.         if(editing && !focused){
  267.             var title = ntTitle.getValue();
  268.             if(!Ext.isEmpty(title)){
  269.                 taskStore.addTask({
  270.                     taskId: Task.nextId(),
  271.                     title: title,
  272.                     dueDate: ntDue.getValue()||'',
  273.                     description: '', // ???
  274.                     category: ntCat.getValue(),
  275.                     completed: false
  276.                 });
  277.                 ntTitle.setValue('');
  278.                 if(userTriggered){ // if the entered to add the task, then go to a new add automatically
  279.                     userTriggered = false;
  280.                     ntTitle.focus.defer(100, ntTitle);
  281.                 }
  282.             }
  283.             ntCat.disable();
  284.             ntDue.disable();
  285.             editing = false;
  286.         }
  287.     }
  288.     var actions = {
  289.      'view-all' : function(){
  290.      taskStore.applyFilter('all');
  291.      grid.setTitle('All Tasks', 'icon-show-all');
  292.      },
  293.     
  294.      'view-active' : function(){
  295.      taskStore.applyFilter(false);
  296.      grid.setTitle('Active Tasks', 'icon-show-active');
  297.      },
  298.     
  299.      'view-complete' : function(){
  300.      taskStore.applyFilter(true);
  301.      grid.setTitle('Completed Tasks', 'icon-show-complete');
  302.      },
  303.     
  304.      'action-new' : function(){
  305.      ntTitle.focus();
  306.      },
  307.     
  308.      'action-complete' : function(){
  309.      selections.each(function(s){
  310.      s.set('completed', true);
  311.      });
  312.             taskStore.applyFilter();
  313.      },
  314.     
  315.      'action-active' : function(){
  316.      selections.each(function(s){
  317.      s.set('completed', false);
  318.      });
  319.             taskStore.applyFilter();
  320.      },
  321.     
  322.      'action-delete' : function(){
  323.      Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?', 
  324.      function(btn){
  325.                 if(btn == 'yes'){
  326.                  selections.each(function(s){
  327.      taskStore.remove(s);
  328.      });
  329.                 }
  330.             });
  331.      },
  332.     
  333.      'group-date' : function(){
  334.      taskStore.groupBy('dueDate');
  335.      },
  336.     
  337.      'group-cat' : function(){
  338.      taskStore.groupBy('category');
  339.      },
  340.     
  341.      'no-group' : function(){
  342.      taskStore.clearGrouping();
  343.      }
  344.     };
  345.     
  346.     function doAction(e, t){
  347.      e.stopEvent();
  348.      actions[t.id]();
  349.     }
  350.     
  351.     
  352.     // generates a renderer function to be used for textual date groups
  353.     function textDate(){
  354.         // create the cache of ranges to be reused
  355.         var today = new Date().clearTime(true);
  356.         var year = today.getFullYear();
  357.         var todayTime = today.getTime();
  358.         var yesterday = today.add('d', -1).getTime();
  359.         var tomorrow = today.add('d', 1).getTime();
  360.         var weekDays = today.add('d', 6).getTime();
  361.         var lastWeekDays = today.add('d', -6).getTime();
  362.         return function(date){
  363.             if(!date) {
  364.                 return '(No Date)';
  365.             }
  366.             var notime = date.clearTime(true).getTime();
  367.             if (notime == todayTime) {
  368.                 return 'Today';
  369.             }
  370.             if(notime > todayTime){
  371.                 if (notime == tomorrow) {
  372.                     return 'Tomorrow';
  373.                 }
  374.                 if (notime <= weekDays) {
  375.                     return date.format('l');
  376.                 }
  377.             }else {
  378.              if(notime == yesterday) {
  379.                  return 'Yesterday';
  380.             }
  381.             if(notime >= lastWeekDays) {
  382.                 return 'Last ' + date.format('l');
  383.             }
  384.             }            
  385.             return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y');
  386.        }
  387.     }
  388. });
  389. /* This is used to laod some demo tasks if the task database is empty */
  390. function loadDemoTasks(store){
  391. var s = new Date();
  392. // hardcoded demo tasks
  393. store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false});
  394. store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
  395. store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false});
  396. store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
  397. store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false});
  398. store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true});
  399. store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false});
  400. store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true});
  401. }
  402.