2 * Copyright (C) 2009 Bruno Prémont <bonbons AT linux-vserver.org>
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; only version 2 of the License is applicable.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 // Toggle visibility of a div
19 function toggleDiv(divID) {
20 var div = document.getElementById(divID);
21 var label = document.getElementById(divID+'_sw');
24 if (div.style.display == 'none') {
25 div.style.display = 'block';
28 div.style.display = 'none';
32 if (label_txt && label) {
33 var childCnt = label.childNodes.length;
35 label.removeChild(label.childNodes[--childCnt]);
36 label.appendChild(document.createTextNode(label_txt));
40 // DHTML helper code to asynchronous loading of content
41 function loadXMLDoc(url, query) {
42 if (window.XMLHttpRequest) {
43 req = new XMLHttpRequest();
44 req.onreadystatechange = processReqChange;
45 req.open('POST', url, true);
46 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
48 } else if (window.ActiveXObject) {
49 req = new ActiveXObject("Microsoft.XMLHTTP");
51 req.onreadystatechange = processReqChange;
52 req.open('POST', url, true);
53 req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
59 // DHTML new-content dispatcher
60 function processReqChange() {
61 if (req.readyState == 4) {
62 if (req.status == 200) {
63 response = req.responseXML.documentElement;
64 method = response.getElementsByTagName('method')[0].firstChild.data;
65 result = response.getElementsByTagName('result')[0];
66 eval(method + '(result)');
71 // Update contents of a <select> drop-down list
72 function refillSelect(options, select) {
76 var childCnt = select.childNodes.length;
77 var oldValue = select.selectedIndex > 0 ? select.options[select.selectedIndex].value : '/';
79 select.removeChild(select.childNodes[--childCnt]);
81 var optCnt = options ? options.length : 0;
83 select.setAttribute('disabled', 'disabled');
86 select.removeAttribute('disabled');
87 var keepSelection = false;
90 oldValue = options[0].firstChild ? options[0].firstChild.data : '';
91 } else if (oldValue != '/') {
92 for (i = 0; i < optCnt && !keepSelection; i++)
93 if (oldValue == (options[i].firstChild ? options[i].firstChild.data : ''))
96 newOption = document.createElement("option");
97 newOption.value = '/';
99 newOption.setAttribute('disabled', 'disabled');
101 newOption.setAttribute('selected', 'selected');
102 newOption.setAttribute('style', 'font-style: italic');
103 newOption.appendChild(document.createTextNode('- please select -'));
104 select.appendChild(newOption);
105 for (i = 0; i < optCnt; i++) {
106 newOption = document.createElement("option");
107 newOption.value = options[i].firstChild ? options[i].firstChild.data : '';
108 if (keepSelection && newOption.value == oldValue)
109 newOption.setAttribute('selected', 'selected');
110 if (keepSelection && optCnt == 1 && newOption.value == '@') {
111 newOption.setAttribute('style', 'font-style: italic');
112 newOption.appendChild(document.createTextNode('Meta graph'));
114 newOption.appendChild(document.createTextNode(newOption.value));
115 select.appendChild(newOption);
117 return keepSelection ? select.selectedIndex : -1;
121 // Request refresh of host list
122 function ListRefreshHost() {
123 var query = 'action=list_hosts';
124 loadXMLDoc(dhtml_url, query);
127 // Handle update to host list
128 function ListOfHost(response) {
129 var select = document.getElementById('host_list');
130 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
137 // Request refresh of plugin list
138 function ListRefreshPlugin() {
139 var host_list = document.getElementById('host_list');
140 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
142 var query = 'action=list_plugins&host='+encodeURIComponent(host);
143 loadXMLDoc(dhtml_url, query);
149 // Handle update to plugin list
150 function ListOfPlugin(response) {
151 var select = document.getElementById('plugin_list');
152 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
154 ListRefreshPluginInstance();
156 ListOfPluginInstance(null);
159 // Request refresh of plugin instance list
160 function ListRefreshPluginInstance() {
161 var host_list = document.getElementById('host_list');
162 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
163 var plugin_list = document.getElementById('plugin_list');
164 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
165 if (host != '/' && plugin != '/') {
166 var query = 'action=list_pinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin);
167 loadXMLDoc(dhtml_url, query);
169 ListOfPluginInstance(null);
173 // Handle update of plugin instance list
174 function ListOfPluginInstance(response) {
175 var select = document.getElementById('pinst_list');
176 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
183 // Request refresh of type list
184 function ListRefreshType() {
185 var host_list = document.getElementById('host_list');
186 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
187 var plugin_list = document.getElementById('plugin_list');
188 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
189 var pinst_list = document.getElementById('pinst_list');
190 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
191 if (host != '/' && plugin != '/' && pinst != '/') {
192 var query = 'action=list_types&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst);
193 loadXMLDoc(dhtml_url, query);
199 // Handle update of type list
200 function ListOfType(response) {
201 var select = document.getElementById('type_list');
202 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
204 ListRefreshTypeInstance();
206 ListOfTypeInstance(null);
209 // Request refresh of type instance list
210 function ListRefreshTypeInstance() {
211 var host_list = document.getElementById('host_list');
212 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
213 var plugin_list = document.getElementById('plugin_list');
214 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
215 var pinst_list = document.getElementById('pinst_list');
216 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
217 var type_list = document.getElementById('type_list');
218 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
219 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
220 var query = 'action=list_tinsts&host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
221 loadXMLDoc(dhtml_url, query);
223 ListOfTypeInstance(null);
227 // Handle update of type instance list
228 function ListOfTypeInstance(response) {
229 var select = document.getElementById('tinst_list');
230 var idx = refillSelect(response ? response.getElementsByTagName('option') : null, select);
235 // Disable add button
240 function RefreshButtons() {
241 var host_list = document.getElementById('host_list');
242 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
243 var plugin_list = document.getElementById('plugin_list');
244 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
245 var pinst_list = document.getElementById('pinst_list');
246 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
247 var type_list = document.getElementById('type_list');
248 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
249 var tinst_list = document.getElementById('tinst_list');
250 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
251 if (host != '/' && plugin != '/' && pinst != '/' && type != '/' && tinst != '/') {
252 document.getElementById('btnAdd').removeAttribute('disabled');
254 document.getElementById('btnAdd').setAttribute('disabled', 'disabled');
257 var graphs = document.getElementById('graphs');
258 if (graphs.getElementsByTagName('div').length > 1) {
259 document.getElementById('btnClear').removeAttribute('disabled');
260 document.getElementById('btnRefresh').removeAttribute('disabled');
262 document.getElementById('btnClear').setAttribute('disabled', 'disabled');
263 document.getElementById('btnRefresh').setAttribute('disabled', 'disabled');
269 function GraphAppend() {
270 var graphs = document.getElementById('graphs');
271 var host_list = document.getElementById('host_list');
272 var host = host_list.selectedIndex >= 0 ? host_list.options[host_list.selectedIndex].value : '/';
273 var plugin_list = document.getElementById('plugin_list');
274 var plugin = plugin_list.selectedIndex >= 0 ? plugin_list.options[plugin_list.selectedIndex].value : '/';
275 var pinst_list = document.getElementById('pinst_list');
276 var pinst = pinst_list.selectedIndex >= 0 ? pinst_list.options[pinst_list.selectedIndex].value : '/';
277 var type_list = document.getElementById('type_list');
278 var type = type_list.selectedIndex >= 0 ? type_list.options[type_list.selectedIndex].value : '/';
279 var tinst_list = document.getElementById('tinst_list');
280 var tinst = tinst_list.selectedIndex >= 0 ? tinst_list.options[tinst_list.selectedIndex].value : '/';
282 if (host != '/' && plugin != '/' && pinst != '/' && type != '/') {
283 var graph_id = 'graph_'+nextGraphId++;
284 var graph_src = graph_url+'?host='+encodeURIComponent(host)+'&plugin='+encodeURIComponent(plugin)+'&plugin_instance='+encodeURIComponent(pinst)+'&type='+encodeURIComponent(type);
288 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type;
289 graph_title = type+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
291 graph_alt = host+'/'+plugin+(pinst.length > 0 ? '-'+pinst : '')+'/'+type+(tinst.length > 0 ? '-'+tinst : '');
292 graph_title = type+(tinst.length > 0 ? '-'+tinst : '')+' of '+plugin+(pinst.length > 0 ? '-'+pinst : '')+' plugin for '+host;
293 graph_src += '&type_instance='+encodeURIComponent(tinst);
295 if (document.getElementById('logarithmic').checked)
296 graph_src += '&logarithmic=1';
297 if (document.getElementById('tinylegend').checked)
298 graph_src += '&tinylegend=1';
299 if (document.getElementById('timespan').selectedIndex >= 0)
300 graph_src += '×pan='+encodeURIComponent(document.getElementById('timespan').options[document.getElementById('timespan').selectedIndex].value);
301 var now = new Date();
302 graph_src += '&ts='+now.getTime();
305 newGraph = document.createElement('div');
306 newGraph.setAttribute('class', 'graph');
307 newGraph.setAttribute('id', graph_id);
308 // Graph cell + graph
309 newDiv = document.createElement('div');
310 newDiv.setAttribute('class', 'graph_img');
311 newImg = document.createElement('img');
312 newImg.setAttribute('src', graph_src);
313 newImg.setAttribute('alt', graph_alt);
314 newImg.setAttribute('title', graph_title);
315 newDiv.appendChild(newImg);
316 newGraph.appendChild(newDiv);
318 newDiv = document.createElement('div');
319 newDiv.setAttribute('class', 'graph_opts');
321 newImg = document.createElement('img');
322 newImg.setAttribute('src', 'move-up.png');
323 newImg.setAttribute('alt', 'UP');
324 newImg.setAttribute('title', 'Move graph up');
325 newA = document.createElement('a');
326 newA.setAttribute('href', 'javascript:GraphMoveUp("'+graph_id+'")');
327 newA.appendChild(newImg);
328 newDiv.appendChild(newA);
329 newDiv.appendChild(document.createElement('br'));
331 newImg = document.createElement('img');
332 newImg.setAttribute('src', 'refresh.png');
333 newImg.setAttribute('alt', 'R');
334 newImg.setAttribute('title', 'Refresh graph');
335 newA = document.createElement('a');
336 newA.setAttribute('href', 'javascript:GraphRefresh("'+graph_id+'")');
337 newA.appendChild(newImg);
338 newDiv.appendChild(newA);
339 newDiv.appendChild(document.createElement('br'));
341 newImg = document.createElement('img');
342 newImg.setAttribute('src', 'delete.png');
343 newImg.setAttribute('alt', 'RM');
344 newImg.setAttribute('title', 'Remove graph');
345 newA = document.createElement('a');
346 newA.setAttribute('href', 'javascript:GraphRemove("'+graph_id+'")');
347 newA.appendChild(newImg);
348 newDiv.appendChild(newA);
349 newDiv.appendChild(document.createElement('br'));
351 newImg = document.createElement('img');
352 newImg.setAttribute('src', 'move-down.png');
353 newImg.setAttribute('alt', 'DN');
354 newImg.setAttribute('title', 'Move graph down');
355 newA = document.createElement('a');
356 newA.setAttribute('href', 'javascript:GraphMoveDown("'+graph_id+'")');
357 newA.appendChild(newImg);
358 newDiv.appendChild(newA);
359 newGraph.appendChild(newDiv);
361 graphs.appendChild(newGraph);
363 document.getElementById('nograph').style.display = 'none';
367 function GraphDropAll() {
368 var graphs = document.getElementById('graphs');
369 var childCnt = graphs.childNodes.length;
371 if (graphs.childNodes[--childCnt].id != 'nograph' && (graphs.childNodes[childCnt].nodeName == 'div' || graphs.childNodes[childCnt].nodeName == 'DIV'))
372 graphs.removeChild(graphs.childNodes[childCnt]);
373 else if (graphs.childNodes[childCnt].id == 'nograph')
374 graphs.childNodes[childCnt].style.display = 'block';
378 function GraphRefresh(graph) {
380 var imgs = document.getElementById('graphs').getElementsByTagName('img');
381 var imgCnt = imgs.length;
382 var now = new Date();
383 var newTS = '&ts='+now.getTime();
385 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph_img') {
386 var oldSrc = imgs[imgCnt].src;
387 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
388 if (newSrc == oldSrc)
389 newSrc = newSrc + newTS;
390 imgs[imgCnt].setAttribute('src', newSrc);
392 } else if (document.getElementById(graph)) {
393 var imgs = document.getElementById(graph).getElementsByTagName('img');
394 var imgCnt = imgs.length;
396 if (imgs[--imgCnt].parentNode.getAttribute('class') == 'graph_img') {
397 var now = new Date();
398 var newTS = '&ts='+now.getTime();
399 var oldSrc = imgs[imgCnt].src;
400 var newSrc = oldSrc.replace(/&ts=[0-9]+/, newTS);
401 if (newSrc == oldSrc)
402 newSrc = newSrc+newTS;
403 imgs[imgCnt].setAttribute('src', newSrc);
409 function GraphRemove(graph) {
410 var graphs = document.getElementById('graphs');
411 if (document.getElementById(graph)) {
412 graphs.removeChild(document.getElementById(graph));
414 if (graphs.getElementsByTagName('div').length == 1)
415 document.getElementById('nograph').style.display = 'block';
419 function GraphMoveUp(graph) {
420 var graphs = document.getElementById('graphs');
421 var childCnt = graphs.childNodes.length;
422 var prevGraph = null;
423 for (i = 0; i < childCnt; i++)
424 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
425 if (graphs.childNodes[i].id == 'nograph') {
427 } else if (graphs.childNodes[i].id == graph) {
428 var myGraph = graphs.childNodes[i];
430 graphs.removeChild(myGraph);
431 graphs.insertBefore(myGraph, prevGraph);
435 prevGraph = graphs.childNodes[i];
439 function GraphMoveDown(graph) {
440 var graphs = document.getElementById('graphs');
441 var childCnt = graphs.childNodes.length;
442 var nextGraph = null;
444 for (i = 0; i < childCnt; i++)
445 if (graphs.childNodes[i].nodeName == 'div' || graphs.childNodes[i].nodeName == 'DIV') {
446 if (graphs.childNodes[i].id == 'nograph') {
448 } else if (graphs.childNodes[i].id == graph) {
449 myGraph = graphs.childNodes[i];
450 } else if (myGraph) {
451 nextGraph = graphs.childNodes[i];
452 graphs.removeChild(nextGraph);
453 graphs.insertBefore(nextGraph, myGraph);