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