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