/** * Global variables */ var configTabs; // Config tabs var configDatatables = new Object(); // Datatables on the config page /** * Set the datatable * * @param id The ID of the datatable * @param obj Datatable object */ function setConfigDatatable(id, obj) { configDatatables[id] = obj; } /** * Get the datatable with the given ID * * @param id The ID of the datatable * @return Datatable object */ function getConfigDatatable(id) { return configDatatables[id]; } /** * Set the configure tab * * @param obj Tab object */ function setConfigTab(obj) { configTabs = obj; } /** * Get the configure tab * * @param Nothing * @return Tab object */ function getConfigTab() { return configTabs; } /** * Load configure page */ function loadConfigPage() { // If the configure page has already been loaded if ($('#content').children().length) { // Do not reload configure page return; } // Create configure tab var tab = new Tab(); setConfigTab(tab); tab.init(); $('#content').append(tab.object()); // Create loader var loader = $('<center></center>').append(createLoader()); // Add tab to configure xCAT tables tab.add('configTablesTab', 'Tables', loader, false); // Add the update tab tab.add('updateTab', 'Update', '', false); // Add the self-service tab tab.add('usersTab', 'Users', '', false); // Add the discover tab tab.add('discoverTab', 'Discover', '', false); // Add the self-service tab tab.add('serviceTab', 'Service', '', false); // Get list of tables and their descriptions $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'tabdump', tgt : '', args : '-d', msg : '' }, success : loadTableNames }); // Do not load everything at once // Load when tab is shown tab.object().bind('tabsshow', function(event, ui) { if ($(ui.panel).children().length) { return; } if (ui.index == 1) { loadUpdatePage(); } else if (ui.index == 2) { loadUserPage(); } else if (ui.index == 3) { loadDiscoverPage(); } else if (ui.index == 4) { loadServicePage(); } }); } /** * Load xCAT database table names and their descriptions * * @param data Data returned from HTTP request */ function loadTableNames(data) { // Get output var tables = data.rsp; // Remove loader var tabId = 'configTablesTab'; $('#' + tabId).find('img').hide(); // Create a groups division var tablesDIV = $('<div id="configTable"></div>'); $('#' + tabId).append(tablesDIV); // Create info bar var infoBar = createInfoBar('Select a table to view or edit.'); tablesDIV.append(infoBar); // Create a list for the tables var list = $('<ul></ul>'); // Loop through each table for ( var i = 0; i < tables.length; i++) { // Create a link for each table var args = tables[i].split(':'); var link = $('<a style="color: blue;" id="' + args[0] + '">' + args[0] + '</a>'); // Open table on click link.bind('click', function(e) { // Get table ID that was clicked var id = (e.target) ? e.target.id : e.srcElement.id; // Create loader var loader = $('<center></center>').append(createLoader()); // Add a new tab for this table var configTab = getConfigTab(); if (!$('#' + id + 'Tab').length) { configTab.add(id + 'Tab', id, loader, true); // Get contents of selected table $.ajax({ url : 'lib/cmd.php', dataType : 'json', data : { cmd : 'tabdump', tgt : '', args : id, msg : id }, success : loadTable }); } // Select new tab configTab.select(id + 'Tab'); }); var item = $('<li></li>'); item.append(link); // Append the table description item.append(': ' + args[1]); // Append item to list list.append(item); } tablesDIV.append(list); } /** * Load a given database table * * @param data Data returned from HTTP request */ function loadTable(data) { // Get response var rsp = data.rsp; // Get table ID var id = data.msg; // Remove loader var tabId = id + 'Tab'; $('#' + tabId).find('img').remove(); // Create info bar var infoBar = createInfoBar('Click on a cell to edit. Click outside the table to write to the cell. Once you are satisfied with how the table looks, click on Save.'); $('#' + tabId).append(infoBar); // Create action bar var actionBar = $('<div></div>'); $('#' + tabId).append(actionBar); // Get table headers var args = rsp[0].replace('#', ''); var headers = args.split(','); // Create container for original table contents var origCont = new Array(); // Original table content origCont[0] = rsp[0].split(','); // Headers // Create container for new table contents var newCont = new Object(); var tmp = new Object(); tmp[0] = '#' + headers[0]; // Put a # in front of the header for ( var i = 1; i < headers.length; i++) { tmp[i] = headers[i]; } newCont[0] = tmp; // Create a new datatable var tableId = id + 'Datatable'; var table = new DataTable(tableId); // Add column for the remove row button headers.unshift(''); table.init(headers); headers.shift(); // Append datatable to tab $('#' + tabId).append(table.object()); // Add table rows // Start with the 2nd row (1st row is the headers) for ( var i = 1; i < rsp.length; i++) { // Split into columns var cols = rsp[i].split(','); // Go through each column for ( var j = 0; j < cols.length; j++) { // If the column is not complete if (cols[j].count('"') == 1) { while (cols[j].count('"') != 2) { // Merge this column with the adjacent one cols[j] = cols[j] + "," + cols[j + 1]; // Remove merged row cols.splice(j + 1, 1); } } // Replace quote cols[j] = cols[j].replace(new RegExp('"', 'g'), ''); } // Add remove button cols.unshift('<span class="ui-icon ui-icon-close" onclick="deleteRow(this)"></span>'); // Add row table.add(cols); // Save original table content origCont[i] = cols; } // Turn table into datatable var dTable = $('#' + id + 'Datatable').dataTable({ 'iDisplayLength': 50, 'bLengthChange': false, "bScrollCollapse": true, "sScrollY": "400px", "sScrollX": "110%", "bAutoWidth": true, "oLanguage": { "oPaginate": { "sNext": "", "sPrevious": "" } } }); /** * Enable editable columns */ // Do not make 1st column editable $('#' + tableId + ' td:not(td:nth-child(1))').editable( function(value, settings) { // Get column index var colPos = this.cellIndex; // Get row index var rowPos = dTable.fnGetPosition(this.parentNode); // Update datatable dTable.fnUpdate(value, rowPos, colPos); return (value); }, { onblur : 'submit', // Clicking outside editable area submits changes type : 'textarea', placeholder: ' ', height : '30px' // The height of the text area }); // Create action bar var actionBar = $('<div class="actionBar"></div>'); var saveLnk = $('<a>Save</a>'); saveLnk.click(function() { // Get table ID and name var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); var tableName = tableId.replace('Datatable', ''); // Get datatable var dTable = $('#' + tableId).dataTable(); // Get the nodes from the table var dRows = dTable.fnGetNodes(); // Go through each row for ( var i = 0; i < dRows.length; i++) { // If there is row with values if (dRows[i]) { // Go through each column // Ignore the 1st column because it is a button var cols = dRows[i].childNodes; var vals = new Object(); for ( var j = 1; j < cols.length; j++) { var val = cols.item(j).firstChild.nodeValue; // Insert quotes if (val == ' ') { vals[j - 1] = ''; } else { vals[j - 1] = val; } } // Save row newCont[i + 1] = vals; } } // Update xCAT table $.ajax({ type : 'POST', url : 'lib/tabRestore.php', dataType : 'json', data : { table : tableName, cont : newCont }, success : function(data) { // Create info message var dialog = $('<div></div>').append(createInfoBar('Changes saved!')); // Open dialog dialog.dialog({ modal: true, title: 'Info', width: 400, buttons: { "Ok": function(){ $(this).dialog("close"); } } }); } }); }); var undoLnk = $('<a>Undo</a>'); undoLnk.click(function() { // Get table ID var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); // Get datatable var dTable = $('#' + tableId).dataTable(); // Clear entire datatable dTable.fnClearTable(); // Add original content back into datatable for ( var i = 1; i < origCont.length; i++) { dTable.fnAddData(origCont[i], true); } // Enable editable columns (again) // Do not make 1st column editable $('#' + tableId + ' td:not(td:nth-child(1))').editable( function(value, settings) { // Get column index var colPos = this.cellIndex; // Get row index var rowPos = dTable.fnGetPosition(this.parentNode); // Update datatable dTable.fnUpdate(value, rowPos, colPos); return (value); }, { onblur : 'submit', // Clicking outside editable area submits changes type : 'textarea', placeholder: ' ', height : '30px' // The height of the text area }); }); var addLnk = $('<a>Add row</a>'); addLnk.click(function() { // Create an empty row var row = new Array(); /** * Remove button */ row.push('<span class="ui-icon ui-icon-close" onclick="deleteRow(this)"></span>'); for ( var i = 0; i < headers.length; i++) { row.push(''); } // Get table ID and name var tableId = $(this).parents('.dataTables_wrapper').attr('id').replace('_wrapper', ''); // Get datatable var dTable = $('#' + tableId).dataTable(); // Add the row to the data table dTable.fnAddData(row); // Enable editable columns (again) // Do not make 1st column editable $('#' + tableId + ' td:not(td:nth-child(1))').editable( function(value, settings) { // Get column index var colPos = this.cellIndex; // Get row index var rowPos = dTable.fnGetPosition(this.parentNode); // Update datatable dTable.fnUpdate(value, rowPos, colPos); return (value); }, { onblur : 'submit', // Clicking outside editable area submits changes type : 'textarea', placeholder: ' ', height : '30px' // The height of the text area }); }); // Create an action menu var actionsMenu = createMenu([saveLnk, undoLnk, addLnk]); actionsMenu.superfish(); actionsMenu.css('display', 'inline-block'); actionBar.append(actionsMenu); // Set correct theme for action menu actionsMenu.find('li').hover(function() { setMenu2Theme($(this)); }, function() { setMenu2Normal($(this)); }); // Create a division to hold actions menu var menuDiv = $('<div id="' + id + 'Datatable_menuDiv" class="menuDiv"></div>'); $('#' + id + 'Datatable_wrapper').prepend(menuDiv); menuDiv.append(actionBar); $('#' + id + 'Datatable_filter').appendTo(menuDiv); } /** * Delete a row in the data table * * @param obj The object that was clicked */ function deleteRow(obj) { // Get table ID var tableId = $(obj).parents('table').attr('id'); // Get datatable var dTable = $('#' + tableId).dataTable(); // Get all nodes within the datatable var rows = dTable.fnGetNodes(); // Get target row var tgtRow = $(obj).parent().parent().get(0); // Find the target row in the datatable for ( var i in rows) { // If the row matches the target row if (rows[i] == tgtRow) { // Remove row dTable.fnDeleteRow(i, null, true); break; } } } /** * Count the number of occurrences of a specific character in a string * * @param c Character to count * @return The number of occurrences */ String.prototype.count = function(c) { return (this.length - this.replace(new RegExp(c, 'g'), '').length)/c.length; }; /** * Update dialog * * @param data HTTP request data */ function updatePanel(data) { var dialogId = data.msg; var infoMsg; // Create info message if (jQuery.isArray(data.rsp)) { infoMsg = ''; for (var i in data.rsp) { infoMsg += data.rsp[i] + '</br>'; } } else { infoMsg = data.rsp; } // Create info bar with close button var infoBar = $('<div class="ui-state-highlight ui-corner-all"></div>').css('margin', '5px 0px'); var icon = $('<span class="ui-icon ui-icon-info"></span>').css({ 'display': 'inline-block', 'margin': '10px 5px' }); // Create close button to close info bar var close = $('<span class="ui-icon ui-icon-close"></span>').css({ 'display': 'inline-block', 'float': 'right' }).click(function() { $(this).parent().remove(); }); var msg = $('<pre>' + infoMsg + '</pre>').css({ 'display': 'inline-block', 'width': '85%' }); infoBar.append(icon, msg, close); infoBar.prependTo($('#' + dialogId)); }