Updated to work better with new Additionals widget
[ajatus.git] / js / ajatus.renderer.js
blob92f7208b884d227b808a243d4f5c8a1e151faaea
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: 500,
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: 40,
128             preload_distance: 1000,
129             use_db: false,
130             db: {}
131         }, settings);
132         
133         this.render_lock = false;
134         
135         this.renderer = renderer;
136         
137             this.items = [];
138             this.done_items = [];
139             this.started = false;
140             
141             this.status_holder = null;
142             this.spacer = null;
143             
144             this.from_back_btn = false;
145             
146             this.scroller_id = $.ajatus.utils.generate_id();
147             this.mouse_state = 'up';
148             this.page_count = 1;
149             this.total_docs = 0;
150             
151             this.done_items = 0;
152     };    
153     $.extend($.ajatus.renderer._scroll.prototype, {
154             add_item: function(callback, args) {
155             var item = {
156                 callback: callback,
157                 args: args || []
158             };
159                 this.items.push(item);
160                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
161             },
162             
163             items_added: function(total_docs) {
164                 if (! this.started) {
165                     this.start();
166                 }
167             
168             if (   this.settings.use_db
169                 && typeof total_docs != 'undefined')
170             {
171                 this.total_docs = total_docs;
172                 this.page_count = (total_docs / this.settings.items_per_page);
173             } else {
174                 this.page_count = (this.items.length / this.settings.items_per_page);
175             }
176             
177                 $('div.renderer_scroll_status_holder .total_pages').val(this.page_count);
178             },
179             
180             load_items: function(d) {
181                 if (   typeof d == 'undefined'
182                     || d == null)
183                 {
184                     var opts = {
185                     descending: true,
186                     count: 1
187                 };
188                 if (typeof this.settings.db.static != 'undefined') {
189                     var d = $.jqCouch.connection('view').get($.ajatus.preferences.client.content_database, this.settings.db.static, opts).rows[0];
190                 } else {
191                     var d = $.jqCouch.connection('view').temp($.ajatus.preferences.client.content_database, this.settings.db.temp, opts).rows[0];
192                 }
193                 }
195             var _self = this;
196             var on_success = function(data) {                
197                 $.each(data.rows, function(i,doc){
198                     var doc = new $.ajatus.document(doc);
199                     
200                     if ($.ajatus.tags.active != '') {
201                         if ($.ajatus.utils.array.has_match($.ajatus.tags.active, doc.value.tags.val)) {
202                             _self.renderer.render_item(doc, i);                            
203                         }
204                     } else {
205                         _self.renderer.render_item(doc, i);
206                     }
207                 });
209                 return data;
210             };
212             var opts = {
213                 descending: true,
214                 startkey: d.key,
215                 startkey_docid: d._id || d.id,
216                 count: this.settings.items_per_page
217             };
218             if (typeof this.settings.db.static != 'undefined') {
219                 $.jqCouch.connection('view', on_success).get($.ajatus.preferences.client.content_database, this.settings.db.static, opts);
220             } else {
221                 $.jqCouch.connection('view', on_success).temp($.ajatus.preferences.client.content_database, this.settings.db.temp, opts);
222             }
223             },
224             
225             start: function() {
226                 if (this.started) {
227                     return;
228             }
229             
230             $.ajatus.events.named_lock_pool.clear('scroll_renderer');
231             
232                 if (this.status_holder == null) {
233                     this.status_holder = $('<div class="renderer_scroll_status_holder" />').appendTo($.ajatus.application_content_area).hide();
234                     $('<input type="hidden" name="scroll_id" class="scroll_id" />').val(this.scroller_id).appendTo(this.status_holder);
235                     $('<input type="hidden" name="scroll_total_pages" class="total_pages" />').val('1').appendTo(this.status_holder);
236                     $('<input type="hidden" name="scroll_history_index" class="history_index" />').val('').appendTo(this.status_holder);
237                     $('<input type="hidden" name="scroll_mouse_state" class="mouse_state" />').val('up').appendTo(this.status_holder);
238                 }
239                 
240                 if (this.spacer == null) {
241                     this.spacer = $('<div class="renderer_scroll_spacer" />').appendTo($.ajatus.application_content_area).css({
242                         position: 'absolute',
243                         top: '0px',
244                         left: '0px',
245                         visibility: 'hidden'
246                     });
247                 }
248                 
249                 var _self = this;
250                 $(document).mousedown(function(e){
251                 $('.mouse_state', _self.status_holder).val('down');
252                 _self.mouse_state = 'down';
253                 
254                 $.cookie(_self.scroller_id+"_height", $(document).scrollTop());
255                 $.cookie(_self.scroller_id+"_scroll", $(document).scrollTop() - $(document).height());
256                 });
257                 $(document).mouseup(function(e){
258                     $('.mouse_state', _self.status_holder).val('up');
259                     _self.mouse_state = 'up';
260                 });
261                                 
262                 if ($.cookie(this.scroller_id)) {
263                     this.from_back_btn = true;
264                 } else {
265                     $.cookie(this.scroller_id, "1");
266                 }
267                 
268                 if( this.from_back_btn ) {
269                         $(".renderer_scroll_spacer").css({
270                             height: $.cookie(this.scroller_id+"_height") + "px"
271                         });
272                         scroll(0, $.cookie(this.scroller_id+"_scroll") );
273                 }
274                 
275                 $('.history_index', this.status_holder).val('1');
276                 
277                 this._create_lock();
278                 
279                 $.ajatus.views.on_change_actions.add('$.ajatus.events.named_lock_pool.clear("scroll_renderer");');
280                 
281                 this.started = true;
282             },
283             
284             _on_tick: function() {
285                 var _self = this;
286                 
287                 if (   !this.settings.use_db
288                     && this.items.length == 0)
289                 {
290                     $.ajatus.events.named_lock_pool.clear('scroll_renderer');
291                     return true;
292                 }
293                 
294             // console.log("_on_tick this.page_count: "+this.page_count);
295             // console.log("_on_tick history_index: "+$('.history_index', this.status_holder).val());
296             // console.log("_on_tick this.items.length: "+this.items.length);
297                 
298                 if (this.mouse_state == 'up' && $(document).height() - $(document).scrollTop() < this.settings.preload_distance) {                  
299                     if (this.settings.use_db) {
300                         var last_doc = null;
301                         $.each(this.items, function(i,n){
302                             last_doc = n.args[1];
303                             
304                         var functionToCall = eval(n.callback);
306                         if (functionToCall.apply(functionToCall, n.args)) {
307                                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
308                                 _self.done_items += 1;
309                         }
310                         });
312                         this.items = [];
313                         if (this.done_items < this.total_docs) {
314                             this.load_items(last_doc);
315                         }
316                 } else {
317                         this.items = $.grep(this.items, function(n, i){
318                             if (i < _self.settings.items_per_page)
319                             {
320                             var functionToCall = eval(n.callback);
322                             if (functionToCall.apply(functionToCall, n.args)) {
323                                 $.ajatus.events.named_lock_pool.decrease('scroll_renderer');
324                             }
325                             } else {
326                                 return true;
327                             }
328                         });
329                 }
330                     
331                 var hi = $('.history_index', this.status_holder).val();
332                 $('.history_index', this.status_holder).val(parseInt(hi)+1);
333                 this.renderer.enable_sorting();
334                 }
335                 
336                 if (parseInt($('.history_index', this.status_holder).val()) > this.page_count && this.page_count != 1 && this.items.length <= 0) {
337                     $.ajatus.events.named_lock_pool.clear('scroll_renderer');
338                     return true;
339             }
340             },
341             
342             _create_lock: function() {
343                 var _self = this;
344             _self.render_lock = new $.ajatus.events.lock({
345                 disable_application: false,
346                 watch: {                    
347                     validate: function() {
348                         _self._on_tick();
349                         return $.ajatus.events.named_lock_pool.count('scroll_renderer') == 0;
350                     },
351                     interval: 200,
352                     safety_runs: 2,
353                     max_runs: false
354                 },
355                 on_release: function() {
356                     _self._lock_finished();
357                 }
358             });
359             },
360             
361             _lock_finished: function() {
362             }
363     });
365 })(jQuery);