From 7fdac54358ce43c781455f20144aae845eb2f835 Mon Sep 17 00:00:00 2001
From: Hector Sanjuan <hsanjuan@opennebula.org>
Date: Wed, 23 Mar 2011 16:52:31 +0100
Subject: [PATCH] Feature #507: Improved addition of main tabs. Fixed bugs.
 Commented code.

---
 .../public/js/plugins/dashboard-tab.js        |   8 +-
 src/sunstone/public/js/plugins/hosts-tab.js   |  13 +-
 src/sunstone/public/js/plugins/images-tab.js  |   9 +-
 src/sunstone/public/js/plugins/users-tab.js   |   9 +-
 src/sunstone/public/js/plugins/vms-tab.js     |   9 +-
 src/sunstone/public/js/plugins/vnets-tab.js   |   9 +-
 src/sunstone/public/js/sunstone.js            | 340 ++++++++++--------
 7 files changed, 229 insertions(+), 168 deletions(-)

diff --git a/src/sunstone/public/js/plugins/dashboard-tab.js b/src/sunstone/public/js/plugins/dashboard-tab.js
index edb303c51f..b6bc6fb2ac 100644
--- a/src/sunstone/public/js/plugins/dashboard-tab.js
+++ b/src/sunstone/public/js/plugins/dashboard-tab.js
@@ -149,7 +149,13 @@ var dashboard_tab_content =
 </table>';
 
 
-Sunstone.addMainTab('dashboard_tab','Dashboard',dashboard_tab_content,null);
+var dashboard_tab = {
+    title: 'Dashboard',
+    content: dashboard_tab_content,
+    condition : True
+}
+
+Sunstone.addMainTab('dashboard_tab',dashboard_tab);
 
 $(document).ready(function(){
     //Dashboard link listener
diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js
index dd1c937765..21c45e5e0d 100644
--- a/src/sunstone/public/js/plugins/hosts-tab.js
+++ b/src/sunstone/public/js/plugins/hosts-tab.js
@@ -322,12 +322,17 @@ var host_info_panel = {
         content: ""
     }
 };
-            
+
+
+var hosts_tab = {
+    title: 'Hosts &amp; Clusters',
+    content: hosts_tab_content,
+    buttons: host_buttons,
+    condition: True
+}            
 
 Sunstone.addActions(host_actions);
-
-// title, content, buttons, id
-Sunstone.addMainTab('hosts_tab','Hosts &amp; Clusters',hosts_tab_content,host_buttons);
+Sunstone.addMainTab('hosts_tab',hosts_tab);
 Sunstone.addInfoPanel("host_info_panel",host_info_panel);
 
 
diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js
index ea6eef4c36..de4ab5a5cd 100644
--- a/src/sunstone/public/js/plugins/images-tab.js
+++ b/src/sunstone/public/js/plugins/images-tab.js
@@ -422,8 +422,15 @@ var image_info_panel = {
     
 }
 
+var images_tab = {
+    title: "Images",
+    content: images_tab_content,
+    buttons: image_buttons,
+    condition: True
+}
+
 Sunstone.addActions(image_actions);
-Sunstone.addMainTab('images_tab',"Images",images_tab_content,image_buttons);
+Sunstone.addMainTab('images_tab',images_tab);
 Sunstone.addInfoPanel('image_info_panel',image_info_panel);
 
 
diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js
index e9f1411f12..1c9f2039a6 100644
--- a/src/sunstone/public/js/plugins/users-tab.js
+++ b/src/sunstone/public/js/plugins/users-tab.js
@@ -119,8 +119,15 @@ var user_buttons = {
     }
 }
 
+var users_tab = {
+    title: "Users",
+    content: users_tab_content,
+    buttons: user_buttons,
+    condition: function(){ return uid == 0; }
+}
+
 Sunstone.addActions(user_actions);
-Sunstone.addMainTab('users_tab',"Users",users_tab_content,user_buttons,false,function(){return uid==0;});
+Sunstone.addMainTab('users_tab',users_tab);
 
 
 function userElementArray(user_json){
diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js
index 9c149e43ae..3fd1622da0 100644
--- a/src/sunstone/public/js/plugins/vms-tab.js
+++ b/src/sunstone/public/js/plugins/vms-tab.js
@@ -805,8 +805,15 @@ var vm_info_panel = {
     }
 }
 
