]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/protected/JavaScript/slide-window.js
baculum: Search field works with all table cells
[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 + '_Container';
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                 var repeater = $(this.repeaterEl);
262                 var grid = $(this.gridEl);
263                 if(grid) {
264                         dataList = grid.select('tr');
265                         this.makeSortable();
266                 } else if (repeater) {
267                         dataList = repeater.select('div.slide-window-element');
268                 }
269
270                 var set_callback_parameter = function(element) {
271                         var el = $(element).down('input[type=hidden]')
272                         if(el) {
273                                 var val = el.getValue();
274                                 this.loadRequest.ActiveControl.CallbackParameter = val;
275                                 this.loadRequest.dispatch();
276                                 this.configurationObj.openConfigurationWindow(this);
277                         }
278                 }.bind(this);
279                 this.setSearch();
280                 dataList.each(function(tr) {
281                         $(tr).observe('click', function(index, clickedEl) {
282                                 var target = clickedEl.target || clickedEl.srcElement;
283                                 var clicked = $(target.id);
284                                 // for element selection action (clicked checkbox) configuration window is not open
285                                 if(clicked && clicked.hasAttribute('type') && clicked.readAttribute('type') == 'checkbox') {
286                                         return;
287                                 }
288                                 set_callback_parameter(tr);
289                         }.bind(this, tr));
290                 }.bind(this));
291                 Formatters.set_formatters();
292                 this.revertSortingFromCookie();
293         },
294
295         isConfigurationOpen: function() {
296                 var is_open = false;
297                 $$(this.elements.configurationWindows, this.elements.configurationProgress).each(function(el) {
298                         if(el.getStyle('display') == 'block') {
299                                 is_open = true;
300                                 throw $break;
301                         }
302                 }.bind(is_open));
303                 return is_open;
304         },
305
306         sortTable: function (col, reverse, set_cookie) {
307                 var table = document.getElementById(this.gridEl);
308                 var tb = table.tBodies[0], tr = Array.prototype.slice.call(tb.rows, 0), i;
309                 reverse = -((+reverse) || -1);
310                 tr = tr.sort(function (a, b) {
311                         var val, val_a, val_b, el_a, el_b;
312                         el_a = a.cells[col].childNodes[1];
313                         el_b = b.cells[col].childNodes[1];
314                         if (el_a && el_b && el_a.nodeType === 1 && el_b.nodeType === 1 && el_a.hasAttribute('rel') && el_b.hasAttribute('rel')) {
315                                 val_a = el_a.getAttribute('rel');
316                                 val_b = el_b.getAttribute('rel');
317                         } else {
318                                 val_a = a.cells[col].textContent.trim();
319                                 val_b = b.cells[col].textContent.trim();
320                         }
321                         if (!isNaN(parseFloat(val_a)) && isFinite(val_a) && !isNaN(parseFloat(val_b)) && isFinite(val_b)) {
322                                 val = val_a - val_b
323                         } else {
324                                 val = val_a.localeCompare(val_b);
325                         }
326                         return reverse * (val);
327                 });
328                 var even;
329                 for (i = 0; i < tr.length; i++) {
330                         even = ((i % 2) == 0);
331                         if (even) {
332                                 tr[i].className = this.elements.contentItems;
333                         } else {
334                                 tr[i].className = this.elements.contentAlternatingItems;
335                         }
336                         tb.appendChild(tr[i]);
337                 }
338                 if (set_cookie === true) {
339                         Cookies.set_cookie(this.gridEl, col + ':' + reverse);
340                 }
341         },
342
343         makeSortable: function () {
344                 var self = this;
345                 var table = document.getElementById(this.gridEl);
346                 table.tHead.style.cursor = 'pointer';
347                 var th = table.tHead, i;
348                 th && (th = th.rows[0]) && (th = th.cells);
349                 if (th) {
350                         i = th.length;
351                 } else {
352                         return;
353                 }
354                 var downCounter = 0;
355                 // skip first column if in column header is input (checkbox for elements mark)
356                 if (th[0].childNodes[0].nodeName == "INPUT") {
357                         downCounter = 1;
358                 }
359                 while (--i >= downCounter) (function (i) {
360                         var dir = 1;
361                         th[i].addEventListener('click', function () {
362                                 self.sortTable(i, (dir = 1 - dir), true);
363                         });
364                 }(i));
365         },
366
367         revertSortingFromCookie: function() {
368                 var sorting = Cookies.get_cookie(this.gridEl);
369                 if (sorting != null) {
370                         var sort_param = sorting.split(':');
371                         var col = parseInt(sort_param[0], 10);
372                         var order = -(parseInt(sort_param[1], 10));
373                         this.sortTable(col, order);
374                 }
375         },
376
377         setSearch: function() {
378                 var search_pattern = new RegExp(this.search.value, 'i');
379                 var repeater = $(this.repeaterEl);
380                 var grid = $(this.gridEl);
381                 if (repeater) {
382                         repeater.select('div.' + this.elements.contentItems).each(function(value){
383                                 if(search_pattern.test(value.childNodes[2].textContent) == false) {
384                                         value.setStyle({'display' : 'none'});
385                                 } else {
386                                         value.setStyle({'display' : ''});
387                                 }
388                         }.bind(search_pattern));
389                 }
390
391                 if (grid) {
392                         grid.select('tr').each(function(value){
393                                 var tds = value.select('td');
394                                 var td;
395                                 var found = false;
396                                 for (var i = 0; i < tds.length; i++) {
397                                         td = tds[i].textContent.trim();
398                                         if(search_pattern.test(td) == true) {
399                                                 found = true;
400                                                 break;
401                                         }
402                                 }
403
404                                 if(found === true) {
405                                         value.show();
406                                 } else {
407                                         value.hide();
408                                 }
409                         }.bind(search_pattern));
410                 }
411         },
412         setElementsCount : function() {
413                 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;
414                 var count_el = $(this.windowId + this.elements.titleSuffix).getElementsByTagName('span')[0];
415                 $(count_el).update(' (' + elements_count + ')');
416         },
417         toggleToolbar: function() {
418                 if (this.isToolbarOpen() === false) {
419                         this.markAllChecked(false);
420                 }
421                 Effect.toggle($(this.windowId + this.elements.toolbarSuffix), 'slide', { duration: 0.2});
422         },
423         isToolbarOpen: function() {
424                 return $(this.windowId + this.elements.toolbarSuffix).visible();
425         },
426         setActions: function() {
427                 var checkboxes = this.getCheckboxes();
428                 checkboxes.each(function(el) {
429                         el.observe('change', function() {
430                                 var is_checked = this.isAnyChecked(checkboxes);
431                                 if(is_checked === true && !this.areActionsOpen()) {
432                                         this.showActions();
433                                 } else if (is_checked === false && this.areActionsOpen()) {
434                                         this.hideActions();
435                                 }
436                         }.bind(this));
437                 }.bind(this));
438         },
439         isAnyChecked: function(checkboxes) {
440                 var is_checked = false;
441                 checkboxes.each(function(ch) {
442                         if(ch.checked == true) {
443                                 is_checked = true;
444                                 throw $break;
445                         }
446                 });
447                 return is_checked;
448         },
449
450         getCheckboxes: function() {
451                 var grid = $(this.gridEl);
452                 var checkboxes = [];
453                 if (grid) {
454                         checkboxes = grid.select('input[name="actions_checkbox"]');
455                 }
456                 return checkboxes;
457         },
458
459         areCheckboxesChecked: function() {
460                 var checkboxes = this.getCheckboxes();
461                 return this.isAnyChecked(checkboxes);
462         },
463
464         markAllChecked: function(check) {
465                 this.checked = [];
466                 var checkboxes = this.getCheckboxes();
467                 var containerId;
468                 if(checkboxes.length > 0) {
469                         checkboxes.each(function(ch, index) {
470                                 if (ch.up('tr').visible()) {
471                                         containerId = ch.getAttribute('rel');
472                                         if (ch.checked == false && check == true) {
473                                                 ch.checked = true;
474                                         } else if (ch.checked == true && check == false) {
475                                                 ch.checked = false;
476                                         }
477                                         this.markChecked(containerId, ch.checked, ch.value);
478                                 }
479                         }.bind(this));
480                         if (containerId) {
481                                 this.packChecked(containerId);
482                         }
483                 }
484
485                 if(check) {
486                         this.showActions();
487                 } else {
488                         this.hideActions();
489                 }
490         },
491         markChecked: function(containerId, checked, param, pack) {
492                 if (this.checked.length == 0) {
493                         if(checked == true) {
494                                 this.checked.push(param);
495                         }
496                 } else {
497                         index = this.checked.indexOf(param);
498                         if(checked === true && index == -1) {
499                                 this.checked.push(param);
500                         } else if (checked === false && index > -1) {
501                                 this.checked.splice(index, 1);
502                         }
503                 }
504
505                 if(checked == true) {
506                         this.showActions();
507                 } else if(this.checked.length == 0) {
508                         this.hideActions();
509                 }
510
511                 if (pack === true) {
512                         this.packChecked(containerId);
513                 }
514         },
515         packChecked: function(containerId) {
516                 var values_packed = this.checked.join(';');
517                 $(containerId).setValue(values_packed);
518         },
519         showActions: function() {
520                 if (this.areActionsOpen()) {
521                         return;
522                 }
523                 if (this.isToolbarOpen()) {
524                         this.toggleToolbar();
525                 }
526                 Effect.toggle($(this.windowId + this.elements.actionsSuffix), 'slide', { duration: 0.2});
527         },
528         hideActions: function() {
529                 if (!this.areActionsOpen()) {
530                         return;
531                 }
532                 this.checked = [];
533                 Effect.toggle($(this.windowId + this.elements.actionsSuffix), 'slide', { duration: 0.2});
534         },
535         areActionsOpen: function() {
536                 return $(this.windowId + this.elements.actionsSuffix).visible();
537         },
538         postWindowOpen: function() {
539                 this.setActions();
540                 this.setElementsCount();
541                 this.setOptionsBtn();
542         },
543         setOptionsBtn: function() {
544                 var options_btn = this.window.getElementsByClassName(this.elements.actionsButton);
545                 var table_window = $(this.windowId + this.elements.containerSuffix).down(this.elements.content);
546                 if (options_btn.length === 1) {
547                         options_btn = options_btn[0];
548                         table_window.stopObserving('mouseover');
549                         table_window.observe('mouseover', function(e) {
550                                 var el = this.getGridRowUnderCursor(e);
551                                 if (el && (el.className == this.elements.contentItems || el.className == this.elements.contentAlternatingItems)) {
552                                         el.style.backgroundColor = '#aeb2b6';
553                                         options_btn.setStyle({display: ''});
554                                         var scroll_y = document.viewport.getScrollOffsets().top;
555                                         var y = (el.viewportOffset().top + scroll_y - 57).toString() + 'px';
556                                         options_btn.setStyle({top: y});
557                                 } else {
558                                         options_btn.setStyle({display: 'none'});
559                                 }
560                         }.bind(this));
561                         table_window.stopObserving('mouseout');
562                         table_window.observe('mouseout', function(e) {
563                                 table_window.select('TR').forEach(function(el) {
564                                         el.style.backgroundColor = '';
565                                 });;
566                                 options_btn.setStyle({display: 'none'});
567                         });
568                 }
569         },
570         getGridRowUnderCursor: function(e) {
571                 var x = e.clientX - 100;
572                 var y = e.clientY;
573                 var element_mouse_is_over = document.elementFromPoint(x, y);
574                 var el;
575                 var el_over = $(element_mouse_is_over);
576                 if (el_over && el_over.nodeName != 'TR') {
577                         el = el_over.down('tr');
578                         if (!el) {
579                                 el = el_over.up('tr');
580                         }
581                 }
582                 return el;
583         }
584 });
585
586 var SlideWindow = new SlideWindowClass()
587
588 document.observe("dom:loaded", function() {
589         if(Prototype.Browser.IE  || Prototype.Browser.Gecko || Prototype.Browser.WebKit) {
590                 $$('input[type=checkbox], input[type=submit], input[type=radio], input[type=image], a').each(function(el) {
591                         el.observe('focus', function() {
592                                 el.blur();
593                         }.bind(el));
594                 });
595         }
596 });
597
598 function setContentWidth() {
599         var content_width = $('container').getWidth() - $('menu-left').getWidth() - 1;
600         $('content').setStyle({'width': content_width + 'px'});
601 }
602
603
604 Event.observe(window, 'resize', function() {
605         setContentWidth();
606 });
607
608 document.observe("dom:loaded", function() {
609         setContentWidth();
610 });