/**
* Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
*
* This software is licensed under the GNU General Public License v3 or later.
*
* It is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
// Version: @VERSION@
//***** actions for details tab in right panel (begin) ************************************************************************
function buildActionLinkForDetailsTab(label, actionMap, $actionMenu, listAPIMap) {
var apiInfo = actionMap[label];
var $listItem = $("#action_list_item").clone();
$actionMenu.find("#action_list").append($listItem.show());
var $link = $listItem.find("#link").text(label);
$link.data("label", label);
$link.data("inProcessText", apiInfo.inProcessText);
$link.data("api", apiInfo.api);
$link.data("isAsyncJob", apiInfo.isAsyncJob);
$link.data("asyncJobResponse", apiInfo.asyncJobResponse);
$link.data("afterActionSeccessFn", apiInfo.afterActionSeccessFn);
$link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn);
$link.data("customActionFn", apiInfo.customActionFn);
var $detailsTab = $("#right_panel_content #tab_content_details");
var id = $detailsTab.data("jsonObj").id;
$link.bind("click", function(event) {
$actionMenu.hide();
var $actionLink = $(this);
var customActionFn = $actionLink.data("customActionFn");
if(customActionFn != null) {
customActionFn();
return false;
}
var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn");
if(dialogBeforeActionFn == null) {
var apiCommand = "command="+$actionLink.data("api")+"&id="+id;
doActionToDetailsTab(id, $actionLink, apiCommand, listAPIMap);
}
else {
dialogBeforeActionFn($actionLink, listAPIMap, $detailsTab);
}
return false;
});
}
function doActionToDetailsTab(id, $actionLink, apiCommand, listAPIMap) {
var label = $actionLink.data("label");
var inProcessText = $actionLink.data("inProcessText");
var isAsyncJob = $actionLink.data("isAsyncJob");
var asyncJobResponse = $actionLink.data("asyncJobResponse");
var afterActionSeccessFn = $actionLink.data("afterActionSeccessFn");
var listAPI = listAPIMap["listAPI"];
var listAPIResponse = listAPIMap["listAPIResponse"];
var listAPIResponseObj = listAPIMap["listAPIResponseObj"];
var $detailsTab = $("#right_panel_content #tab_content_details");
var $spinningWheel = $detailsTab.find("#spinning_wheel");
$spinningWheel.find("#description").text(inProcessText);
$spinningWheel.show();
//Async job (begin) *****
if(isAsyncJob == true) {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
success: function(json) {
var jobId = json[asyncJobResponse].jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
10000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
$("#right_panel_content #after_action_info").text(label + " action succeeded.");
$("#right_panel_content #after_action_info_container").removeClass("errorbox").show();
if(apiCommand.indexOf("command=delete")!=0) {
//DestroyVirtualMachine API doesn't return an embedded object on success (Bug 6041)
//Before Bug 6041 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
success: function(json) {
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
}
else { //apiCommand is deleteXXXXXXX
afterActionSeccessFn(id);
}
} else if (result.jobstatus == 2) { // Failed
$("#right_panel_content #after_action_info").text(label + " action failed. Reason: " + fromdb(result.jobresult));
$("#right_panel_content #after_action_info_container").addClass("errorbox").show();
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInDetailsTab(XMLHttpResponse, $detailsTab, label);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInDetailsTab(XMLHttpResponse, $detailsTab, label);
}
});
}
//Async job (end) *****
//Sync job (begin) *****
else {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
async: false,
success: function(json) {
$spinningWheel.hide();
$("#right_panel_content #after_action_info").text(label + " action succeeded.");
$("#right_panel_content #after_action_info_container").removeClass("errorbox").show();
if(apiCommand.indexOf("command=delete")!=0) {
//RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037)
//Before Bug 6037 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
async: false,
success: function(json) {
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0]);
}
else { //apiCommand is deleteXXXXXXX
afterActionSeccessFn(id);
}
},
error: function(XMLHttpResponse) {
handleErrorInDetailsTab(XMLHttpResponse, $detailsTab, label);
}
});
}
//Sync job (end) *****
}
function handleErrorInDetailsTab(XMLHttpResponse, $detailsTab, label) {
$detailsTab.find("#spinning_wheel").hide();
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf(" 0)
$("#right_panel_content #after_action_info").text(label + " action failed. Reason: " + fromdb(errorMsg));
else
$("#right_panel_content #after_action_info").text(label + " action failed.");
$("#right_panel_content #after_action_info_container").addClass("errorbox").show();
}
//***** actions for details tab in right panel (end) **************************************************************************
//***** actions for middle menu (begin) ************************************************************************
var selectedItemsInMidMenu = {};
function buildActionLinkForMidMenu(label, actionMap, $actionMenu, listAPIMap) {
var apiInfo = actionMap[label];
var $listItem = $("#action_list_item_middle_menu").clone();
$actionMenu.find("#action_list").append($listItem.show());
var $link = $listItem.find("#link").text(label);
$link.data("label", label);
$link.data("api", apiInfo.api);
$link.data("isAsyncJob", apiInfo.isAsyncJob);
$link.data("asyncJobResponse", apiInfo.asyncJobResponse);
$link.data("afterActionSeccessFn", apiInfo.afterActionSeccessFn);
$link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn);
$link.bind("click", function(event) {
$actionMenu.hide();
var $actionLink = $(this);
var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn");
if(dialogBeforeActionFn == null) {
for(var id in selectedItemsInMidMenu) {
var apiCommand = "command="+$actionLink.data("api")+"&id="+id;
doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap);
}
}
else {
dialogBeforeActionFn($actionLink, selectedItemsInMidMenu, listAPIMap);
}
selectedItemsInMidMenu = {}; //clear selected items for action
return false;
});
}
function doActionForMidMenu(id, $actionLink, apiCommand, listAPIMap) {
var label = $actionLink.data("label");
var isAsyncJob = $actionLink.data("isAsyncJob");
var asyncJobResponse = $actionLink.data("asyncJobResponse");
var afterActionSeccessFn = $actionLink.data("afterActionSeccessFn");
var listAPI = listAPIMap["listAPI"];
var listAPIResponse = listAPIMap["listAPIResponse"];
var listAPIResponseObj = listAPIMap["listAPIResponseObj"];
var $midmenuItem = $("#midmenuItem_"+id);
$midmenuItem.find("#content").removeClass("selected").addClass("inaction");
$midmenuItem.find("#spinning_wheel").addClass("midmenu_addingloader").show();
$midmenuItem.find("#info_icon").hide();
//Async job (begin) *****
if(isAsyncJob == true) {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
success: function(json) {
var jobId = json[asyncJobResponse].jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
10000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$midmenuItem.find("#content").removeClass("inaction");
$midmenuItem.find("#spinning_wheel").hide();
if (result.jobstatus == 1) { // Succeeded
$midmenuItem.find("#info_icon").removeClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action succeeded."));
//DestroyVirtualMachine API doesn't return an embedded object on success (Bug 6041)
//Before Bug 6041 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
success: function(json) {
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem, $midmenuItem.data("toRightPanelFn"));
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem, $midmenuItem.data("toRightPanelFn"));
} else if (result.jobstatus == 2) { // Failed
$midmenuItem.find("#info_icon").addClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action failed. Reason: " + fromdb(result.jobresult)));
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
}
//Async job (end) *****
//Sync job (begin) *****
else {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
async: false,
success: function(json) {
$midmenuItem.find("#content").removeClass("inaction");
$midmenuItem.find("#spinning_wheel").hide();
//RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037)
//Before Bug 6037 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
async: false,
success: function(json) {
$midmenuItem.find("#info_icon").removeClass("error").show();
$midmenuItem.data("afterActionInfo", (label + " action succeeded."));
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem, $midmenuItem.data("toRightPanelFn"));
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $midmenuItem, $midmenuItem.data("toRightPanelFn"));
},
error: function(XMLHttpResponse) {
handleErrorInMidMenu(XMLHttpResponse, $midmenuItem);
}
});
}
//Sync job (end) *****
}
function handleErrorInMidMenu(XMLHttpResponse, $midmenuItem1) {
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
$midmenuItem1.find("#info_icon").addClass("error").show();
$midmenuItem1.find("#first_row").text("Adding failed");
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf(" 0)
$midmenuItem1.find("#second_row").text(fromdb(errorMsg));
else
$midmenuItem1.find("#second_row").html(" ");
}
function handleAsyncJobFailInMidMenu(errorMsg, $midmenuItem1) {
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
$midmenuItem1.find("#info_icon").addClass("error").show();
$midmenuItem1.find("#first_row").text("Adding failed");
if(errorMsg.length > 0)
$midmenuItem1.find("#second_row").text(fromdb(errorMsg));
else
$midmenuItem1.find("#second_row").html(" ");
}
//***** actions for middle menu (end) **************************************************************************
//***** actions for a subgrid item in right panel (begin) ************************************************************************
function buildActionLinkForSubgridItem(label, actionMap, $actionMenu, listAPIMap, $subgridItem) {
var apiInfo = actionMap[label];
var $listItem = $("#action_list_item").clone();
$actionMenu.find("#action_list").append($listItem.show());
var $link = $listItem.find("#link").text(label);
$link.data("label", label);
$link.data("inProcessText", apiInfo.inProcessText);
$link.data("api", apiInfo.api);
$link.data("isAsyncJob", apiInfo.isAsyncJob);
$link.data("asyncJobResponse", apiInfo.asyncJobResponse);
$link.data("afterActionSeccessFn", apiInfo.afterActionSeccessFn);
$link.data("dialogBeforeActionFn", apiInfo.dialogBeforeActionFn);
var id = $subgridItem.data("jsonObj").id;
$link.bind("click", function(event) {
$actionMenu.hide();
var $actionLink = $(this);
var dialogBeforeActionFn = $actionLink.data("dialogBeforeActionFn");
if(dialogBeforeActionFn == null) {
var apiCommand = "command="+$actionLink.data("api")+"&id="+id;
doActionToSubgridItem(id, $actionLink, apiCommand, listAPIMap, $subgridItem);
}
else {
dialogBeforeActionFn($actionLink, listAPIMap, $subgridItem);
}
return false;
});
}
function doActionToSubgridItem(id, $actionLink, apiCommand, listAPIMap, $subgridItem) {
var label = $actionLink.data("label");
var inProcessText = $actionLink.data("inProcessText");
var isAsyncJob = $actionLink.data("isAsyncJob");
var asyncJobResponse = $actionLink.data("asyncJobResponse");
var afterActionSeccessFn = $actionLink.data("afterActionSeccessFn");
var listAPI = listAPIMap["listAPI"];
var listAPIResponse = listAPIMap["listAPIResponse"];
var listAPIResponseObj = listAPIMap["listAPIResponseObj"];
var $spinningWheel = $subgridItem.find("#spinning_wheel");
$spinningWheel.find("#description").text(inProcessText);
$spinningWheel.show();
//Async job (begin) *****
if(isAsyncJob == true) {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
success: function(json) {
var jobId = json[asyncJobResponse].jobid;
var timerKey = "asyncJob_" + jobId;
$("body").everyTime(
10000,
timerKey,
function() {
$.ajax({
data: createURL("command=queryAsyncJobResult&jobId="+jobId),
dataType: "json",
success: function(json) {
var result = json.queryasyncjobresultresponse;
if (result.jobstatus == 0) {
return; //Job has not completed
} else {
$("body").stopTime(timerKey);
$spinningWheel.hide();
if (result.jobstatus == 1) { // Succeeded
$subgridItem.find("#after_action_info").text(label + " action succeeded.");
$subgridItem.find("#after_action_info_container").removeClass("error").addClass("success").show();
if(apiCommand.indexOf("command=delete")!=0) {
//DestroyVirtualMachine API doesn't return an embedded object on success (Bug 6041)
//Before Bug 6041 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
success: function(json) {
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $subgridItem);
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $subgridItem);
}
else { //apiCommand is deleteXXXXXXX
afterActionSeccessFn(id);
}
} else if (result.jobstatus == 2) { // Failed
$subgridItem.find("#after_action_info").text(label + " action failed. Reason: " + fromdb(result.jobresult));
$subgridItem.find("#after_action_info_container").removeClass("success").addClass("error").show();
}
}
},
error: function(XMLHttpResponse) {
$("body").stopTime(timerKey);
handleErrorInSubgridItem(XMLHttpResponse, $subgridItem, label);
}
});
},
0
);
},
error: function(XMLHttpResponse) {
handleErrorInSubgridItem(XMLHttpResponse, $subgridItem, label);
}
});
}
//Async job (end) *****
//Sync job (begin) *****
else {
$.ajax({
data: createURL(apiCommand),
dataType: "json",
async: false,
success: function(json) {
$spinningWheel.hide();
if(apiCommand.indexOf("command=delete")!=0) {
//RecoverVirtualMachine API doesn't return an embedded object on success (Bug 6037)
//Before Bug 6037 get fixed, use the temporary solution below.
$.ajax({
cache: false,
data: createURL("command="+listAPI+"&id="+id),
dataType: "json",
async: false,
success: function(json) {
$subgridItem.find("#after_action_info").text(label + " action succeeded.");
$subgridItem.find("#after_action_info_container").removeClass("error").addClass("success").show();
afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $subgridItem);
}
});
//After Bug 6037 is fixed, remove temporary solution above and uncomment the line below
//afterActionSeccessFn(json[listAPIResponse][listAPIResponseObj][0], $subgridItem);
}
else { //apiCommand is deleteXXXXXXX
afterActionSeccessFn(id);
}
},
error: function(XMLHttpResponse) {
handleErrorInSubgridItem(XMLHttpResponse, $subgridItem, label);
}
});
}
//Sync job (end) *****
}
function handleErrorInSubgridItem(XMLHttpResponse, $subgridItem, label) {
$subgridItem.find("#spinning_wheel").hide();
var errorMsg = "";
if(XMLHttpResponse.responseText != null & XMLHttpResponse.responseText.length > 0) {
var start = XMLHttpResponse.responseText.indexOf("h1") + 3;
var end = XMLHttpResponse.responseText.indexOf(" 0)
$subgridItem.find("#after_action_info").text(label + " action failed. Reason: " + fromdb(errorMsg));
else
$subgridItem.find("#after_action_info").text(label + " action failed.");
$subgridItem.find("#after_action_info_container").removeClass("success").addClass("error").show();
}
//***** actions for a subgrid item in right panel (end) **************************************************************************
function createURL(url) {
return url +"&response=json&sessionkey=" + g_sessionKey;
}
function fromdb(val) {
return sanitizeXSS(unescape(noNull(val)));
}
function todb(val) {
return encodeURIComponent(escape(val));
}
var midmenuItemCount = 20;
function setBooleanField(value, $field) {
if(value == "true" || value == true)
$field.text("Yes").show();
else if(value == "false" || value == false)
$field.text("No").show();
else
$field.hide();
}
function clearLeftMenu() {
var $arrowIcon = $("#leftmenu_instance_group_header #arrow_icon");
if($arrowIcon.hasClass("open") == true) {
$arrowIcon.removeClass("open").addClass("close");
$("#leftmenu_instance_group_container").empty();
}
}
function clearMiddleMenu() {
$("#midmenu_container").empty();
$("#midmenu_action_link").hide();
$("#midmenu_add_link").hide();
}
function clearRightPanel() {
$("#right_panel_content #tab_content_details #action_link #action_menu #action_list").empty();
$("#right_panel_content #after_action_info_container").hide();
}
var selected_leftmenu_id = null;
var selected_midmenu_id = null;
function hideMiddleMenu() {
$("#middle_menu, #search_panel, #middle_menu_pagination").hide();
$("#right_panel").removeClass("main_contentarea").addClass("main_contentarea_dashboard");
}
function showMiddleMenu() {
$("#middle_menu, #search_panel, #middle_menu_pagination").show();
$("#right_panel").removeClass("main_contentarea_dashboard").addClass("main_contentarea");
}
function showMiddleMenuWithoutSearch() {
$("#middle_menu").show();
$("#search_panel, #middle_menu_pagination").hide();
$("#right_panel").removeClass("main_contentarea_dashboard").addClass("main_contentarea");
}
// adding middle menu item ***
function beforeAddingMidMenuItem() {
var $midmenuItem1 = $("#midmenu_item").clone();
$midmenuItem1.find("#first_row").text("Adding....");
$midmenuItem1.find("#second_row").html(" ");
$midmenuItem1.find("#content").addClass("inaction");
$midmenuItem1.find("#spinning_wheel").show();
$midmenuItem1.find("#info_icon").removeClass("error").hide();
$("#midmenu_container").append($midmenuItem1.show());
return $midmenuItem1;
}
function afterAddingMidMenuItem($midmenuItem1, isSuccessful, extraMessage) {
$midmenuItem1.find("#content").removeClass("inaction");
$midmenuItem1.find("#spinning_wheel").hide();
if(isSuccessful == true) {
$midmenuItem1.find("#info_icon").removeClass("error").show();
$midmenuItem1.data("afterActionInfo", ("Adding succeeded."));
}
else {
$midmenuItem1.find("#info_icon").addClass("error").show();
$midmenuItem1.find("#first_row").text("Adding failed");
if(extraMessage != null)
$midmenuItem1.find("#second_row").text(extraMessage);
}
}
function bindClickToMidMenu($midmenuItem1, toRightPanel, getMidmenuId) {
$midmenuItem1.bind("click", function(event){
var thisMidmenuItem = $(this);
if(selected_midmenu_id != null && selected_midmenu_id.length > 0)
$("#"+selected_midmenu_id).find("#content").removeClass("selected");
if(getMidmenuId == null)
selected_midmenu_id = "midmenuItem_"+thisMidmenuItem.data("jsonObj").id;
else
selected_midmenu_id = getMidmenuId(thisMidmenuItem.data("jsonObj"));
thisMidmenuItem.find("#content").addClass("selected");
clearRightPanel();
toRightPanel(thisMidmenuItem);
return false;
});
}
function initializeEditFunction($readonlyFields, $editFields, doUpdateFn) {
$("#edit_button").bind("click", function(event){
$readonlyFields.hide();
$editFields.show();
$("#cancel_button, #save_button").show()
return false;
});
$("#cancel_button").bind("click", function(event){
$editFields.hide();
$readonlyFields.show();
$("#save_button, #cancel_button").hide();
return false;
});
$("#save_button").bind("click", function(event){
doUpdateFn();
$editFields.hide();
$readonlyFields.show();
$("#save_button, #cancel_button").hide();
return false;
});
}
function switchBetweenDifferentTabs(tabArray, tabContentArray) {
for(var tabIndex=0; tabIndex 0) {
var disconnected = new Date();
disconnected.setISO8601(dateValue);
var showDate;
if(g_timezoneoffset != null)
showDate = disconnected.getTimePlusTimezoneOffset(g_timezoneoffset);
else
showDate = disconnected.format("m/d/Y H:i:s");
if(htmlMarkup == null)
dateField.text(showDate);
else
dateField.html(htmlMarkup + showDate);
}
}
function initResizable(resizeElement, alsoResizeElement) {
var alsoResizeUi_originalHeight;
$("#"+resizeElement).resizable({
handles: 'e, w',
autoHide: true,
//containment: ".grid_header" ,
alsoResize: "."+alsoResizeElement
});
}
var sortBy = "";
var parseFunction = function() {}
var sortingOrder = "asc";
function sortArrayAlphabetically(a, b) {
if(a[sortBy] == null || b[sortBy] == null)
return 0;
var A = a[sortBy].toLowerCase();
var B = b[sortBy].toLowerCase();
if(sortingOrder == "asc") {
if (A < B)
return -1;
if (A > B)
return 1;
} else {
if (A < B)
return 1;
if (A > B)
return -1;
}
return 0;
}
function sortArrayAlphabeticallyParse(a, b) {
if(a[sortBy] == null || b[sortBy] == null)
return 0;
var A = parseFunction(a[sortBy]).toLowerCase();
var B = parseFunction(b[sortBy]).toLowerCase();
if(sortingOrder == "asc") {
if (A < B)
return -1;
if (A > B)
return 1;
} else {
if (A < B)
return 1;
if (A > B)
return -1;
}
return 0;
}
function sortArrayNumerically(a, b) {
if(a[sortBy] == null || b[sortBy] == null)
return 0;
var A = parseInt(a[sortBy]);
var B = parseInt(b[sortBy]);
if(sortingOrder == "asc") {
if (A < B)
return -1;
if (A > B)
return 1;
} else {
if (A < B)
return 1;
if (A > B)
return -1;
}
return 0;
}
function sortArrayNumericallyParse(a, b) {
if(a[sortBy] == null || b[sortBy] == null)
return 0;
var A = parseFunction(parseInt(a[sortBy]));
var B = parseFunction(parseInt(b[sortBy]));
if(sortingOrder == "asc") {
if (A < B)
return -1;
if (A > B)
return 1;
} else {
if (A < B)
return 1;
if (A > B)
return -1;
}
return 0;
}
function sortArrayByDate(a, b) {
if(a[sortBy] == null || b[sortBy] == null)
return 0;
var A = convertMilliseconds(a[sortBy]);
var B = convertMilliseconds(b[sortBy]);
if(sortingOrder == "asc") {
if (A < B)
return -1;
if (A > B)
return 1;
} else {
if (A < B)
return 1;
if (A > B)
return -1;
}
return 0;
}
function convertMilliseconds(string) {
if (string != null && string.length > 0) {
var date1 = new Date();
date1.setISO8601(string);
return date1.getTime();
} else {
return null;
}
}
function drawGrid(items, submenuContent, template, fnJSONToTemplate) {
var grid = submenuContent.find("#grid_content").empty();
if (items != null && items.length > 0) {
for (var i = 0; i < items.length; i++) {
var newTemplate = template.clone(true);
fnJSONToTemplate(items[i], newTemplate);
grid.append(newTemplate.show());
}
setGridRowsTotal(submenuContent.find("#grid_rows_total"), items.length);
if(items.length < pageSize)
submenuContent.find("#nextPage_div").hide();
else
submenuContent.find("#nextPage_div").show();
} else {
setGridRowsTotal(submenuContent.find("#grid_rows_total"), null);
submenuContent.find("#nextPage_div").hide();
}
}
//listItems() function takes care of loading image, pagination
var items = [];
function listItems(submenuContent, commandString, jsonResponse1, jsonResponse2, template, fnJSONToTemplate ) {
if(currentPage==1)
submenuContent.find("#prevPage_div").hide();
else
submenuContent.find("#prevPage_div").show();
submenuContent.find("#loading_gridtable").show();
submenuContent.find("#pagination_panel").hide();
index = 0;
$.ajax({
data: createURL(commandString),
dataType: "json",
async: false,
success: function(json) {
//IF jsonResponse1=="listaccountsresponse", jsonResponse2=="account", THEN json[jsonResponse1][jsonResponse2] == json.listaccountsresponse.account
items = json[jsonResponse1][jsonResponse2];
drawGrid(items, submenuContent, template, fnJSONToTemplate);
submenuContent.find("#loading_gridtable").hide();
submenuContent.find("#pagination_panel").show();
},
error: function(XMLHttpResponse) {
submenuContent.find("#loading_gridtable").hide();
handleError(XMLHttpResponse, function() {
if(XMLHttpResponse.status == ERROR_VMOPS_ACCOUNT_ERROR) {
submenuContent.find("#grid_content").empty();
setGridRowsTotal(submenuContent.find("#grid_rows_total"), null);
submenuContent.find("#nextPage_div").hide();
}
submenuContent.find("#loading_gridtable").hide();
submenuContent.find("#pagination_panel").show();
});
}
});
}
//event binder
var currentPage = 1;
var pageSize = 50; //consistent with server-side
function submenuContentEventBinder(submenuContent, listFunction) {
submenuContent.find("#nextPage").bind("click", function(event){
event.preventDefault();
currentPage++;
listFunction();
});
submenuContent.find("#prevPage").bind("click", function(event){
event.preventDefault();
currentPage--;
listFunction();
});
submenuContent.find("#refresh").bind("click", function(event){
event.preventDefault();
currentPage=1;
listFunction();
});
submenuContent.find("#search_button").bind("click", function(event) {
event.preventDefault();
currentPage = 1;
listFunction();
});
submenuContent.find("#adv_search_button").bind("click", function(event) {
event.preventDefault();
currentPage = 1;
listFunction();
submenuContent.find("#search_button").data("advanced", false);
submenuContent.find("#advanced_search").hide();
});
submenuContent.find("#search_input").bind("keypress", function(event) {
if(event.keyCode == keycode_Enter) {
event.preventDefault();
submenuContent.find("#search_button").click();
}
});
submenuContent.find("#advanced_search").bind("keypress", function(event) {
if(event.keyCode == keycode_Enter) {
event.preventDefault();
submenuContent.find("#adv_search_button").click();
}
});
submenuContent.find("#advanced_search_close").bind("click", function(event) {
event.preventDefault();
submenuContent.find("#search_button").data("advanced", false);
submenuContent.find("#advanced_search").hide();
});
submenuContent.find("#advanced_search_link").bind("click", function(event) {
event.preventDefault();
submenuContent.find("#search_button").data("advanced", true);
submenuContent.find("#advanced_search").show();
});
var zoneSelect = submenuContent.find("#advanced_search #adv_search_zone");
if(zoneSelect.length>0) { //if zone dropdown is found on Advanced Search dialog
$.ajax({
data: createURL("command=listZones&available=true&response=json"+maxPageSize),
dataType: "json",
success: function(json) {
var zones = json.listzonesresponse.zone;
zoneSelect.empty();
zoneSelect.append("");
if (zones != null && zones.length > 0) {
for (var i = 0; i < zones.length; i++) {
zoneSelect.append("");
}
}
}
});
var podSelect = submenuContent.find("#advanced_search #adv_search_pod").empty();
var podLabel = submenuContent.find("#advanced_search #adv_search_pod_label");
if(podSelect.length>0 && isAdmin()) { //if pod dropdown is found on Advanced Search dialog and if its role is admin
zoneSelect.bind("change", function(event) {
var zoneId = $(this).val();
if (zoneId == null || zoneId.length == 0) {
podLabel.css("color", "gray");
podSelect.attr("disabled", "disabled");
podSelect.empty();
} else {
podLabel.css("color", "black");
podSelect.removeAttr("disabled");
$.ajax({
data: createURL("command=listPods&zoneId="+zoneId+"&response=json"+maxPageSize),
dataType: "json",
async: false,
success: function(json) {
var pods = json.listpodsresponse.pod;
podSelect.empty();
if (pods != null && pods.length > 0) {
for (var i = 0; i < pods.length; i++) {
podSelect.append("");
}
}
}
});
}
return false;
});
zoneSelect.change();
}
}
var domainSelect = submenuContent.find("#advanced_search #adv_search_domain");
if(domainSelect.length>0 && isAdmin()) {
var domainSelect = domainSelect.empty();
$.ajax({
data: createURL("command=listDomains&available=true&response=json"+maxPageSize),
dataType: "json",
success: function(json) {
var domains = json.listdomainsresponse.domain;
if (domains != null && domains.length > 0) {
for (var i = 0; i < domains.length; i++) {
domainSelect.append("");
}
}
}
});
}
var vmSelect = submenuContent.find("#advanced_search").find("#adv_search_vm");
if(vmSelect.length>0) {
vmSelect.empty();
vmSelect.append("");
$.ajax({
data: createURL("command=listVirtualMachines&response=json"+maxPageSize),
dataType: "json",
success: function(json) {
var items = json.listvirtualmachinesresponse.virtualmachine;
if (items != null && items.length > 0) {
for (var i = 0; i < items.length; i++) {
vmSelect.append("");
}
}
}
});
}
}
// Validation functions
function showError(isValid, field, errMsgField, errMsg) {
if(isValid) {
errMsgField.text("").hide();
field.addClass("text").removeClass("error_text");
}
else {
errMsgField.text(errMsg).show();
field.removeClass("text").addClass("error_text");
}
}
function showError2(isValid, field, errMsgField, errMsg, appendErrMsg) {
if(isValid) {
errMsgField.text("").hide();
field.addClass("text2").removeClass("error_text2");
}
else {
if(appendErrMsg) //append text
errMsgField.text(errMsgField.text()+errMsg).show();
else //reset text
errMsgField.text(errMsg).show();
field.removeClass("text2").addClass("error_text2");
}
}
function validateDropDownBox(label, field, errMsgField, appendErrMsg) {
var isValid = true;
var errMsg = "";
var value = field.val();
if (value == null || value.length == 0) {
errMsg = label + " is a required value. ";
isValid = false;
}
showError2(isValid, field, errMsgField, errMsg, appendErrMsg);
return isValid;
}
function validateNumber(label, field, errMsgField, min, max, isOptional) {
var isValid = true;
var errMsg = "";
var value = field.val();
if (value != null && value.length != 0) {
if(isNaN(value)) {
errMsg = label + " must be a number";
isValid = false;
} else {
if (min != null && value < min) {
errMsg = label + " must be a value greater than or equal to " + min;
isValid = false;
}
if (max != null && value > max) {
errMsg = label + " must be a value less than or equal to " + max;
isValid = false;
}
}
} else if(isOptional!=true){ //required field
errMsg = label + " is a required value. ";
isValid = false;
}
showError(isValid, field, errMsgField, errMsg);
return isValid;
}
function validateString(label, field, errMsgField, isOptional) {
var isValid = true;
var errMsg = "";
var value = field.val();
if (isOptional!=true && (value == null || value.length == 0)) { //required field
errMsg = label + " is a required value. ";
isValid = false;
}
else if (value!=null && value.length >= 255) {
errMsg = label + " must be less than 255 characters";
isValid = false;
}
else if(value!=null && value.indexOf('"')!=-1) {
errMsg = "Double quotes are not allowed.";
isValid = false;
}
showError(isValid, field, errMsgField, errMsg);
return isValid;
}
function validateIp(label, field, errMsgField, isOptional) {
if(validateString(label, field, errMsgField, isOptional) == false)
return;
var isValid = true;
var errMsg = "";
var value = field.val();
if(value!=null && value.length>0) {
myregexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
var isMatch = myregexp.test(value);
if(!isMatch) {
errMsg = label + " should be like 75.52.126.11";
isValid = false;
}
}
showError(isValid, field, errMsgField, errMsg);
return isValid;
}
function validateCIDR(label, field, errMsgField, isOptional) {
if(validateString(label, field, errMsgField, isOptional) == false)
return;
var isValid = true;
var errMsg = "";
var value = field.val();
if(value!=null && value.length>0) {
myregexp = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/;
var isMatch = myregexp.test(value);
if(!isMatch) {
errMsg = label + " should be like 10.1.1.0/24";
isValid = false;
}
}
showError(isValid, field, errMsgField, errMsg);
return isValid;
}
function validatePath(label, field, errMsgField, isOptional) {
if(validateString(label, field, errMsgField, isOptional) == false)
return;
var isValid = true;
var errMsg = "";
var value = field.val();
if(value!=null && value.length>0) {
myregexp = /^\//;
var isMatch = myregexp.test(value);
if(!isMatch) {
errMsg = label + " should be like /aaa/bbb/ccc";
isValid = false;
}
}
showError(isValid, field, errMsgField, errMsg);
return isValid;
}
function cleanErrMsg(field, errMsgField) {
showError(true, field, errMsgField);
}
// setter
function setGridRowsTotal(field, gridRowsTotal) {
if(gridRowsTotal==null) {
field.text("");
return;
}
if(gridRowsTotal==1)
field.text(gridRowsTotal + " item");
else
field.text(gridRowsTotal + " items");
}
function changeGridRowsTotal(field, difference) {
var t = field.text();
var oldTotal = 0;
if(t.length>0 && t.indexOf(" item")!=-1) {
var s = t.substring(0, t.indexOf(" item"));
if(!isNaN(s))
oldTotal = parseInt(s);
}
var newTotal = oldTotal + difference;
setGridRowsTotal(field, newTotal);
}
// others
function trim(val) {
if(val == null)
return null;
return val.replace(/^\s*/, "").replace(/\s*$/, "");
}
function noNull(val) {
if(val == null)
return "";
else
return val;
}
// Prevent cross-site-script(XSS) attack.
// used right before adding user input to the DOM tree. e.g. DOM_element.html(fromdb(user_input));
function sanitizeXSS(val) {
if(val == null || typeof(val) != "string")
return val;
val = val.replace(//g, ">"); //replace > whose unicode is \u003e
return val;
}
function getVmName(p_vmName, p_vmDisplayname) {
if(p_vmDisplayname == null)
return fromdb(p_vmName);
var vmName = null;
if (isAdmin()) {
if (p_vmDisplayname != p_vmName) {
vmName = p_vmName + "(" + fromdb(p_vmDisplayname) + ")";
} else {
vmName = p_vmName;
}
} else {
vmName = fromdb(p_vmDisplayname);
}
return vmName;
}
// FUNCTION: Handles AJAX error callbacks. You can pass in an optional function to
// handle errors that are not already handled by this method.
function handleError(xmlHttp, handleErrorCallback) {
// User Not authenticated
if (xmlHttp.status == ERROR_ACCESS_DENIED_DUE_TO_UNAUTHORIZED) {
$("#dialog_session_expired").dialog("open");
}
else if (xmlHttp.status == ERROR_INTERNET_NAME_NOT_RESOLVED) {
$("#dialog_error_internet_not_resolved").dialog("open");
}
else if (xmlHttp.status == ERROR_INTERNET_CANNOT_CONNECT) {
$("#dialog_error_management_server_not_accessible").dialog("open");
}
else if (xmlHttp.status == ERROR_VMOPS_ACCOUNT_ERROR && handleErrorCallback != undefined) {
handleErrorCallback();
}
else if (handleErrorCallback != undefined) {
handleErrorCallback();
}
else {
var start = xmlHttp.responseText.indexOf("h1") + 3;
var end = xmlHttp.responseText.indexOf("