+var vms_tab = {
+    title: "Virtual Machines",
+    content: vms_tab_content,
+    buttons: vm_buttons,
+    condition: True
+}
+
 Sunstone.addActions(vm_actions);
-Sunstone.addMainTab('vms_tab',"Virtual Machines",vms_tab_content,vm_buttons);
+Sunstone.addMainTab('vms_tab',vms_tab);
 Sunstone.addInfoPanel('vm_info_panel',vm_info_panel);
 
 
diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js
index 08845611d7..030202981c 100644
--- a/src/sunstone/public/js/plugins/vnets-tab.js
+++ b/src/sunstone/public/js/plugins/vnets-tab.js
@@ -259,8 +259,15 @@ var vnet_info_panel = {
     }
 }
 
+var vnets_tab = {
+    title: "Virtual Networks",
+    content: vnets_tab_content,
+    buttons: vnet_buttons,
+    condition: True
+}
+
 Sunstone.addActions(vnet_actions);
-Sunstone.addMainTab('vnets_tab',"Virtual Networks",vnets_tab_content, vnet_buttons);
+Sunstone.addMainTab('vnets_tab',vnets_tab);
 Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
 
 
diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js
index 1473526406..e425a3a308 100644
--- a/src/sunstone/public/js/sunstone.js
+++ b/src/sunstone/public/js/sunstone.js
@@ -14,69 +14,64 @@
 /* limitations under the License.                                             */
 /* -------------------------------------------------------------------------- */
 
-
-//TODOs: handle confirm and confirm with select dialogs
-
 var cookie = {};
 var username = '';
 var uid = '';
 var spinner = '<img src="/images/ajax-loader.gif" alt="retrieving" class="loading_img"/>';
 
+
+//Sunstone configuration is formed by predifined "actions", main tabs
+//and "info_panels". Each tab has "content" and "buttons". Each 
+//"info_panel" has "tabs" with "content".
 var SunstoneCfg = {
-    "actions" : {
-            
-    
-     },
-        
-     "tabs" : { 
-           
-     },
-        
-     "info_panels" : {
-        
-     }
+    "actions" : {},
+     "tabs" : {},
+     "info_panels" : {}
 };
 
