tasks.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:13k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.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.      width:200,
  160.      minWidth: 150,
  161.      border: false,
  162.      baseCls:'x-plain',
  163.      items: [taskActions, viewPanel, groupActions]
  164.     });
  165.     if(Ext.isAir){ // create AIR window
  166.         var win = new Ext.air.MainWindow({
  167.             layout:'border',
  168.             items: [actionPanel, grid],
  169.             title: 'Simple Tasks',
  170.             iconCls: 'icon-show-all'
  171.         }).render();
  172. }else{
  173.         var viewport = new Ext.Viewport({
  174.             layout:'border',
  175.             items: [actionPanel, grid]
  176.         });
  177.     }
  178.     var ab = actionPanel.body;
  179.     ab.on('mousedown', doAction, null, {delegate:'a'});
  180. ab.on('click', Ext.emptyFn, null, {delegate:'a', preventDefault:true});
  181.     grid.on('resize', syncFields);
  182. grid.on('columnresize', syncFields);
  183.     grid.on('afteredit', function(e){
  184.         if(e.field == 'category'){
  185.             catStore.addCategory(e.value);
  186.         }
  187.         if(e.field == taskStore.getGroupState()){
  188.             taskStore.applyGrouping();
  189.         }
  190.     });
  191.     grid.on('keydown', function(e){
  192.          if(e.getKey() == e.DELETE && !grid.editing){
  193.              actions['action-delete']();
  194.          }
  195.     });
  196.     selections.on('selectionchange', function(sm){
  197.      var bd = taskActions.body, c = sm.getCount();
  198.      bd.select('li:not(#new-task)').setDisplayed(c > 0);
  199.      bd.select('span.s').setDisplayed(c > 1);
  200.     });
  201.     // The fields in the grid's header
  202.     var ntTitle = new Ext.form.TextField({
  203.         renderTo: 'new-task-title',
  204.         emptyText: 'Add a task...'
  205.     });
  206.     var ntCat = new Ext.form.ComboBox({
  207.         renderTo: 'new-task-cat',
  208.         disabled:true,
  209.         displayField: 'text',
  210.         triggerAction: 'all',
  211.         mode:'local',
  212.         selectOnFocus:true,
  213.         listClass:'x-combo-list-small',
  214.         listeners: comboEvents
  215.     });
  216.     var ntDue = new Ext.form.DateField({
  217.         renderTo: 'new-task-due',
  218.         value: new Date(),
  219.         disabled:true,
  220.         format : "m/d/Y"
  221.     });
  222.     // syncs the header fields' widths with the grid column widths
  223.     function syncFields(){
  224.         var cm = grid.getColumnModel();
  225.         ntTitle.setSize(cm.getColumnWidth(1)-2);
  226.         ntCat.setSize(cm.getColumnWidth(2)-4);
  227.         ntDue.setSize(cm.getColumnWidth(3)-4);
  228.     }
  229.     syncFields();
  230.     var editing = false, focused = false, userTriggered = false;
  231.     var handlers = {
  232.         focus: function(){
  233.             focused = true;
  234.         },
  235.         blur: function(){
  236.             focused = false;
  237.             doBlur.defer(250);
  238.         },
  239.         specialkey: function(f, e){
  240.             if(e.getKey()==e.ENTER){
  241.                 userTriggered = true;
  242.                 e.stopEvent();
  243.                 f.el.blur();
  244.                 if(f.triggerBlur){
  245.                     f.triggerBlur();
  246.                 }
  247.             }
  248.         }
  249.     }
  250.     ntTitle.on(handlers);
  251.     ntCat.on(handlers);
  252.     ntDue.on(handlers);
  253.     ntTitle.on('focus', function(){
  254.         focused = true;
  255.         if(!editing){
  256.             ntCat.enable();
  257.             ntDue.enable();
  258.             syncFields();
  259.             editing = true;
  260.         }
  261.     });
  262.     // when a field in the add bar is blurred, this determines
  263.     // whether a new task should be created
  264.     function doBlur(){
  265.         if(editing && !focused){
  266.             var title = ntTitle.getValue();
  267.             if(!Ext.isEmpty(title)){
  268.                 taskStore.addTask({
  269.                     taskId: Task.nextId(),
  270.                     title: title,
  271.                     dueDate: ntDue.getValue()||'',
  272.                     description: '', // ???
  273.                     category: ntCat.getValue(),
  274.                     completed: false
  275.                 });
  276.                 ntTitle.setValue('');
  277.                 if(userTriggered){ // if the entered to add the task, then go to a new add automatically
  278.                     userTriggered = false;
  279.                     ntTitle.focus.defer(100, ntTitle);
  280.                 }
  281.             }
  282.             ntCat.disable();
  283.             ntDue.disable();
  284.             editing = false;
  285.         }
  286.     }
  287.     var actions = {
  288.      'view-all' : function(){
  289.      taskStore.applyFilter('all');
  290.      grid.setTitle('All Tasks', 'icon-show-all');
  291.      },
  292.     
  293.      'view-active' : function(){
  294.      taskStore.applyFilter(false);
  295.      grid.setTitle('Active Tasks', 'icon-show-active');
  296.      },
  297.     
  298.      'view-complete' : function(){
  299.      taskStore.applyFilter(true);
  300.      grid.setTitle('Completed Tasks', 'icon-show-complete');
  301.      },
  302.     
  303.      'action-new' : function(){
  304.      ntTitle.focus();
  305.      },
  306.     
  307.      'action-complete' : function(){
  308.      selections.each(function(s){
  309.      s.set('completed', true);
  310.      });
  311.             taskStore.applyFilter();
  312.      },
  313.     
  314.      'action-active' : function(){
  315.      selections.each(function(s){
  316.      s.set('completed', false);
  317.      });
  318.             taskStore.applyFilter();
  319.      },
  320.     
  321.      'action-delete' : function(){
  322.      Ext.Msg.confirm('Confirm', 'Are you sure you want to delete the selected task(s)?', 
  323.      function(btn){
  324.                 if(btn == 'yes'){
  325.                  selections.each(function(s){
  326.      taskStore.remove(s);
  327.      });
  328.                 }
  329.             });
  330.      },
  331.     
  332.      'group-date' : function(){
  333.      taskStore.groupBy('dueDate');
  334.      },
  335.     
  336.      'group-cat' : function(){
  337.      taskStore.groupBy('category');
  338.      },
  339.     
  340.      'no-group' : function(){
  341.      taskStore.clearGrouping();
  342.      }
  343.     };
  344.     
  345.     function doAction(e, t){
  346.      e.stopEvent();
  347.      actions[t.id]();
  348.     }
  349.     
  350.     
  351.     // generates a renderer function to be used for textual date groups
  352.     function textDate(){
  353.         // create the cache of ranges to be reused
  354.         var today = new Date().clearTime(true);
  355.         var year = today.getFullYear();
  356.         var todayTime = today.getTime();
  357.         var yesterday = today.add('d', -1).getTime();
  358.         var tomorrow = today.add('d', 1).getTime();
  359.         var weekDays = today.add('d', 6).getTime();
  360.         var lastWeekDays = today.add('d', -6).getTime();
  361.         return function(date){
  362.             if(!date) {
  363.                 return '(No Date)';
  364.             }
  365.             var notime = date.clearTime(true).getTime();
  366.             if (notime == todayTime) {
  367.                 return 'Today';
  368.             }
  369.             if(notime > todayTime){
  370.                 if (notime == tomorrow) {
  371.                     return 'Tomorrow';
  372.                 }
  373.                 if (notime <= weekDays) {
  374.                     return date.format('l');
  375.                 }
  376.             }else {
  377.              if(notime == yesterday) {
  378.                  return 'Yesterday';
  379.             }
  380.             if(notime >= lastWeekDays) {
  381.                 return 'Last ' + date.format('l');
  382.             }
  383.             }            
  384.             return date.getFullYear() == year ? date.format('D m/d') : date.format('D m/d/Y');
  385.        }
  386.     }
  387. });
  388. /* This is used to laod some demo tasks if the task database is empty */
  389. function loadDemoTasks(store){
  390. var s = new Date();
  391. // hardcoded demo tasks
  392. store.addTask({taskId: Task.nextId(), title:'Start documentation of Ext 2.0', category:'Ext', description:'', dueDate: s.add('d', 21), completed: false});
  393. store.addTask({taskId: Task.nextId(), title:'Release Ext 1.l Beta 2', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
  394. store.addTask({taskId: Task.nextId(), title:'Take wife to see movie', category:'Family', description:'', dueDate:s.add('d', 2), completed: false});
  395. store.addTask({taskId: Task.nextId(), title:'Finish task list demo app', category:'Ext', description:'', dueDate:s.add('d', 2), completed: false});
  396. store.addTask({taskId: Task.nextId(), title:'Do something other than work', category:'Family', description:'', dueDate:s.add('d', -1), completed: false});
  397. store.addTask({taskId: Task.nextId(), title:'Go to the grocery store', category:'Family', description:'', dueDate:s.add('d', -1), completed: true});
  398. store.addTask({taskId: Task.nextId(), title:'Reboot my computer', category:'Misc', description:'', dueDate:s, completed: false});
  399. store.addTask({taskId: Task.nextId(), title:'Respond to emails', category:'Ext', description:'', dueDate:s, completed: true});
  400. }
  401.