Added license header
[ajatus.git] / js / ajatus.renderer.js
blobe333b11bf7f8b2e59450b01e1f11355641c5dece
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
16     $.ajatus = $.ajatus || {};
17     
18     $.ajatus.renderer_defaults = {
19         type: 'block',
20         tick_limit: 20,
21         max_item_before_pool: 20,
22         items_per_page: 40,
23         use_db_after: 100,
24     };
25     
26     $.ajatus.renderer = function(settings, r) {
27         this.settings = $.extend({}, $.ajatus.renderer_defaults, (settings || {}));
29         if (this.settings.type == 'block') {
30             this.handler = new $.ajatus.renderer._block(this.settings, r);
31         } else if (this.settings.type == 'scroll') {
32             this.handler = new $.ajatus.renderer._scroll(this.settings, r);
33         }
34         };
35         $.extend($.ajatus.renderer.prototype, {
36             add_item: function(callback, args) {
37             this.handler.add_item(callback, args);
38             },
39             
40             items_added: function(doc_count) {
41                 if (typeof this.handler.items_added == 'function') {
42                     this.handler.items_added(doc_count);
43             }
44             },
45             
46             start: function() {
47                 this.handler.start();
48             }
49         });
50         
51         $.ajatus.renderer._block = function(settings, renderer) {
52         this.settings = $.extend({
53             tick_limit: 20,
54             max_item_before_pool: 20
55         }, settings);
56         this.render_lock = false;           
57             this.items = [];
58             this.done_items = [];
59             
60             this.renderer = renderer;
61     };
62         $.extend($.ajatus.renderer._block.prototype, {
63             add_item: function(callback, args) {
64             var item = {
65                 callback: callback,
66                 args: args || []
67             };
68                 this.items.push(item);
69                 $.ajatus.events.named_lock_pool.increase('block_renderer');
70                 
71                 if (! this.render_lock) {
72                     this.start();
73                 }
74             },
75             
76             start: function() {
77             this._create_lock();
78             },
79             
80             _on_tick: function() {
81                 var _self = this;
82                 if (this.items.length == 0)
83                 {
84                     $.ajatus.events.named_lock_pool.clear('block_renderer')
85                     return true;
86                 }
87                 this.items = $.grep(this.items, function(n, i){
88                     if (i < _self.settings.tick_limit)
89                     {                   
90                         var functionToCall = eval(n.callback);
91                         
92                     if (functionToCall.apply(functionToCall, n.args)) {
93                         _self.done_items.push(i);
94                         $.ajatus.events.named_lock_pool.decrease('block_renderer');
95                     }
96                     } else {
97                         return true;
98                     }               
99                 });
100                 this.renderer.enable_sorting();
101             },
102             
103             _create_lock: function() {
104                 var _self = this;
105             _self.render_lock = new $.ajatus.events.lock({
106                 disable_application: false,
107                 watch: {                    
108                     validate: function() {
109                         _self._on_tick();
110                         return $.ajatus.events.named_lock_pool.count('block_renderer') == 0;
111                     },
112                     interval: 400,
113                     safety_runs: 2
114                 },
115                 on_release: function() {
116                     _self._lock_finished();
117                 }
118             });
119             },
120             
121             _lock_finished: function() {
122             }
123     });
125     $.ajatus.renderer._scroll = function(settings, renderer) {
126         this.settings = $.extend({
127             items_per_page: 30,
128             preload_distance: 900,
129             use_db: false,
130             db: {},
131             render_item_after_load: true
132         }, settings);
133         
134         this.render_lock = false;
135         
136         this.renderer = renderer;
137         
138             this.items = [];
139             this.done_items = [];
140             this.started = false;
141             
142             this.status_holder = null;
143             this.spacer = null;
144             
145             this.from_back_btn = false;
146             
147             this.scroller_id = $.ajatus.utils.generate_id();
148             this.mouse_state = 'up';
149             this.page_count = 1;
150             this.total_docs = 0;
151             
152             this.done_items = 0;
153             
154             this.indicator = new $.ajatus.elements.indicator();
155     };    
156     $.extend($.ajatus.renderer._scroll.prototype, {
157             add_item: function() {
158                 var item = {};
159                 if (typeof arguments[0] == 'object')
160                 {
161                     item = {
162                         doc: arguments[0]
163                     };
164                 } else {
165                     if (   arguments.length >= 1
166                         && typeof arguments[0] == 'string')
167                     {
168                         item = {
169                         callback: arguments[0],
170                         args: arguments[1] || []
171                     };
172                     }
173                 }
174                 
175                 this.items.push(item);
176                 $.ajatus.events.named_lock_pool.increase('scroll_renderer');
177             },
178             
179             items_added: function(total_docs) {
180                 if (! this.started) {
181                     this.start();
182                 }
183             
184             if (   this.settings.use_db
185                 && typeof total_docs != 'undefined')
186             {                
187                 this.total_docs = total_docs;
188                 this.page_count = (total_docs / this.settings.items_per_page);
189             } else {
190                 this.page_count = (this.items.length / this.settings.items_per_page);
191             }
192             
193                 $('div.renderer_scroll_status_holder .total_pages').val(this.page_count);
194             },
195             
196             load_items: function(d) {
197             // console.log("load_items: ");
198             // console.log(d);
199                 
200                 this.indicator.show();
201                 
202                 if (   typeof d == 'undefined'
203                     || d == null)
204                 {
205                     var opts = {
206                     descending: true,
207                     count: 1
208                 };
209                 if (typeof this.settings.db.static != 'undefined') {
210                     var d = $.jqCouch.connection('view').get($.ajatus.preferences.client.content_database, this.settings.db.static, opts).rows[0];
211                 } else {
212                     var d = $.jqCouch.connection('view').temp($.ajatus.preferences.client.content_database, this.settings.db.temp, opts).rows[0];
213                 }
214                 }
216             var _self = this;
217             var on_success = function(data) {
218                 $.each(data.rows, function(i,doc){
219                     var doc = new $.ajatus.document(doc);
220                     if (_self.settings.render_item_after_load) {
221                         _self.renderer.render_item(doc, i);
222                     } else {
223                         _self.add_item(doc);
224                     }
225                 });
226                 
227                 _self.indicator.hide();
228                 
229                 return data;
230             };
232             var opts = {
233                 descending: true,
234                 startkey: '"'+d.key+'"',
235                 startkey_docid: d._id || d.id,
236                 count: this.settings.items_per_page,
237                 skip: 1
238             };
239             if (typeof this.settings.db.static != 'undefined') {
240                 $.jqCouch.connection('view', on_success).get($.ajatus.preferences.client.content_database, this.settings.db.static, opts);
241             } else {
242                 $.jqCouch.connection('view', on_success).temp($.ajatus.preferences.client.content_database, this.settings.db.temp, opts);
243             }
244             },
245             
246             start: function() {
247                 if (this.started) {
248                     return;
249             }
250             
251             $.ajatus.events.named_lock_pool.clear('scroll_renderer');
252             
253                 if (this.status_holder == null) {
254                     this.status_holder = $('<div class="renderer_scroll_status_holder" />').appendTo($.ajatus.application_content_area).hide();
255                     $('<input type="hidden" name="scroll_id" class="scroll_id" />').val(this.scroller_id).appendTo(this.status_holder);
256                     $('<input type="hidden" name="scroll_total_pages" class="total_pages" />').val('1').appendTo(this.status_holder);
257                     $('<input type="hidden" name="scroll_history_index" class="history_index" />').val('').appendTo(this.status_holder);
258                     $('<input type="hidden" name="scroll_mouse_state" class="mouse_state" />').val('up').appendTo(this.status_holder);
259                 }
260                 
261                 if (this.spacer == null) {
262                     this.spacer = $('<div class="renderer_scroll_spacer" />').appendTo($.ajatus.application_content_area).css({
263                         position: 'absolute',
264                         top: '0px',
265                         left: '0px',
266                         visibility: 'hidden'
267                     });
268                 }
269                 
270                 var _self = this;
271                 $(document).mousedown(function(e){
272                 $('.mouse_state', _self.status_holder).val('down');
273                 _self.mouse_state = 'down';
274                 });
275                 $(document).mouseup(function(e){
276                     $('.mouse_state', _self.status_holder).val('up');
277                     _self.mouse_state = 'up';
278                 });
279                 
280                 $('.history_index', this.status_holder).val('1');
281                 
282                 this._create_lock();
283                 
284                 $.ajatus.views.on_change_actions.add('$.ajatus.events.named_lock_pool.clear("scroll_renderer");');
285                 
286                 this.started = true;
287             },
288             
289             _on_tick: function() {
290                 var _self = this;
291                 
292                 if (   !this.settings.use_db
293                     && this.items.length == 0)
294                 {
295                     $.ajatus.events.named_lock_pool.clear('scroll_renderer');
296                     return true;
297                 }
298                 
299             // console.log("this.total_docs: "+this.total_docs);
300             // console.log("this.done_items: "+this.done_items);
301             // console.log("_on_tick this.page_count: "+this.page_count);
302             // console.log("_on_tick history_index: "+$('.history_index', this.status_holder).val());
303             // console.log("_on_tick this.items.length: "+this.items.length);
304                 
305                 if (this.mouse_state == 'up' && $(document).height() - $(document).scrollTop() < this.settings.preload_distance) {                  
306                     if (this.settings.use_db) {
307                         this.indicator.show();
308                         
309                         var last_doc = null;
310                         $.each(this.items, function(i,n){
311                             if (typeof n['doc'] != 'undefined') {
312                                 last_doc = n.doc;
314                                 if (_self.renderer.render_item(n.doc, i)) {
315                                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
316                                 _self.done_items += 1;                              
317                                 }
319                                 return true;
320                         }
321                         
322                             last_doc = n.args[1];
323                             
324                         var functionToCall = eval(n.callback);
326                         if (functionToCall.apply(functionToCall, n.args)) {
327                                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
328                                 _self.done_items += 1;
329                         }
330                         });
331                     
332                     this.items = [];
333                         if (this.done_items < this.total_docs) {
334                             this.load_items(last_doc);
335                         }
336                 } else {
337                     this.indicator.show();
338                     
339                         this.items = $.grep(this.items, function(n, i){
340                             if (i < _self.settings.items_per_page)
341                             {
342                             if (typeof n['doc'] != 'undefined') {
343                                 if (_self.renderer.render_item(n.doc, i)) {
344                                         $.ajatus.events.named_lock_pool.decrease('scroll_renderer');                                        
345                                 }
347                                 return false;
348                                 }
349                                 
350                             var functionToCall = eval(n.callback);
352                             if (functionToCall.apply(functionToCall, n.args)) {
353                                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
354                             }
355                             } else {
356                                 return true;
357                             }
358                         });
359                         
360                         this.indicator.hide();
361                 }
362                     
363                 var hi = $('.history_index', this.status_holder).val();
364                 $('.history_index', this.status_holder).val(parseInt(hi)+1);
365                 this.renderer.enable_sorting();
366                 }
367                 
368                 if (parseInt($('.history_index', this.status_holder).val()) > this.page_count && this.page_count != 1 && this.items.length <= 0) {
369                     $.ajatus.events.named_lock_pool.clear('scroll_renderer');               
370                     return true;
371             }
372             },
373             
374             _create_lock: function() {
375                 var _self = this;
376                 $.ajatus.events.named_lock_pool.increase('scroll_renderer');
377                 
378             _self.render_lock = new $.ajatus.events.lock({
379                 disable_application: false,
380                 watch: {                    
381                     validate: function() {
382                         _self._on_tick();
383                         return $.ajatus.events.named_lock_pool.count('scroll_renderer') == 0;
384                     },
385                     interval: 200,
386                     safety_runs: 2,
387                     max_runs: false
388                 },
389                 on_release: function() {
390                     _self._lock_finished();
391                 }
392             });
393             },
394             
395             _lock_finished: function() {
396                 this.indicator.close();
397             }
398     });
400 })(jQuery);