3 <title>The source code</title>
\r
4 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
\r
5 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
\r
7 <body onload="prettyPrint();">
\r
8 <pre class="prettyprint lang-js">Ext.BLANK_IMAGE_URL = 'images/s.gif';
\r
10 Task = Ext.data.Record.create([
\r
11 {name: 'taskId', type:'string'},
\r
12 {name: 'title', type:'string'},
\r
13 {name: 'category', type:'string'},
\r
14 {name: 'description', type:'string'},
\r
15 {name: 'dueDate', type:'date', dateFormat: 'Y-m-d H:i:s'},
\r
16 {name: 'completed', type:'boolean'}
\r
19 Task.nextId = function(){
\r
20 // if the time isn't unique enough, the addition
\r
21 // of random chars should be
\r
22 var t = String(new Date().getTime()).substr(4);
\r
23 var s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
\r
24 for(var i = 0; i < 4; i++){
\r
25 t += s.charAt(Math.floor(Math.random()*26));
\r
30 // The main grid's store
\r
31 TaskStore = function(conn){
\r
32 TaskStore.superclass.constructor.call(this, {
\r
33 sortInfo:{field: 'dueDate', direction: "ASC"},
\r
34 groupField:'dueDate',
\r
36 reader: new Ext.data.JsonReader({
\r
37 idProperty: 'taskId'
\r
41 this.proxy = new Ext.data.SqlDB.Proxy(conn, 'task', 'taskId', this);
\r
43 if(window.google){ // google needs the table created
\r
44 this.proxy.on('beforeload', this.prepareTable, conn);
\r
47 this.addEvents({newcategory: true});
\r
50 Ext.extend(TaskStore, Ext.data.GroupingStore, {
\r
51 applyFilter : function(filter){
\r
52 if(filter !== undefined){
\r
53 this.taskFilter = filter;
\r
55 var value = this.taskFilter;
\r
57 return this.clearFilter();
\r
59 return this.filterBy(function(item){
\r
60 return item.data.completed === value;
\r
64 addTask : function(data){
\r
65 this.suspendEvents();
\r
67 this.resumeEvents();
\r
68 this.loadData([data], true);
\r
69 this.suspendEvents();
\r
71 this.applyGrouping(true);
\r
72 this.resumeEvents();
\r
73 this.fireEvent('datachanged', this);
\r
74 this.fireEvent('newcategory', data.category);
\r
77 prepareTable : function(){
\r
82 fields: Task.prototype.fields
\r
84 }catch(e){console.log(e)}
\r
88 // The store for Categories
\r
89 CategoryStore = function(){
\r
90 CategoryStore.superclass.constructor.call(this, {
\r
93 fields:[{name: 'text', type:'string'}],
\r
94 sortInfo:{field:'text', direction:'ASC'},
\r
99 Ext.extend(CategoryStore, Ext.data.ArrayStore, {
\r
100 init : function(store){
\r
101 var cats = store.collect('category', false, true);
\r
102 this.loadData(cats);
\r
105 addCategory : function(cat){
\r
106 if(cat && this.indexOfId(cat) === -1){
\r
107 this.clearFilter(true);
\r
108 this.loadData([cat], true);
\r
114 // Grid column plugin that does the complete/active button in the left-most column
\r
115 CompleteColumn = function(){
\r
118 function getRecord(t){
\r
119 var index = grid.getView().findRowIndex(t);
\r
120 return grid.store.getAt(index);
\r
123 function onMouseDown(e, t){
\r
124 if(Ext.fly(t).hasClass('task-check')){
\r
126 var record = getRecord(t);
\r
127 record.set('completed', !record.data.completed);
\r
128 grid.store.applyFilter();
\r
132 function onMouseOver(e, t){
\r
133 if(Ext.fly(t).hasClass('task-check')){
\r
134 Ext.fly(t.parentNode).addClass('task-check-over');
\r
138 function onMouseOut(e, t){
\r
139 if(Ext.fly(t).hasClass('task-check')){
\r
140 Ext.fly(t.parentNode).removeClass('task-check-over');
\r
146 header: '<div class="task-col-hd"></div>',
\r
150 renderer: function(){
\r
151 return '<div class="task-check"></div>';
\r
153 init : function(xg){
\r
155 grid.on('render', function(){
\r
156 var view = grid.getView();
\r
157 view.mainBody.on('mousedown', onMouseDown);
\r
158 view.mainBody.on('mouseover', onMouseOver);
\r
159 view.mainBody.on('mouseout', onMouseOut);
\r