]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/protected/JavaScript/slide-window.js
baculum: Add jobbytes and jobfiles columns in job list
[bacula/bacula] / gui / baculum / protected / JavaScript / slide-window.js
1 var SlideWindowClass = Class.create({
2
3         windowId: null,
4         window: null,
5         showEl: null,
6         hideEl: null,
7         fullSizeEl : null,
8         search: null,
9         toolbar: null,
10         tools: null,
11         titlebar: null,
12         options: null,
13         configurationObj: null,
14         loadRequest : null,
15         actionsRequest: null,
16         repeaterEl: null,
17         gridEl: null,
18         checked: [],
19         objects: {},
20         windowSize: null,
21
22         size: {
23                 widthNormal : '53%',
24                 heightNormal : '325px',
25                 widthHalf : '53%',
26                 heightHalf : '586px',
27                 widthFull : '100%',
28                 heightFull : '586px',
29                 menuWidth: '75px'
30         },
31
32         elements : {
33                 content: 'div.slide-window-content',
34                 containerSuffix: '-slide-window-container',
35                 containerProgressSuffix: '-slide-window-progress',
36                 configurationWindows: 'div.configuration',
37                 configurationProgress: 'div.configuration-progress',
38                 contentItems: 'slide-window-element',
39                 contentAlternatingItems: 'slide-window-element-alternating',
40                 toolsButtonSuffix: '-slide-window-tools',
41                 optionsButtonSuffix: '-slide-window-options',
42                 actionsSuffix: '-slide-window-actions',
43                 toolbarSuffix: '-slide-window-toolbar',
44                 titleSuffix: '-slide-window-title',
45                 actionsButton : 'actions_btn'
46         },
47
48         initialize: function(windowId, data) {
49                 if(typeof(windowId) == "undefined") {
50                         return;
51                 }
52
53                 this.windowId = windowId;
54                 this.window = $(this.windowId + this.elements.containerSuffix);
55                 this.tools = $(this.windowId + this.elements.toolsButtonSuffix);
56                 this.options = $(this.windowId + this.elements.optionsButtonSuffix);
57                 this.titlebar = $(this.windowId + this.elements.titleSuffix);
58
59                 if(data.hasOwnProperty('showId')) {
60                                 this.showEl = $(data.showId);
61                 } else {
62                         alert('slide-window.js - "showId" property does not exists.');
63                         return false;
64                 }
65
66                 if(data.hasOwnProperty('hideId')) {
67                         this.hideEl = $(data.hideId);
68                 } else {
69                         alert('slide-window.js - "hideId" property does not exists.');
70                         return false;
71                 }
72
73                 if(data.hasOwnProperty('fullSizeId')) {
74                         this.fullSizeEl = $(data.fullSizeId);
75                 } else {
76                         alert('slide-window.js - "fullSizeId" property does not exists.');
77                         return false;
78                 }
79
80                 if(data.hasOwnProperty('search')) {
81                         this.search = $(data.search);
82                 } else {
83                         alert('slide-window.js - "search" property does not exists.');
84                         return false;
85                 }
86                 this.setEvents();
87         },
88
89         objectExists: function(key) {
90                 return this.objects.hasOwnProperty(key);
91         },
92
93         registerObj: function(key, obj) {
94                 if(this.objectExists(key) === false) {
95                         this.objects[key] = obj;
96                 }
97         },
98
99         getObj: function(key) {
100                 var obj = null;
101                 if(this.objectExists(key) === true) {
102                         obj = this.objects[key];
103                 }
104                 return obj;
105         },
106
107         setEvents: function() {
108                 this.showEl.observe('click', function(){
109                         this.openWindow();
110                 }.bind(this));
111
112                 this.hideEl.observe('click', function(){
113                         this.closeWindow();
114                 }.bind(this));
115                 
116                 this.fullSizeEl.observe('click', function(){
117                         this.resetSize();
118                 }.bind(this));
119
120                 this.titlebar.observe('dblclick', function() {
121                         this.resetSize();
122                 }.bind(this));
123
124                 this.search.observe('keyup', function(){
125                         this.setSearch();
126                 }.bind(this));
127
128                 this.tools.observe('click', function() {
129                         this.toggleToolbar();
130                 }.bind(this));
131
132                 this.options.observe('click', function() {
133                         this.toggleToolbar();
134                 }.bind(this));
135
136                 this.setActionsBtnEvents();
137         },
138
139         setActionsBtnEvents: function() {
140                 var actions_btn_container = this.window.getElementsByClassName(this.elements.actionsButton);
141                 if (actions_btn_container.length === 1) {
142                         var actions_btn = actions_btn_container[0].getElementsByTagName('INPUT');
143                         if (actions_btn.length === 1) {
144                                 actions_btn[0].addEventListener('mouseup', function(e) {
145                                         var row = this.getGridRowUnderCursor(e);
146                                         var el = $(row).down('input[type=hidden]');
147                                         if(el) {
148                                                 var val = el.getValue();
149                                                 this.actionsRequest.ActiveControl.CallbackParameter = val;
150                                                 this.actionsRequest.dispatch();
151                                         }
152                                 }.bind(this));
153                         }
154                 }
155         },
156
157         openWindow : function() {
158                 this.hideOtherWindows();
159                 Effect.toggle(this.window, 'slide', { duration: 0.1, afterFinish : function() {
160                                 this.halfSizeWindow();
161                         }.bind(this)
162                 });
163         },
164
165         closeWindow : function() {
166                 Effect.toggle(this.window, 'slide', { duration: 0.3, afterFinish : function() {
167                                 this.resetSize();
168                         }.bind(this)
169                 });
170         },
171
172         isWindowOpen: function() {
173                 return !(this.window.style.display === 'none');
174         },
175
176         showProgress: function(show) {
177                 var progress = $(this.windowId + this.elements.containerProgressSuffix);
178                 if (show === true) {
179                         progress.setStyle({display: 'block'});
180                 } else if (show === false) {
181                         progress.hide();
182                 }
183         },
184
185         resetSize : function() {
186                 if(this.isConfigurationOpen()) {
187                         if(this.isFullSize()) {
188                                 this.halfSizeWindow();
189                         } else if(this.isHalfSize()) {
190                                         this.normalSizeWindow();
191                         } else if (this.isNormalSize()){
192                                 this.halfSizeWindow();
193                         } else {
194                                 this.normalSizeWindow();
195                         }
196                 } else {
197                         if(this.isFullSize()) {
198                                 this.normalSizeWindow();
199                         } else if(this.isHalfSize() || this.isNormalSize()) {
200                                 this.fullSizeWindow();
201                         }
202                 }
203         },
204
205         isNormalSize: function() {
206                 return (this.windowSize == this.size.widthNormal && this.window.getHeight()  + 'px' == this.size.heightNormal);
207         },
208
209         isHalfSize: function() {
210                 return (this.windowSize == this.size.widthHalf && this.window.getHeight()  + 'px' == this.size.heightHalf);
211         },
212
213         isFullSize: function() {
214                 return (this.windowSize  == this.size.widthFull && this.window.getHeight()  + 'px' == this.size.heightFull);
215         },
216
217         normalSizeWindow: function() {
218                         new Effect.Morph(this.window, {style : 'width: ' + this.size.widthNormal + '; height: ' + this.size.heightNormal + ';', duration : 0.4});
219                         this.windowSize = this.size.widthNormal;
220         },
221         
222         halfSizeWindow: function() {
223                         new Effect.Morph(this.window, {style : 'width: ' + this.size.widthHalf + '; height: ' + this.size.heightHalf + ';', duration : 0.4});
224                         this.windowSize = this.size.widthHalf;
225         },
226         
227         fullSizeWindow: function() {
228                         new Effect.Morph(this.window, {style : 'width: ' + this.size.widthFull + '; height: ' + this.size.heightFull + ';', duration : 0.4});
229                         this.windowSize = this.size.widthFull;
230         },
231
232         hideOtherWindows: function() {
233                 $$('.slide-window-container').each(function(el, index) {
234                         el.setStyle({
235                                 display : 'none',
236                                 width : this.size.widthNormal,
237                                 height : this.size.heightNormal
238                         });
239                 }.bind(this));
240         },
241
242         setConfigurationObj: function(obj) {
243                 this.configurationObj = obj;
244         },
245
246         setWindowElementsEvent: function(opts) {
247                 this.repeaterEl = opts.repeater_id;
248                 this.gridEl = opts.grid_id;
249                 this.loadRequest = opts.request_obj;
250                 if (opts.hasOwnProperty('actions_obj')) {
251                         this.actionsRequest = opts.actions_obj;
252                 }
253                 this.showProgress(false);
254                 this.markAllChecked(false);
255                 this.setLoadRequest();
256                 this.postWindowOpen();
257         },
258
259         setLoadRequest: function() {
260                 var dataList = [];
261                 if($(this.gridEl)) {
262                         dataList = $(this.gridEl).select('tr');
263                         this.makeSortable();
264                 } else if ($(this.repeaterEl + '_Container')) {
265                         dataList = $(this.repeaterEl + '_Container').select('div.slide-window-element');
266                 }
267
268                 var set_callback_parameter = function(element) {
269                         var el = $(element).down('input[type=hidden]')
270                         if(el) {
271                                 var val = el.getValue();
272                                 this.loadRequest.ActiveControl.CallbackParameter = val;
273                                 this.loadRequest.dispatch();
274                                 this.configurationObj.openConfigurationWindow(this);
275                         }
276                 }.bind(this);
277                 dataList.each(function(tr) {
278                         $(tr).observe('click', function(index, clickedEl) {
279                                 var target = clickedEl.target || clickedEl.srcElement;
280                                 var clicked = $(target.id);
281                                 // for element selection action (clicked checkbox) configuration window is not open
282                                 if(clicked && clicked.hasAttribute('type') && clicked.readAttribute('type') == 'checkbox') {
283                                         return;
284                                 }
285                                 set_callback_parameter(tr);
286                         }.bind(this, tr));
287                 }.bind(this));
288                 Formatters.set_formatters();
289         },
290
291         isConfigurationOpen: function() {
292                 var is_open = false;
293                 $$(this.elements.configurationWindows, this.elements.configurationProgress).each(function(el) {
294                         if(el.getStyle('display') == 'block') {
295                                 is_open = true;
296                                 throw $break;
297                         }
298                 }.bind(is_open));
299                 return is_open;
300         },
301
302         sortTable: function (col, reverse) {
303                 var table = document.getElementById(this.gridEl);
304                 var tb = table.tBodies[0], tr = Array.prototype.slice.call(tb.rows, 0), i;
305                 reverse = -((+reverse) || -1);
306                 tr = tr.sort(function (a, b) {
307                         var val;
308                         var val_a = a.cells[col].textContent.trim();
309                         var val_b = b.cells[col].textContent.trim();
310                         if (!isNaN(parseFloat(val_a)) && isFinite(val_a) && !isNaN(parseFloat(val_b)) && isFinite(val_b)) {
311                                 val = val_a - val_b
312                         } else {
313                                 val = val_a.localeCompare(val_b);
314                         }
315                         return reverse * (val);
316                 });
317                 for(i = 0; i < tr.length; i++) {
318                         var even = ((i % 2) == 0);
319                         if (even) {
320                                 tr[i].className = this.elements.contentItems;
321                         } else {
322                                 tr[i].className = this.elements.contentAlternatingItems;
323                         }
324                         tb.appendChild(tr[i]);
325                 }
326         },
327
328         makeSortable: function () {
329                 var self = this;
330                 var table = document.getElementById(this.gridEl);
331                 table.tHead.style.cursor = 'pointer';
332                 var th = table.tHead, i;
333                 th && (th = th.rows[0]) && (th = th.cells);
334                 if (th) {
335                         i = th.length;
336                 } else {
337                         return;
338                 }
339                 var downCounter = 0;
340                 // skip first column if in column header is input (checkbox for elements mark)
341                 if (th[0].childNodes[0].nodeName == "INPUT") {
342                         downCounter = 1;
343                 }
344                 while (--i >= downCounter) (function (i) {
345                         var dir = 1;
346                         th[i].addEventListener('click', function () {
347                                 self.sortTable(i, (dir = 1 - dir));
348                         });
349                 }(i));
350         },
351
352         setSearch: function() {
353                 var search_pattern = new RegExp(this.search.value)
354                 $$('div[id="' + this.windowId + this.elements.containerSuffix + '"] div.' + this.elements.contentItems).each(function(value){
355                                 
356                                 if(search_pattern.match(value.childNodes[2].textContent) == false) {
357                                         value.setStyle({'display' : 'none'});
358                                 } else {
359                                         value.setStyle({'display' : ''});
360                                 }
361                         }.bind(search_pattern));
362                         
363                         $$('div[id="' + this.windowId + this.elements.containerSuffix + '"] tr.' + this.elements.contentItems + ', div[id="' + this.windowId + this.elements.containerSuffix + '"] tr.' + this.elements.contentAlternatingItems).each(function(value){
364                                 if(search_pattern.match(value.down('div').innerHTML) == false) {
365                                         value.setStyle({'display' : 'none'});
366                                 } else {
367                                         value.setStyle({'display' : ''});
368                                 }
369                         }.bind(search_pattern));
370         },
371         setElementsCount : function() {
372                 var elements_count = $$('div[id="' + this.windowId + this.elements.containerSuffix + '"] div.' + this.elements.contentItems).length || $$('div[id="' + this.windowId + this.elements.containerSuffix + '"] tr.' + this.elements.contentItems + ', div[id="' + this.windowId + this.elements.containerSuffix + '"] tr.' + this.elements.contentAlternatingItems).length;
373                 var count_el = $(this.windowId + this.elements.titleSuffix).getElementsByTagName('span')[0];
374                 $(count_el).update(' (' + elements_count + ')');
375         },
376         toggleToolbar: function() {
377                 if (this.isToolbarOpen() === false) {
378                         this.markAllChecked(false);
379                 }
380                 Effect.toggle($(this.windowId + this.elements.toolbarSuffix), 'slide', { duration: 0.2});
381         },
382         isToolbarOpen: function() {
383                 return $(this.windowId + this.elements.toolbarSuffix).visible();
384         },
385         setActions: function() {
386                 var table = $(this.window).down('table');
387                 var checkboxes = table.select('input[name="actions_checkbox"]');
388                 checkboxes.each(function(el) {
389                         el.observe('change', function() {
390                                 var is_checked = this.is_any_checked(checkboxes);
391                                 if(is_checked === true && !this.areActionsOpen()) {
392                                         this.showActions();
393                                 } else if (is_checked === false && this.areActionsOpen()) {
394                                         this.hideActions();
395                                 }
396                         }.bind(this));
397                 }.bind(this));
398         },
399         is_any_checked: function(checkboxes) {
400                 var is_checked = false;
401                 checkboxes.each(function(ch) {
402                         if(ch.checked == true) {
403                                 is_checked = true;
404                                 throw $break;
405                         }
406                 });
407                 return is_checked;
408         },
409
410         markAllChecked: function(check) {
411                 this.checked = [];
412                 var table = $(this.window).down('table');
413                 var checkboxes = table.select('input[name="actions_checkbox"]');
414                 var containerId;
415                 if(checkboxes.length > 0) {
416                         checkboxes.each(function(ch, index) {
417                                 if (ch.up('tr').visible()) {
418                                         containerId = ch.getAttribute('rel');
419                                         if (ch.checked == false && check == true) {
420                                                 ch.checked = true;
421                                         } else if (ch.checked == true && check == false) {
422                                                 ch.checked = false;
423                                         }
424                                         this.markChecked(containerId, ch.checked, ch.value);
425                                 }
426                         }.bind(this));
427                         if (containerId) {
428                                 this.packChecked(containerId);
429                         }
430                 }
431
432                 if(check) {
433                         this.showActions();
434                 } else {
435                         this.hideActions();
436                 }
437         },
438         markChecked: function(containerId, checked, param, pack) {
439                 if (this.checked.length == 0) {
440                         if(checked == true) {
441                                 this.checked.push(param);
442                         }
443                 } else {
444                         index = this.checked.indexOf(param);
445                         if(checked === true && index == -1) {
446                                 this.checked.push(param);
447                         } else if (checked === false && index > -1) {
448                                 this.checked.splice(index, 1);
449                         }
450                 }
451
452                 if(checked == true) {
453                         this.showActions();
454                 } else if(this.checked.length == 0) {
455                         this.hideActions();
456                 }
457
458                 if (pack === true) {
459                         this.packChecked(containerId);
460                 }
461         },
462         packChecked: function(containerId) {
463                 var values_packed = this.checked.join(';');
464                 $(containerId).setValue(values_packed);
465         },
466         showActions: function() {
467                 if (this.areActionsOpen()) {
468                         return;
469                 }
470                 if (this.isToolbarOpen()) {
471                         this.toggleToolbar();
472                 }
473                 Effect.toggle($(this.windowId + this.elements.actionsSuffix), 'slide', { duration: 0.2});
474         },
475         hideActions: function() {
476                 if (!this.areActionsOpen()) {
477                         return;
478                 }
479                 this.checked = [];
480                 Effect.toggle($(this.windowId + this.elements.actionsSuffix), 'slide', { duration: 0.2});
481         },
482         areActionsOpen: function() {
483                 return $(this.windowId + this.elements.actionsSuffix).visible();
484         },
485         postWindowOpen: function() {
486                 this.setActions();
487                 this.setElementsCount();
488                 this.setOptionsBtn();
489         },
490         setOptionsBtn: function() {
491                 var options_btn = this.window.getElementsByClassName(this.elements.actionsButton);
492                 var table_window = $(this.windowId + this.elements.containerSuffix).down(this.elements.content);
493                 if (options_btn.length === 1) {
494                         options_btn = options_btn[0];
495                         table_window.stopObserving('mouseover');
496                         table_window.observe('mouseover', function(e) {
497                                 var el = this.getGridRowUnderCursor(e);
498                                 if (el && (el.className == this.elements.contentItems || el.className == this.elements.contentAlternatingItems)) {
499                                         el.style.backgroundColor = '#aeb2b6';
500                                         options_btn.setStyle({display: ''});
501                                         var scroll_y = document.viewport.getScrollOffsets().top;
502                                         var y = (el.viewportOffset().top + scroll_y - 57).toString() + 'px';
503                                         options_btn.setStyle({top: y});
504                                 } else {
505                                         options_btn.setStyle({display: 'none'});
506                                 }
507                         }.bind(this));
508                         table_window.stopObserving('mouseout');
509                         table_window.observe('mouseout', function(e) {
510                                 table_window.select('TR').forEach(function(el) {
511                                         el.style.backgroundColor = '';
512                                 });;
513                                 options_btn.setStyle({display: 'none'});
514                         });
515                 }
516         },
517         getGridRowUnderCursor: function(e) {
518                 var x = e.clientX - 100;
519                 var y = e.clientY;
520                 var element_mouse_is_over = document.elementFromPoint(x, y);
521                 var el;
522                 var el_over = $(element_mouse_is_over);
523                 if (el_over && el_over.nodeName != 'TR') {
524                         el = el_over.down('tr');
525                         if (!el) {
526                                 el = el_over.up('tr');
527                         }
528                 }
529                 return el;
530         }
531 });
532
533 var SlideWindow = new SlideWindowClass()
534
535 document.observe("dom:loaded", function() {
536         if(Prototype.Browser.IE  || Prototype.Browser.Gecko || Prototype.Browser.WebKit) {
537                 $$('input[type=checkbox], input[type=submit], input[type=radio], input[type=image], a').each(function(el) {
538                         el.observe('focus', function() {
539                                 el.blur();
540                         }.bind(el));
541                 });
542         }
543 });
544
545 function setContentWidth() {
546         var content_width = $('container').getWidth() - $('menu-left').getWidth() - 1;
547         $('content').setStyle({'width': content_width + 'px'});
548 }
549
550
551 Event.observe(window, 'resize', function() {
552         setContentWidth();
553 });
554
555 document.observe("dom:loaded", function() {
556         setContentWidth();
557 });