+/* Public plugin interface */
 
 var Sunstone = {
     
-    
+    //Adds a predifined action
     "addAction" : function (name,action_obj) {
         SunstoneCfg["actions"][name] = action_obj;
     },
     
+    //Replaces a predefined action
     "updateAction" : function(name,action_obj) {
          SunstoneCfg["actions"][name] = action_obj;
     },
     
+    //Deletes a predefined action.
     "removeAction" : function(action) {
-         SunstoneCfg["actions"][action] = null;
+         delete SunstoneCfg["actions"][action];
     },
     
+    //Adds several actions encapsulated in an js object.
     "addActions" : function(actions) {
         for (action in actions){
             Sunstone.addAction(action,actions[action]);
         }  
     },
     
-    "addMainTab" : function(tab_id,title_arg,content_arg, buttons_arg,refresh,condition_f) {
-        SunstoneCfg["tabs"][tab_id] = {title: title_arg,
-                                        content: content_arg,
-                                        buttons: buttons_arg,
-                                        condition: condition_f 
-                                        };
+    //Adds a new main tab. Refreshes the dom if wanted.
+    "addMainTab" : function(tab_id,tab_obj,refresh) {
+        SunstoneCfg["tabs"][tab_id] = tab_obj;
         if (refresh){
-            
+            insertTab(tab_id);
         }
     },
     
+    //Updates the content of an info tab and refreshes the DOM if wanted.
     "updateMainTabContent" : function(tab_id,content_arg,refresh){
         SunstoneCfg["tabs"][tab_id]["content"]=content_arg;
-        if (refresh){
+        if (refresh){ //if not present it won't be updated
             $('div#'+tab).html(tab_info.content);
         }
     },
     
+    //Replaces the buttons of an info tab and regenerates them if wanted.
     "updateMainTabButtons" : function(tab_id,buttons_arg,refresh){
         SunstoneCfg["tabs"][tab_id]["buttons"]=buttons_arg;
         if (refresh){
@@ -85,13 +80,16 @@ var Sunstone = {
         }
     },
     
+    //Removes a tab and refreshes the DOM
     "removeMainTab" : function(tab_id,refresh) {
-         SunstoneCfg["tabs"][tab_id]=null;
+         delete SunstoneCfg["tabs"][tab_id];
          if (refresh) {
              $('div#'+tab_name).remove();
          }
     },
     
+    //Generates and returns the HTML div element for an info panel, with
+    //Jquery tabs.
     "getInfoPanelHTML" : function(name,selected_tab){
         var info_panel = $('<div id="'+name+'"><ul></ul></div>');
         var tabs = SunstoneCfg["info_panels"][name];
@@ -108,26 +106,32 @@ var Sunstone = {
         
     },
     
+    //Adds a new info panel
     "addInfoPanel" : function(name, info_panel){
         SunstoneCfg["info_panels"][name]=info_panel;
     },
     
+    //Replaces an existing info panel
     "updateInfoPanel" : function(name, info_panel){
         SunstoneCfg["info_panels"][name]=info_panel;
     },
     
+    //Removes an info panel
     "removeInfoPanel" : function(name){
-        SunstoneCfg["info_panels"][name] = null;
+        delete SunstoneCfg["info_panels"][name];
     },
     
+    //Makes an info panel content pop up in the screen.
     "popUpInfoPanel" : function(name, selected_tab){
         popDialog(Sunstone.getInfoPanelHTML(name, selected_tab));
     },
     
+    //adds a tab to an info panel.
     "addInfoPanelTab" : function(info_panel, tab_name, tab){
         SunstoneCfg["info_panels"][info_panel][tab_name] = tab;
     },
     
+    //Replaces a tab from an info panel. Refreshes the DOM if wanted.
     "updateInfoPanelTab" : function(info_panel, tab_name, tab, refresh){
         SunstoneCfg["info_panels"][info_panel][tab_name] = tab;
         if (refresh){
@@ -135,11 +139,14 @@ var Sunstone = {
         }
     },
     
-    
+    //Removes a tab from an info panel configuration.
     "removeInfoPanelTab" : function(info_panel,tab_name){
-        SunstoneCfg["info_panels"][info_panel][tab_name] = null;
+        delete SunstoneCfg["info_panels"][info_panel][tab_name];
     },
     
+    //Runs a predefined action. Wraps the calls to opennebula.js and
+    //can be use to run action depending on conditions and notify them
+    //if desired.
     "runAction" : function(action, data_arg, extra_param){
     
         var actions = SunstoneCfg["actions"];
@@ -152,9 +159,13 @@ var Sunstone = {
         var notify = action_cfg.notify;
         
         var condition = action_cfg["condition"];
-        if (condition && !condition() && notify){
-            //we do not meet the condition to run this action
+        
+        //Is the condition to run the action met?
+        //Should we inform if it is not met?
+        if (condition && !condition()){
+            if (notify) {
             notifyError("This action cannot be run");
+            }
             return;
         }
         
@@ -163,19 +174,23 @@ var Sunstone = {
         var err = action_cfg["error"];
        
         
-        
+        //Time to close any confirmation dialogs, as the execution may have
+        //come from them.
         $('div#confirm_with_select_dialog').dialog("close");
         $('div#confirm_dialog').dialog("close");
         
         
         //We ease the use of:
-        // * Create call
-        // * Confirm and confirm with select calls
-        // * Calls on multiple elements
-        // * Other calls
+        // * "create" calls to opennebula.js
+        // * "single" element calls to opennebula.js
+        // * "list" (get the pool of elements) calls to opennebula.js
+        // * "multiple" - actions to be run on a given list of elements
+        //      (with maybe an extra parameter).
+        // * The default actions. Simple call the the pre-defined "call"
+        //      function with an extraparam if defined.
         switch (action_cfg.type){
             
-            case "create":
+            case "create","register":
                 call({data:data_arg, success: callback, error:err});
                 break;
             case "single":
@@ -195,8 +210,8 @@ var Sunstone = {
                 });
                 break;
             default: 
-                //we have supposedly altered an action and we want it to do
-                //something completely different
+                //This action is complemente handled by the "call" function.
+                //we pass any data if present.
                 if (data_arg && extra_param) {call(data_arg,extra_param);}
                 else if (data_arg) {call(data_arg);}
                 else {call();}
@@ -204,6 +219,9 @@ var Sunstone = {
         
     },
     
+    //Runs a predefined action on the selected nodes of a datatable.
+    //Optionally they are run with an extra_parameter.
+    //If no datatable is provided, it simply runs the action.
     "runActionOnDatatableNodes": function(action,dataTable,extra_param){
         if (dataTable != null){
             
@@ -219,11 +237,14 @@ var Sunstone = {
             Sunstone.runAction(action,extra_param);
         };
     },
+    
+    //returns a button object from the desired tab
     "getButton" : function(tab_name,button_name){
             var button = null;
             var buttons = SunstoneCfg["tabs"][tab_name]["buttons"];
             button = buttons[button_name];
-            if (!button && buttons["action_list"]) //not found, is it in the list then?
+            //not found, is it in the list then?
+            if (!button && buttons["action_list"]) 
             {
                 button = buttons["action_list"]["actions"][button_name];
             }
@@ -236,17 +257,25 @@ var Sunstone = {
 
 
 
-//plugins have done their jobs when we execute this
+//Plugins have done their pre-ready jobs when we execute this. That means
+//all startup configuration is in place regarding tabs, info panels etc.
 $(document).ready(function(){
     readCookie();
     setLogin();
+    
+    //Insert the tabs in the DOM and their buttons.
     insertTabs();
     insertButtons();
     
+    //Enhace the look of select buttons
     initListButtons();
-    setupCreateDialogs(); //listener for create
+    
+    //Prepare the standard confirmation dialogs
     setupConfirmDialogs();
     
+    //Listen for .action_buttons
+    //An action buttons runs a predefined action. If it has type 
+    //"multiple" it runs that action on the elements of a datatable.
     $('.action_button').live("click",function(){
         
         var table = null;
@@ -264,32 +293,35 @@ $(document).ready(function(){
         return false;
     });
     
+    
+    //Listen .confirm_buttons. These buttons show a confirmation dialog
+    //before running the action.
     $('.confirm_button').live("click",function(){
         popUpConfirmDialog(this);
         return false;
     });
     
+    //Listen .confirm_buttons. These buttons show a confirmation dialog
+    //with a select box before running the action.
     $('.confirm_with_select_button').live("click",function(){
         popUpConfirmWithSelectDialog(this);
         return false;
     });
     
-    
+    //Jquery-enhace the buttons in the DOM
     $('button').button();
-	$('div#select_helpers').hide();
-
     
-    	$(".ui-widget-overlay").live("click", function (){
-		$("div:ui-dialog:visible").dialog("close");
+    //Close overlay dialogs when clicking outside of them.
+    $(".ui-widget-overlay").live("click", function (){
+        $("div:ui-dialog:visible").dialog("close");
     });
 
-
-
-    //Close select lists...
+    //Close select lists when clicking somewhere else.
     $('*:not(.action_list,.list_button)').click(function(){
        $('.action_list:visible').hide();
     });
     
+    //Start with the dashboard (supposing we have one).
     showTab('#dashboard_tab');
     
 });
@@ -307,8 +339,10 @@ function readCookie(){
     });
 }
 
-//sets the user info in the top bar and creates a listner in the signout button
+//sets the user info in the top bar and creates a listner in the 
+//signout button
 function setLogin(){
+    //This two variables can be used anywhere
     username = cookie["one-user"];
     uid = cookie["one-user_id"];
 
@@ -322,128 +356,114 @@ function setLogin(){
     });
 }
 
-
+//Inserts all main tabs in the DOM
 function insertTabs(){
     var tab_info;
     for (tab in SunstoneCfg["tabs"]){
-        tab_info = SunstoneCfg["tabs"][tab];
-        
-        //skip this tab if we do not meet the condition
-        if (tab_info.condition && !tab_info.condition()) {continue;}
-        $("div.inner-center").append('<div id="'+tab+'" class="tab"></div>');
-        $('div#'+tab).html(tab_info.content);
-        
-        $('ul#navigation').append('<li><a href="#'+tab+'">'+tab_info.title+'</a></li>');
-        
+        insertTab(tab);
     }
 }
 
 
+//Inserts a main tab in the DOM. This is done by
+//adding the content to the proper div and by adding a list item
+//link to the navigation menu
+function insertTab(tab_name){
+    var tab_info = SunstoneCfg["tabs"][tab_name];
+    var condition = tab_info["condition"];
+    //skip this tab if we do not meet the condition
+    if (condition && !condition()) {return;}
+    $("div.inner-center").append('<div id="'+tab_name+'" class="tab"></div>');
+    $('div#'+tab_name).html(tab_info.content);
+       
+    $('ul#navigation').append('<li><a href="#'+tab_name+'">'+tab_info.title+'</a></li>');
+}
+
+
+//Inserts the buttons of all tabs.
 function insertButtons(){
      for (tab in SunstoneCfg["tabs"]){
         insertButtonsInTab(tab)
     }
 }
 
+//If we have defined a block of action buttons in a tab,
+//this function takes care of inserting them in the DOM.
 function insertButtonsInTab(tab_name){
     var buttons = SunstoneCfg["tabs"][tab_name]["buttons"];
     var button_code="";
     var sel_obj=null;
+    var condition=null;
     
-    if ($('div#'+tab_name+' .action_blocks').length){
+    //Check if we have included an appropiate space our tab to
+    //insert them (an .action_blocks div)
+    if ($('div#'+tab_name+' div.action_blocks').length){
+        
+        //for every button defined for this tab...
         for (button_name in buttons){
             button_code = "";
             button = buttons[button_name];
-            if (button.condition()) {
-                switch (button.type) {
-                  case "select":
-                    button_code = '<select class="multi_action_slct">';
-                 
-                    for (sel_name in button.actions){
-                        sel_obj = button["actions"][sel_name];
-                        if (sel_obj.condition()){
-                                button_code += '<option class="'+sel_obj.type+'_button" value="'+sel_name+'">'+sel_obj.text+'</option>';
-                        };
-                    };
-                    button_code += '</select>';
-                    break;
-                  case "image":
-                    button_code = '<a href="#" class="action_button" value="'+button_name+'"><img class="image_button" src="'+button.img+'" alt="'+button.text+'" /></a>';
-                    break;
-                  case "create_dialog":
-                    button_code = '<button class="'+button.type+'_button action_button top_button" value="'+button_name+'">'+button.text+'</button>';
-                    break;
-                  default:
-                    button_code = '<button class="'+button.type+'_button top_button" value="'+button_name+'">'+button.text+'</button>';
+            condition = button.condition;
+            //if we meet the condition we proceed. Otherwise we skip it.
+            if (condition && !condition()) { continue; }
                 
-                }
+            //depending on the type of button we generate different
+            //code. There are 4 possible types:
+            /*
+             * select: We need to create a select element with actions inside.
+             * image: a button consisting of a link with an image inside.
+             * create: we make sure they have the "action_button" class.
+             * default: generally buttons have the "<type>_button" class.
+             */
+            switch (button.type) {
+              case "select":
+                button_code = '<select class="multi_action_slct">';
+                //for each subbutton in the list we add an option to the select.
+                for (sel_name in button.actions){
+                    sel_obj = button["actions"][sel_name];
+                    condition = sel_obj.condition;
+                    //only add if we meet the condition
+                    if (condition && !condition()){ continue; };
+                    button_code += '<option class="'+sel_obj.type+'_button" value="'+sel_name+'">'+sel_obj.text+'</option>';
+                };
+                button_code += '</select>';
+                break;
+              case "image":
+                button_code = '<a href="#" class="action_button" value="'+button_name+'"><img class="image_button" src="'+button.img+'" alt="'+button.text+'" /></a>';
+                break;
+              case "create_dialog":
+                button_code = '<button class="'+button.type+'_button action_button top_button" value="'+button_name+'">'+button.text+'</button>';
+                break;
+              default:
+                button_code = '<button class="'+button.type+'_button top_button" value="'+button_name+'">'+button.text+'</button>';
+            
             }
+            
             $('div#'+tab_name+' .action_blocks').append(button_code);
                 
         }//for each button in tab
     }//if tab exists
 }
 
-// We do not insert info panels code, we generate it dynamicly when
-// we need it with getInfoPanelHTML()
-//~ function insertInfoPanels(){
-    //~ var panels = SunstoneCfg["info_panels"];
-    //~ tabs = null;
-    //~ //For each defined dialog
-    //~ for (panel in panels) {
-        //~ addInfoPanel(panel);
-    //~ }
-//~ }
-//~ 
-//~ function addInfoPanel(name){
-    //~ var tabs = SunstoneCfg["info_panels"][name];
-    //~ $('#info_panels').append('<div id="'+name+'"></div>');
-    //~ for (tab in tabs){
-        //~ addInfoPanelTab(name,tab);
-    //~ }
-    //~ //at this point jquery tabs structure is ready, so we enable it
-    //~ $('div#'+name).tabs();
-//~ }
-//~ 
-//~ function refreshInfoPanel(name){
-    //~ $('#info_panels div#'+name).tabs("destroy");
-    //~ $('#info_panels div#'+name).remove();
-    //~ $('#info_panels').append('<div id="'+name+'"></div>');
-    //~ var tabs = SunstoneCfg["info_panels"][name];
-     //~ for (tab in tabs){
-        //~ addInfoPanelTab(name,tab);
-    //~ }
-     //~ //at this point jquery tabs structure is ready, so we enable it
-    //~ $('div#'+name).tabs();
-//~ }
-//~ 
-//~ function addInfoPanelTab(panel_name,tab_name){
-    //~ var tab = SunstoneCfg["info_panels"][panel_name][tab_name];
-    //~ if ( !$('div#'+panel_name+' ul').length ) {
-        //~ $('div#'+panel_name).prepend('<ul></ul>');
-    //~ }
-    //~ $('div#'+panel_name+' ul').append('<li><a href="#'+tab_name+'">'+tab.title+'</a></li>');
-    //~ $('div#'+panel_name).append('<div id="'+tab_name+'">'+tab.content+'</div>');
-//~ }
-//~ 
-
-
 //Tries to refresh a tab content if it is somewhere in the DOM
+//Useful for plugins wanting to update certain information.
 function refreshInfoPanelTab(panel_name,tab_name){
-    var tab = SunstoneCfg["info_panels"][panel_name][tab_name];
-    $('div#'+panel_name+' div#'+tab_name).html(tab.content);
+    var tab_content = SunstoneCfg["info_panels"][panel_name][tab_name].content;
+    $('div#'+panel_name+' div#'+tab_name).html(tab_content);
 }
 
-//Converts selects into buttons which show a of actions when clicked
+//Converts selects into buttons which show a list of actions when 
+//clicked. This lists have two parts, one for the last action run, and 
+//another containing a list of actions that can be folded/unfolded.
 function initListButtons(){
 
         //for each multi_action select
         $('.multi_action_slct').each(function(){
              //prepare replacement buttons
-            buttonset = $('<div style="display:inline-block;" class="top_button"></div');
-            button1 = $('<button class="last_action_button action_button confirm_button confirm_with_select_button" value="">Previous action</button>').button();
+            var buttonset = $('<div style="display:inline-block;" class="top_button"></div');
+            var button1 = $('<button class="last_action_button action_button confirm_button confirm_with_select_button" value="">Previous action</button>').button();
             button1.attr("disabled","disabled");
-            button2 = $('<button class="list_button" value="">See more</button>').button({
+            var button2 = $('<button class="list_button" value="">See more</button>').button({
                 text:false,
                 icons: { primary: "ui-icon-triangle-1-s" }
                 });
@@ -452,12 +472,12 @@ function initListButtons(){
             buttonset.buttonset();
 
             //prepare list
-            options = $('option', $(this));
-             list = $('<ul class="action_list"></ul>');
+            var options = $('option', $(this));
+            var list = $('<ul class="action_list"></ul>');
             $.each(options,function(){
-                classes = $(this).attr("class");
-                item = $('<li></li>');
-                a = $('<a href="#" class="'+classes+'" value="'+$(this).val()+'">'+$(this).text()+'</a>');
+                var classes = $(this).attr("class");
+                var item = $('<li></li>');
+                var a = $('<a href="#" class="'+classes+'" value="'+$(this).val()+'">'+$(this).text()+'</a>');
                 a.val($(this).val());
                 item.html(a);
                 list.append(item);
@@ -476,12 +496,12 @@ function initListButtons(){
         });
 
 
-        //listen for events on this buttons and list
+        //below the listeners for events on these buttons and list
 
         //enable run the last action button
         $('.action_list li a').click(function(){
                 //enable run last action button
-                prev_action_button = $('.last_action_button',$(this).parents('.action_blocks'));
+                var prev_action_button = $('.last_action_button',$(this).parents('.action_blocks'));
                 prev_action_button.val($(this).val());
                 prev_action_button.removeClass("confirm_with_select_button");
                 prev_action_button.removeClass("confirm_button");
@@ -506,26 +526,15 @@ function initListButtons(){
         });
 }
 
-//Sets up all the "+ New Thing" dialogs.
-function setupCreateDialogs(){
-//	createHostDialog();
-//	createClusterDialog();
-//	createVMachineDialog();
-//	createVNetworkDialog();
-//	createUserDialog();
-//    createImageDialog();
-    
-    //Todo listener on "create" class to trigger the right dialog.
-}
-
-//Adds the dialogs bodies
+//Prepares the standard confirm dialogs
 function setupConfirmDialogs(){
     
-    //confirm
+    //add div to the main body if it isn't present.
     if (!($('div#confirm_dialog').length)){
         $('div#dialogs').append('<div id="confirm_dialog" title="Confirmation of action"></div>');
     };
 
+    //add the HTML with the standard question and buttons.
 	$('div#confirm_dialog').html(
 			'<form action="javascript:alert(\'js error!\');">\
 			<div id="confirm_tip">Do you want to proceed?</div>\
@@ -547,8 +556,10 @@ function setupConfirmDialogs(){
 			autoOpen:false
 		});
 
+    //enhace the button look
     $('div#confirm_dialog button').button();
     
+    //same for the confirm with select dialog.
     if (!($('div#confirm_with_select_dialog').length)){
         $('div#dialogs').append('<div id="confirm_with_select_dialog" title="Confirmation of action"></div>');
     };
@@ -564,7 +575,8 @@ function setupConfirmDialogs(){
 			</div>\
 			</form>');
             
-    	//prepare the jquery dialog
+    
+    //prepare the jquery dialog
 	$('div#confirm_with_select_dialog').dialog({
 			resizable:false,
 			modal:true,
@@ -575,12 +587,16 @@ function setupConfirmDialogs(){
         
     $('div#confirm_with_select_dialog button').button();
     
+    //if a cancel button is pressed, we close the dialog.
     $('button.confirm_cancel').click(function(){
 		$('div#confirm_with_select_dialog').dialog("close");
         $('div#confirm_dialog').dialog("close");
 		return false;
 	});
     
+    //when we proceed with a "confirm with select" we need to
+    //find out if we are running an action with a parametre on a datatable
+    //items or if its just an action 
     $('button#confirm_with_select_proceed').click(function(){
         var value = $(this).val();
         var action = SunstoneCfg["actions"][value];
@@ -588,7 +604,7 @@ function setupConfirmDialogs(){
         if (!action) { notifyError("Action "+value+" not defined."); return false;};
         switch (action.type){
             case "multiple": //find the datatable
-                table = SunstoneCfg["actions"][value].dataTable();
+                var table = SunstoneCfg["actions"][value].dataTable();
                 Sunstone.runActionOnDatatableNodes(value,table,param);
                 break;
             default:
@@ -601,6 +617,11 @@ function setupConfirmDialogs(){
     
 }
 
+//Popup a confirmation dialog.
+//In order to find out the dialog action and
+//tip for the user we need to access the clicked button
+//configuration. We do this by discovering the name of the parent tab
+//and with the value of the clicked element.
 function popUpConfirmDialog(target_elem){
     var value = $(target_elem).val();
     var tab_id = $(target_elem).parents('.tab').attr('id');
@@ -611,6 +632,9 @@ function popUpConfirmDialog(target_elem){
     $('div#confirm_dialog').dialog("open");
 }
 
+//Same as previous. This time we need as well to access the updated
+//select list, which is done through the pointer of found in the
+//config of the button (a function returning the select options).
 function popUpConfirmWithSelectDialog(target_elem){
     var value = $(target_elem).val();
     var tab_id = $(target_elem).parents('.tab').attr('id');
@@ -622,8 +646,6 @@ function popUpConfirmWithSelectDialog(target_elem){
     
     $('button#confirm_with_select_proceed').val(value);
     $('div#confirm_with_select_dialog').dialog("open");
-   
-   
 }