You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by se...@apache.org on 2013/07/18 18:34:39 UTC

[04/39] Format JS

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/ad69bc8d/ui/scripts/ui/widgets/multiEdit.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js
index 08bd0bf..a09b0a1 100755
--- a/ui/scripts/ui/widgets/multiEdit.js
+++ b/ui/scripts/ui/widgets/multiEdit.js
@@ -16,1171 +16,1187 @@
 // under the License.
 
 (function($, cloudStack) {
-  var getMultiData = function($multi) {
-    return cloudStack.serializeForm($multi.find('form'));
-  };
-
-  var _medit = cloudStack.ui.widgets.multiEdit = {
-    /**
-     * Append item to list
-     */
-    addItem: function(data, fields, $multi, itemData, actions, options) {
-      if (!options) options = {};
-
-      var $tr;
-      var $item = $('<div>').addClass('data-item');
-      var multiRule = data;
-      var reorder = options.reorder;
-
-      $item.append($('<table>').append($('<tbody>')));
-      $tr = $('<tr>').appendTo($item.find('tbody'));
-      $item.data('json-obj', multiRule);
-
-      if (itemData) {
-        $tr.data('multi-edit-data', itemData);
-      }
-
-      // Add reorder actions
-      if (reorder) {
-        $('<td>').addClass('actions reorder').appendTo($tr).append(function() {
-          var $td = $(this);
-
-          $.each(reorder, function(actionName, action) {
-            var fnLabel = {
-              moveTop: _l('label.move.to.top'),
-              moveBottom: _l('label.move.to.bottom'),
-              moveUp: _l('label.move.up.row'),
-              moveDown: _l('label.move.down.row'),
-              moveDrag: _l('label.drag.new.position')
-            };
+    var getMultiData = function($multi) {
+        return cloudStack.serializeForm($multi.find('form'));
+    };
 
-            $('<div>')
-              .addClass('action reorder')
-              .addClass(actionName)
-              .append(
-                $('<span>').addClass('icon').html('&nbsp;')
-              )
-              .attr({
-                title: _l(fnLabel[actionName])
-              })
-              .appendTo($td)
-              .click(function() {
-                if (actionName == 'moveDrag') return false;
-
-                rowActions[actionName]($tr);
-                $tr.closest('.data-body').find('.data-item').each(function() {
-                  sort($(this), action);
-                });
+    var _medit = cloudStack.ui.widgets.multiEdit = {
+        /**
+         * Append item to list
+         */
+        addItem: function(data, fields, $multi, itemData, actions, options) {
+            if (!options) options = {};
 
-                return false;
-              });
-          });
-        });
-      }
-
-
-    // Setup columns
-    $.each(fields, function(fieldName, field) {
-      if (!field || (options.ignoreEmptyFields && !data[fieldName])) {
-        return true;
-      }
-
-      var $td = $('<td>').addClass(fieldName).appendTo($tr);
-      var $input, val;
-      var $addButton = $multi.find('form .button.add-vm:not(.custom-action)').clone();
-      var newItemRows = [];
-      var addItemAction = function(data) {
-        var $loading = $('<div>').addClass('loading-overlay');
-        var complete = function(args) {
-          var $tbody = $item.find('.expandable-listing tbody');
-
-          $loading.remove();
-          $(data).each(function() {
-            var item = this;
-            var $itemRow = _medit.multiItem.itemRow(item, options.itemActions, multiRule, $tbody);
-
-            $itemRow.appendTo($tbody);
-            newItemRows.push($itemRow);
-
-            cloudStack.evenOdd($tbody, 'tr:visible', {
-              even: function($elem) {
-                $elem.removeClass('odd');
-                $elem.addClass('even');
-              },
-              odd: function($elem) {
-                $elem.removeClass('even');
-                $elem.addClass('odd');
-              }
-            });
-          });
-        };
-        var error = function() {
-          $(newItemRows).each(function() {
-            var $itemRow = this;
+            var $tr;
+            var $item = $('<div>').addClass('data-item');
+            var multiRule = data;
+            var reorder = options.reorder;
 
-            $itemRow.remove();
-          });
-          $loading.remove();
-        };
+            $item.append($('<table>').append($('<tbody>')));
+            $tr = $('<tr>').appendTo($item.find('tbody'));
+            $item.data('json-obj', multiRule);
 
-        $loading.prependTo($item);
-        options.itemActions.add.action({
-          context: options.context,
-          data: data,
-          multiRule: multiRule,
-          response: {
-            success: function(args) {
-              var notificationError = function(args) {
-                error();
-              };
-
-              cloudStack.ui.notifications.add(args.notification,
-                                              complete, {},
-                                              notificationError, {});
-            },
-            error: error
-          }
-        });
-      };
-
-      if (!itemData) itemData = [{}];
-
-      if (!options.noSelect &&
-          $multi.find('th,td').filter(function() {
-            return $(this).attr('rel') == fieldName;
-          }).is(':hidden')) {
-        return true;
-      }
-
-      if (!field.isPassword) {
-        if (field.edit) {
-          // Edit fields append value of data
-          if (field.range) {
-            var start = _s(data[field.range[0]]);
-            var end = _s(data[field.range[1]]);
-
-            $td.append($('<span>').html(start + ' - ' + end));
-          } else {
-            var maxLengths = data['_maxLength'];
-
-            if (maxLengths &&
-                maxLengths[fieldName] &&
-                data[fieldName].length >= maxLengths[fieldName]) {
-              $td.append($('<span>').html(_s(data[fieldName].toString().substr(0, maxLengths[fieldName] - 3).concat('...'))));
-            } else {
-              $td.append($('<span>').html(_s(data[fieldName])));
+            if (itemData) {
+                $tr.data('multi-edit-data', itemData);
             }
-            $td.attr('title', data[fieldName]);
-          }
-        } else if (field.select) {
-          // Get matching option text
-          var $matchingSelect = $multi.find('select')
-                .filter(function() {
-                  return $(this).attr('name') == fieldName;
-                });
-          var $matchingOption = $matchingSelect.find('option')
-                .filter(function() {
-                  return $(this).val() == data[fieldName];
-                });
 
-          var matchingValue = $matchingOption.size() ?
-                $matchingOption.html() : data[fieldName];
-          
-          $td.append($('<span>').html(_s(matchingValue)));
-        } else if (field.addButton && !options.noSelect) {
-          if (options.multipleAdd) {
-            $addButton.click(function() {
-              if ($td.hasClass('disabled')) return false;
-              
-              _medit.vmList($multi,
-                            options.listView,
-                            options.context,
-                            options.multipleAdd, _l('label.add.vms'),
-                            addItemAction,
-                            {
-                              multiRule: multiRule
+            // Add reorder actions
+            if (reorder) {
+                $('<td>').addClass('actions reorder').appendTo($tr).append(function() {
+                    var $td = $(this);
+
+                    $.each(reorder, function(actionName, action) {
+                        var fnLabel = {
+                            moveTop: _l('label.move.to.top'),
+                            moveBottom: _l('label.move.to.bottom'),
+                            moveUp: _l('label.move.up.row'),
+                            moveDown: _l('label.move.down.row'),
+                            moveDrag: _l('label.drag.new.position')
+                        };
+
+                        $('<div>')
+                            .addClass('action reorder')
+                            .addClass(actionName)
+                            .append(
+                                $('<span>').addClass('icon').html('&nbsp;')
+                        )
+                            .attr({
+                                title: _l(fnLabel[actionName])
+                            })
+                            .appendTo($td)
+                            .click(function() {
+                                if (actionName == 'moveDrag') return false;
+
+                                rowActions[actionName]($tr);
+                                $tr.closest('.data-body').find('.data-item').each(function() {
+                                    sort($(this), action);
+                                });
+
+                                return false;
                             });
-
-              return true;
-            });
-            $td.append($addButton);
-          } else {
-            // Show VM data
-            var itemName = data._itemName ? itemData[0][data._itemName] : itemData[0].name;
-            $td.html(options.multipleAdd ?
-                     itemData.length + ' VMs' : itemName);
-            $td.click(function() {
-              var $browser = $(this).closest('.detail-view').data('view-args').$browser;
-
-              if (options.multipleAdd) {
-                _medit.multiItem.details(itemData, $browser);
-              } else {
-                _medit.details(itemData[0], $browser, {
-                  context: options.context, itemName: itemName
+                    });
                 });
-              }
-            });
-          }
-        } else if (field.custom) {
-          var $button = $('<div>').addClass('button add-vm custom-action');
-
-          $td.data('multi-custom-data', data[fieldName]);
-          $button.html(data && data[fieldName] && data[fieldName]['_buttonLabel'] ?
-                       _l(data[fieldName]['_buttonLabel']) : _l(field.custom.buttonLabel));
-          $button.click(function() {
-            if ($td.hasClass('disabled')) return false;
-            
-            var $button = $(this);
-            var context = $.extend(true, {},
-                                   options.context ?
-                                   options.context : cloudStack.context, {
-                                     multiRules: [data]
-                                   });
-
-            field.custom.action({
-              context: context,
-              data: $td.data('multi-custom-data'),
-              $item: $td,
-              response: {
-                success: function(args) {
-                  if (args.data['_buttonLabel']) {
-                    $button.html(_l(args.data['_buttonLabel']));
-                  }
-                  $td.data('multi-custom-data', args.data);
+            }
+
+
+            // Setup columns
+            $.each(fields, function(fieldName, field) {
+                if (!field || (options.ignoreEmptyFields && !data[fieldName])) {
+                    return true;
                 }
-              }
-            });
 
-            return true;
-          });
-          $button.appendTo($td);
-        }
-      }
-
-      // Add blank styling for empty fields
-      if ($td.html() == '') {
-        $td.addClass('blank');
-      }
-
-      // Align width to main header
-      _medit.refreshItemWidths($multi);
-
-      if (data._hideFields &&
-          $.inArray(fieldName, data._hideFields) > -1) {
-        $td.addClass('disabled');
-      }
-
-      return true;
-    });
-
-    // Actions column
-    var $actions = $('<td>').addClass('multi-actions').appendTo($item.find('tr'));
-
-    // Align action column width
-    $actions.width($multi.find('th.multi-actions').width() + 4);
-
-    // Action filter
-    var allowedActions = options.preFilter ? options.preFilter({
-      actions: $.map(actions, function(value, key) { return key; }),
-      context: $.extend(true, {}, options.context, {
-        multiRule: [data],
-        actions: $.map(actions, function(value, key) { return key; })
-      })
-    }) : null;
-
-    // Append actions
-    $.each(actions, function(actionID, action) {
-      if (allowedActions && $.inArray(actionID, allowedActions) == -1) return true;
-
-      $actions.append(
-        $('<div>').addClass('action')
-          .addClass(actionID)
-          .append($('<span>').addClass('icon'))
-          .attr({ title: _l(action.label) })
-          .click(function() {
-            var performAction = function(actionOptions) {
-              if (!actionOptions) actionOptions = {};
-
-              action.action({
-                context: $.extend(true, {}, options.context, {
-                  multiRule: [data]
-                }),
-                data: actionOptions.data,
-                response: {
-                  success: function(args) {
-                    var notification = args ? args.notification : null;
-                    var _custom = args ? args._custom : null;
-                    if (notification) {
-                      $('.notifications').notifications('add', {
-                        section: 'network',
-                        desc: notification.label,
-                        interval: 3000,
-                        _custom: _custom,
-                        poll: function(args) {
-                          var complete = args.complete;
-                          var error = args.error;
-
-                          notification.poll({
-                            _custom: args._custom,
-                            complete: function(args) {
-                              if (isDestroy) {
-                                $loading.remove();
-                                $dataItem.remove();
-                              } else {
-                                $multi.trigger('refresh');
-                              }
+                var $td = $('<td>').addClass(fieldName).appendTo($tr);
+                var $input, val;
+                var $addButton = $multi.find('form .button.add-vm:not(.custom-action)').clone();
+                var newItemRows = [];
+                var addItemAction = function(data) {
+                    var $loading = $('<div>').addClass('loading-overlay');
+                    var complete = function(args) {
+                        var $tbody = $item.find('.expandable-listing tbody');
+
+                        $loading.remove();
+                        $(data).each(function() {
+                            var item = this;
+                            var $itemRow = _medit.multiItem.itemRow(item, options.itemActions, multiRule, $tbody);
+
+                            $itemRow.appendTo($tbody);
+                            newItemRows.push($itemRow);
+
+                            cloudStack.evenOdd($tbody, 'tr:visible', {
+                                even: function($elem) {
+                                    $elem.removeClass('odd');
+                                    $elem.addClass('even');
+                                },
+                                odd: function($elem) {
+                                    $elem.removeClass('even');
+                                    $elem.addClass('odd');
+                                }
+                            });
+                        });
+                    };
+                    var error = function() {
+                        $(newItemRows).each(function() {
+                            var $itemRow = this;
 
-                              complete();
+                            $itemRow.remove();
+                        });
+                        $loading.remove();
+                    };
 
-                              if (actionOptions.complete) actionOptions.complete();
+                    $loading.prependTo($item);
+                    options.itemActions.add.action({
+                        context: options.context,
+                        data: data,
+                        multiRule: multiRule,
+                        response: {
+                            success: function(args) {
+                                var notificationError = function(args) {
+                                    error();
+                                };
+
+                                cloudStack.ui.notifications.add(args.notification,
+                                    complete, {},
+                                    notificationError, {});
                             },
-                            error: function(args) {
-                              error(args);
-                              $multi.trigger('refresh');
+                            error: error
+                        }
+                    });
+                };
 
-                              return cloudStack.dialog.error;
+                if (!itemData) itemData = [{}];
+
+                if (!options.noSelect &&
+                    $multi.find('th,td').filter(function() {
+                        return $(this).attr('rel') == fieldName;
+                    }).is(':hidden')) {
+                    return true;
+                }
+
+                if (!field.isPassword) {
+                    if (field.edit) {
+                        // Edit fields append value of data
+                        if (field.range) {
+                            var start = _s(data[field.range[0]]);
+                            var end = _s(data[field.range[1]]);
+
+                            $td.append($('<span>').html(start + ' - ' + end));
+                        } else {
+                            var maxLengths = data['_maxLength'];
+
+                            if (maxLengths &&
+                                maxLengths[fieldName] &&
+                                data[fieldName].length >= maxLengths[fieldName]) {
+                                $td.append($('<span>').html(_s(data[fieldName].toString().substr(0, maxLengths[fieldName] - 3).concat('...'))));
+                            } else {
+                                $td.append($('<span>').html(_s(data[fieldName])));
                             }
-                          });
+                            $td.attr('title', data[fieldName]);
                         }
-                      });
-                    } else {
-                      $loading.remove();
-                      if (isDestroy) {
-                        $dataItem.remove();
-                      }
+                    } else if (field.select) {
+                        // Get matching option text
+                        var $matchingSelect = $multi.find('select')
+                            .filter(function() {
+                                return $(this).attr('name') == fieldName;
+                            });
+                        var $matchingOption = $matchingSelect.find('option')
+                            .filter(function() {
+                                return $(this).val() == data[fieldName];
+                            });
+
+                        var matchingValue = $matchingOption.size() ?
+                            $matchingOption.html() : data[fieldName];
+
+                        $td.append($('<span>').html(_s(matchingValue)));
+                    } else if (field.addButton && !options.noSelect) {
+                        if (options.multipleAdd) {
+                            $addButton.click(function() {
+                                if ($td.hasClass('disabled')) return false;
+
+                                _medit.vmList($multi,
+                                    options.listView,
+                                    options.context,
+                                    options.multipleAdd, _l('label.add.vms'),
+                                    addItemAction, {
+                                        multiRule: multiRule
+                                    });
+
+                                return true;
+                            });
+                            $td.append($addButton);
+                        } else {
+                            // Show VM data
+                            var itemName = data._itemName ? itemData[0][data._itemName] : itemData[0].name;
+                            $td.html(options.multipleAdd ?
+                                itemData.length + ' VMs' : itemName);
+                            $td.click(function() {
+                                var $browser = $(this).closest('.detail-view').data('view-args').$browser;
+
+                                if (options.multipleAdd) {
+                                    _medit.multiItem.details(itemData, $browser);
+                                } else {
+                                    _medit.details(itemData[0], $browser, {
+                                        context: options.context,
+                                        itemName: itemName
+                                    });
+                                }
+                            });
+                        }
+                    } else if (field.custom) {
+                        var $button = $('<div>').addClass('button add-vm custom-action');
+
+                        $td.data('multi-custom-data', data[fieldName]);
+                        $button.html(data && data[fieldName] && data[fieldName]['_buttonLabel'] ?
+                            _l(data[fieldName]['_buttonLabel']) : _l(field.custom.buttonLabel));
+                        $button.click(function() {
+                            if ($td.hasClass('disabled')) return false;
+
+                            var $button = $(this);
+                            var context = $.extend(true, {},
+                                options.context ?
+                                options.context : cloudStack.context, {
+                                    multiRules: [data]
+                                });
+
+                            field.custom.action({
+                                context: context,
+                                data: $td.data('multi-custom-data'),
+                                $item: $td,
+                                response: {
+                                    success: function(args) {
+                                        if (args.data['_buttonLabel']) {
+                                            $button.html(_l(args.data['_buttonLabel']));
+                                        }
+                                        $td.data('multi-custom-data', args.data);
+                                    }
+                                }
+                            });
+
+                            return true;
+                        });
+                        $button.appendTo($td);
                     }
-                  },
-                  error: function(message) {
-                    cloudStack.dialog.notice({ message: message });
-                    $item.show();
-                    $dataItem.find('.loading-overlay').remove();
-                  }
                 }
-              });
-            };
 
-            var $target = $(this);
-            var $dataItem = $target.closest('.data-item');
-            var $expandable = $dataItem.find('.expandable-listing');
-            var isDestroy = $target.hasClass('destroy');
-            var isEdit = $target.hasClass('edit');
-            var createForm = action.createForm;
-            var reorder = options.reorder;
+                // Add blank styling for empty fields
+                if ($td.html() == '') {
+                    $td.addClass('blank');
+                }
 
-            if (isDestroy) {
-              var $loading = _medit.loadingItem($multi, _l('label.removing') + '...');
+                // Align width to main header
+                _medit.refreshItemWidths($multi);
 
-              if ($expandable.is(':visible')) {
-                $expandable.slideToggle(function() {
-                  $dataItem.hide();
-                  $dataItem.after($loading);
-                });
-              } else {
-                // Loading appearance
-                $dataItem.hide();
-                $dataItem.after($loading);
-              }
+                if (data._hideFields &&
+                    $.inArray(fieldName, data._hideFields) > -1) {
+                    $td.addClass('disabled');
+                }
+
+                return true;
+            });
+
+            // Actions column
+            var $actions = $('<td>').addClass('multi-actions').appendTo($item.find('tr'));
+
+            // Align action column width
+            $actions.width($multi.find('th.multi-actions').width() + 4);
+
+            // Action filter
+            var allowedActions = options.preFilter ? options.preFilter({
+                actions: $.map(actions, function(value, key) {
+                    return key;
+                }),
+                context: $.extend(true, {}, options.context, {
+                    multiRule: [data],
+                    actions: $.map(actions, function(value, key) {
+                        return key;
+                    })
+                })
+            }) : null;
+
+            // Append actions
+            $.each(actions, function(actionID, action) {
+                if (allowedActions && $.inArray(actionID, allowedActions) == -1) return true;
+
+                $actions.append(
+                    $('<div>').addClass('action')
+                    .addClass(actionID)
+                    .append($('<span>').addClass('icon'))
+                    .attr({
+                        title: _l(action.label)
+                    })
+                    .click(function() {
+                        var performAction = function(actionOptions) {
+                            if (!actionOptions) actionOptions = {};
+
+                            action.action({
+                                context: $.extend(true, {}, options.context, {
+                                    multiRule: [data]
+                                }),
+                                data: actionOptions.data,
+                                response: {
+                                    success: function(args) {
+                                        var notification = args ? args.notification : null;
+                                        var _custom = args ? args._custom : null;
+                                        if (notification) {
+                                            $('.notifications').notifications('add', {
+                                                section: 'network',
+                                                desc: notification.label,
+                                                interval: 3000,
+                                                _custom: _custom,
+                                                poll: function(args) {
+                                                    var complete = args.complete;
+                                                    var error = args.error;
+
+                                                    notification.poll({
+                                                        _custom: args._custom,
+                                                        complete: function(args) {
+                                                            if (isDestroy) {
+                                                                $loading.remove();
+                                                                $dataItem.remove();
+                                                            } else {
+                                                                $multi.trigger('refresh');
+                                                            }
+
+                                                            complete();
+
+                                                            if (actionOptions.complete) actionOptions.complete();
+                                                        },
+                                                        error: function(args) {
+                                                            error(args);
+                                                            $multi.trigger('refresh');
+
+                                                            return cloudStack.dialog.error;
+                                                        }
+                                                    });
+                                                }
+                                            });
+                                        } else {
+                                            $loading.remove();
+                                            if (isDestroy) {
+                                                $dataItem.remove();
+                                            }
+                                        }
+                                    },
+                                    error: function(message) {
+                                        cloudStack.dialog.notice({
+                                            message: message
+                                        });
+                                        $item.show();
+                                        $dataItem.find('.loading-overlay').remove();
+                                    }
+                                }
+                            });
+                        };
+
+                        var $target = $(this);
+                        var $dataItem = $target.closest('.data-item');
+                        var $expandable = $dataItem.find('.expandable-listing');
+                        var isDestroy = $target.hasClass('destroy');
+                        var isEdit = $target.hasClass('edit');
+                        var createForm = action.createForm;
+                        var reorder = options.reorder;
+
+                        if (isDestroy) {
+                            var $loading = _medit.loadingItem($multi, _l('label.removing') + '...');
+
+                            if ($expandable.is(':visible')) {
+                                $expandable.slideToggle(function() {
+                                    $dataItem.hide();
+                                    $dataItem.after($loading);
+                                });
+                            } else {
+                                // Loading appearance
+                                $dataItem.hide();
+                                $dataItem.after($loading);
+                            }
+                        }
+
+                        if (!isEdit) {
+                            if (createForm) {
+                                cloudStack.dialog.createForm({
+                                    form: createForm,
+                                    after: function(args) {
+                                        var $loading = $('<div>').addClass('loading-overlay').prependTo($dataItem);
+                                        performAction({
+                                            data: args.data,
+                                            complete: function() {
+                                                $multi.trigger('refresh');
+                                            }
+                                        });
+                                    }
+                                });
+                            } else {
+                                performAction();
+                            }
+                        } else {
+                            // Get editable fields
+                            var editableFields = {};
+
+                            $.each(fields, function(key, field) {
+                                field.isDisabled = false;
+
+                                if (field && field.isEditable) editableFields[key] = $.extend(true, {}, field, {
+                                    defaultValue: data[key]
+                                });
+                            });
+
+                            cloudStack.dialog.createForm({
+                                form: {
+                                    title: 'Edit rule',
+                                    desc: '',
+                                    fields: editableFields
+                                },
+                                after: function(args) {
+                                    var $loading = $('<div>').addClass('loading-overlay').prependTo($dataItem);
+                                    performAction({
+                                        data: args.data,
+                                        complete: function() {
+                                            $multi.trigger('refresh');
+                                        }
+                                    });
+                                }
+                            });
+                        }
+                    })
+                );
+            });
+
+            // Add tagger action
+            if (options.tags) {
+                $actions.prepend(
+                    $('<div></div>')
+                    .addClass('action editTags')
+                    .attr('title', _l('label.edit.tags'))
+                    .append($('<span></span>').addClass('icon'))
+                    .click(function() {
+                        $('<div>')
+                            .dialog({
+                                dialogClass: 'editTags',
+                                title: _l('label.edit.tags'),
+                                width: 400,
+                                buttons: [{
+                                    text: _l('label.done'),
+                                    'class': 'ok',
+                                    click: function() {
+                                        $(this).dialog('destroy');
+                                        $('div.overlay:last').remove();
+
+                                        return true;
+                                    }
+                                }]
+                            })
+                            .append(
+                                $('<div></div>').addClass('multi-edit-tags').tagger($.extend(true, {}, options.tags, {
+                                    context: $.extend(true, {}, options.context, {
+                                        multiRule: [multiRule]
+                                    })
+                                }))
+                        )
+                            .closest('.ui-dialog').overlay();
+
+                        return false;
+                    })
+                )
             }
 
-            if (!isEdit) {
-              if (createForm) {
-                cloudStack.dialog.createForm({
-                  form: createForm,
-                  after: function(args) {
-                    var $loading = $('<div>').addClass('loading-overlay').prependTo($dataItem);
-                    performAction({ data: args.data, complete: function() {
-                      $multi.trigger('refresh');
-                    } });
-                  }
-                });
-              } else {
-                performAction();
-              }
-            } else {
-              // Get editable fields
-              var editableFields = {};
-
-              $.each(fields, function(key, field) {
-                field.isDisabled = false;
-                
-                if (field && field.isEditable) editableFields[key] = $.extend(true, {}, field, {
-                  defaultValue: data[key]
-                });
-              });
-
-              cloudStack.dialog.createForm({
-                form: {
-                  title: 'Edit rule',
-                  desc: '',
-                  fields: editableFields
-                },
-                after: function(args) {
-                  var $loading = $('<div>').addClass('loading-overlay').prependTo($dataItem);
-                  performAction({ data: args.data, complete: function() {
-                    $multi.trigger('refresh');
-                  } });
-                }
-              });
+            // Add expandable listing, for multiple-item
+            if (options.multipleAdd) {
+                // Create expandable box
+                _medit.multiItem.expandable($item.find('tr').data('multi-edit-data'),
+                    options.itemActions,
+                    multiRule).appendTo($item);
+
+                // Expandable icon/action
+                $item.find('td:first').prepend(
+                    $('<div>').addClass('expand').click(function() {
+                        $item.closest('.data-item').find('.expandable-listing').slideToggle();
+                    }));
             }
-          })
-      );
-    });
-
-    // Add tagger action
-    if (options.tags) {
-      $actions.prepend(
-        $('<div></div>')
-          .addClass('action editTags')
-          .attr('title', _l('label.edit.tags'))
-          .append($('<span></span>').addClass('icon'))
-          .click(function() {
-            $('<div>')
-              .dialog({
-                dialogClass: 'editTags',
-                title: _l('label.edit.tags'),
-                width: 400,
-                buttons: [
-                  {
-                    text: _l('label.done'),
+
+            return $item;
+        },
+
+        vmList: function($multi, listView, context, isMultipleAdd, label, complete, options) {
+            if (!options) options = {};
+
+            // Create a listing of instances, based on limited information
+            // from main instances list view
+            var $listView;
+            var instances = $.extend(true, {}, listView, {
+                context: $.extend(true, {}, context, {
+                    multiData: getMultiData($multi),
+                    multiRule: options.multiRule ? [options.multiRule] : null
+                }),
+                uiCustom: true
+            });
+
+            instances.listView.actions = {
+                select: {
+                    label: 'Select instance',
+                    type: isMultipleAdd ? 'checkbox' : 'radio',
+                    action: {
+                        uiCustom: function(args) {
+                            var $item = args.$item;
+                            var $input = $item.find('td.actions input:visible');
+
+                            if ($input.attr('type') == 'checkbox') {
+                                if ($input.is(':checked'))
+                                    $item.addClass('multi-edit-selected');
+                                else
+                                    $item.removeClass('multi-edit-selected');
+                            } else {
+                                $item.siblings().removeClass('multi-edit-selected');
+                                $item.addClass('multi-edit-selected');
+                            }
+                        }
+                    }
+                }
+            };
+
+            $listView = $('<div>').listView(instances);
+
+            // Change action label
+            $listView.find('th.actions').html(_l('Select'));
+
+            var $dataList = $listView.addClass('multi-edit-add-list').dialog({
+                dialogClass: 'multi-edit-add-list panel',
+                width: 825,
+                title: label,
+                buttons: [{
+                    text: _l('label.apply'),
                     'class': 'ok',
                     click: function() {
-                      $(this).dialog('destroy');
-                      $('div.overlay:last').remove();
+                        if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').size()) {
+                            cloudStack.dialog.notice({
+                                message: _l('message.select.item')
+                            });
 
-                      return true;
-                    }
-                  }
-                ]
-              })
-              .append(
-                $('<div></div>').addClass('multi-edit-tags').tagger($.extend(true, {}, options.tags, {
-                  context: $.extend(true, {}, options.context, {
-                    multiRule: [multiRule]
-                  })
-                }))
-              )
-              .closest('.ui-dialog').overlay();
-
-            return false;
-          })
-      )
-    }
-
-    // Add expandable listing, for multiple-item
-    if (options.multipleAdd) {
-      // Create expandable box
-      _medit.multiItem.expandable($item.find('tr').data('multi-edit-data'),
-                                  options.itemActions,
-                                  multiRule).appendTo($item);
-
-      // Expandable icon/action
-      $item.find('td:first').prepend(
-        $('<div>').addClass('expand').click(function() {
-          $item.closest('.data-item').find('.expandable-listing').slideToggle();
-        }));
-    }
-
-    return $item;
-  },
-
-  vmList: function($multi, listView, context, isMultipleAdd, label, complete, options) {
-    if (!options) options = {};
-
-    // Create a listing of instances, based on limited information
-    // from main instances list view
-    var $listView;
-    var instances = $.extend(true, {}, listView, {
-      context: $.extend(true, {}, context, {
-        multiData: getMultiData($multi),
-        multiRule: options.multiRule ? [options.multiRule] : null
-      }),
-      uiCustom: true
-    });
-
-    instances.listView.actions = {
-      select: {
-        label: 'Select instance',
-        type: isMultipleAdd ? 'checkbox' : 'radio',
-        action: {
-          uiCustom: function(args) {
-            var $item = args.$item;
-            var $input = $item.find('td.actions input:visible');
-
-            if ($input.attr('type') == 'checkbox') {
-              if ($input.is(':checked'))
-                $item.addClass('multi-edit-selected');
-              else
-                $item.removeClass('multi-edit-selected');
-            } else {
-              $item.siblings().removeClass('multi-edit-selected');
-              $item.addClass('multi-edit-selected');
-            }
-          }
-        }
-      }
-    };
+                            return false;
+                        }
 
-    $listView = $('<div>').listView(instances);
+                        $dataList.fadeOut(function() {
+                            complete($.map(
+                                $listView.find('tr.multi-edit-selected'),
 
-    // Change action label
-    $listView.find('th.actions').html(_l('Select'));
+                                // Attach VM data to row
 
-    var $dataList = $listView.addClass('multi-edit-add-list').dialog({
-      dialogClass: 'multi-edit-add-list panel',
-      width: 825,
-      title: label,
-      buttons: [
-        {
-          text: _l('label.apply'),
-          'class': 'ok',
-          click: function() {
-            if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').size()) {
-              cloudStack.dialog.notice({ message: _l('message.select.item')});
+                                function(elem) {
+                                    var itemData = $(elem).data('json-obj');
+                                    var $subselect = $(elem).find('.subselect select');
 
-              return false;
-            }
+                                    // Include subselect data
+                                    if ($subselect && $subselect.val()) {
+                                        return $.extend(itemData, {
+                                            _subselect: $subselect.val()
+                                        });
+                                    }
 
-            $dataList.fadeOut(function() {
-              complete($.map(
-                $listView.find('tr.multi-edit-selected'),
+                                    return itemData;
+                                }
+                            ));
+                            $dataList.remove();
+                        });
 
-                // Attach VM data to row
-                function(elem) {
-                  var itemData = $(elem).data('json-obj');
-                  var $subselect = $(elem).find('.subselect select');
+                        $('div.overlay').fadeOut(function() {
+                            $('div.overlay').remove();
+                        });
 
-                  // Include subselect data
-                  if ($subselect && $subselect.val()) {
-                    return $.extend(itemData, {
-                      _subselect: $subselect.val()
-                    });
-                  }
-                  
-                  return itemData;
-                }
-              ));
-              $dataList.remove();
-            });
+                        return true;
+                    }
+                }, {
+                    text: _l('label.cancel'),
+                    'class': 'cancel',
+                    click: function() {
+                        $dataList.fadeOut(function() {
+                            $dataList.remove();
+                        });
+                        $('div.overlay').fadeOut(function() {
+                            $('div.overlay').remove();
+                        });
+                    }
+                }]
+            }).parent('.ui-dialog').overlay();
+        },
 
-            $('div.overlay').fadeOut(function() {
-              $('div.overlay').remove();
+        /**
+         * Align width of each data row to main header
+         */
+        refreshItemWidths: function($multi) {
+            $multi.find('.data-body').width(
+                $multi.find('form > table.multi-edit').width()
+            );
+
+            $multi.find('.data tr').filter(function() {
+                return !$(this).closest('.expandable-listing').size();
+            }).each(function() {
+                var $tr = $(this);
+
+                $tr.find('td').each(function() {
+                    var $td = $(this);
+
+                    $td.width($($multi.find('th:visible')[$td.index()]).width() + 5);
+                });
             });
+        },
 
-            return true;
-          }
+        /**
+         * Create a fake 'loading' item box
+         */
+        loadingItem: function($multi, label) {
+            var $loading = $('<div>').addClass('data-item loading');
+
+            // Align height with existing items
+            var $row = $multi.find('.data-item:first');
+
+            // Set label
+            if (label) {
+                $loading.append(
+                    $('<div>').addClass('label').append(
+                        $('<span>').html(_l(label))
+                    )
+                );
+            }
+
+            return $loading;
         },
-        {
-          text: _l('label.cancel'),
-          'class': 'cancel',
-          click: function() {
-            $dataList.fadeOut(function() {
-              $dataList.remove();
-            });
-            $('div.overlay').fadeOut(function() {
-              $('div.overlay').remove();
+        details: function(data, $browser, options) {
+            if (!options) options = {};
+
+            var detailViewArgs, $detailView;
+
+            detailViewArgs = $.extend(true, {}, cloudStack.sections.instances.listView.detailView);
+            detailViewArgs.actions = null;
+            detailViewArgs.$browser = $browser;
+            detailViewArgs.id = data.id;
+            detailViewArgs.jsonObj = data;
+            detailViewArgs.context = options.context;
+
+            $browser.cloudBrowser('addPanel', {
+                title: options.itemName ? options.itemName : data.name,
+                maximizeIfSelected: true,
+                complete: function($newPanel) {
+                    $newPanel.detailView(detailViewArgs);
+                }
             });
-          }
-        }
-      ]
-    }).parent('.ui-dialog').overlay();
-  },
-
-  /**
-   * Align width of each data row to main header
-   */
-  refreshItemWidths: function($multi) {
-    $multi.find('.data-body').width(
-      $multi.find('form > table.multi-edit').width()
-    );
-
-    $multi.find('.data tr').filter(function() {
-      return !$(this).closest('.expandable-listing').size();
-    }).each(function() {
-      var $tr = $(this);
-
-      $tr.find('td').each(function() {
-        var $td = $(this);
-
-        $td.width($($multi.find('th:visible')[$td.index()]).width() + 5);
-      });
-    });
-  },
-
-  /**
-   * Create a fake 'loading' item box
-   */
-  loadingItem: function($multi, label) {
-    var $loading = $('<div>').addClass('data-item loading');
-
-    // Align height with existing items
-    var $row = $multi.find('.data-item:first');
-
-    // Set label
-    if (label) {
-      $loading.append(
-        $('<div>').addClass('label').append(
-          $('<span>').html(_l(label))
-        )
-      );
-    }
-
-    return $loading;
-  },
-  details: function(data, $browser, options) {
-    if (!options) options = {};
-
-    var detailViewArgs, $detailView;
-
-    detailViewArgs = $.extend(true, {}, cloudStack.sections.instances.listView.detailView);
-    detailViewArgs.actions = null;
-    detailViewArgs.$browser = $browser;
-    detailViewArgs.id = data.id;
-    detailViewArgs.jsonObj = data;
-    detailViewArgs.context = options.context;
-
-    $browser.cloudBrowser('addPanel', {
-      title: options.itemName ? options.itemName : data.name,
-      maximizeIfSelected: true,
-      complete: function($newPanel) {
-        $newPanel.detailView(detailViewArgs);
-      }
-    });
-  },
-  multiItem: {
-    /**
-     * Show listing of load balanced VMs
-     */
-    details: function(data, $browser) {
-      var listViewArgs, $listView;
-
-      // Setup list view
-      listViewArgs = $.extend(true, {}, cloudStack.sections.instances);
-      listViewArgs.listView.actions = null;
-      listViewArgs.listView.filters = null;
-      listViewArgs.$browser = $browser;
-      listViewArgs.listView.detailView.actions = null;
-      listViewArgs.listView.dataProvider = function(args) {
-        setTimeout(function() {
-          args.response.success({
-            data: data
-          });
-        }, 50);
-      };
-      $listView = $('<div>').listView(listViewArgs);
-
-      // Show list view of selected VMs
-      $browser.cloudBrowser('addPanel', {
-        title: _l('label.item.listing'),
-        data: '',
-        noSelectPanel: true,
-        maximizeIfSelected: true,
-        complete: function($newPanel) {
-          return $newPanel.listView(listViewArgs);
-        }
-      });
-    },
-
-    itemRow: function(item, itemActions, multiRule, $tbody) {
-      var $tr = $('<tr>');
-      var itemName = multiRule._itemName ? item[multiRule._itemName] : item.name;
-      var $itemName = $('<span>').html(_s(itemName));
-
-      $tr.append($('<td>').addClass('name').appendTo($tr).append($itemName));
-
-      $itemName.click(function() {
-        _medit.details(item, $('#browser .container'), {
-          itemName: itemName,
-          context: {
-            instances: [item]
-          }
-        });
-      });
+        },
+        multiItem: {
+            /**
+             * Show listing of load balanced VMs
+             */
+            details: function(data, $browser) {
+                var listViewArgs, $listView;
+
+                // Setup list view
+                listViewArgs = $.extend(true, {}, cloudStack.sections.instances);
+                listViewArgs.listView.actions = null;
+                listViewArgs.listView.filters = null;
+                listViewArgs.$browser = $browser;
+                listViewArgs.listView.detailView.actions = null;
+                listViewArgs.listView.dataProvider = function(args) {
+                    setTimeout(function() {
+                        args.response.success({
+                            data: data
+                        });
+                    }, 50);
+                };
+                $listView = $('<div>').listView(listViewArgs);
+
+                // Show list view of selected VMs
+                $browser.cloudBrowser('addPanel', {
+                    title: _l('label.item.listing'),
+                    data: '',
+                    noSelectPanel: true,
+                    maximizeIfSelected: true,
+                    complete: function($newPanel) {
+                        return $newPanel.listView(listViewArgs);
+                    }
+                });
+            },
 
-      var itemState=multiRule._itemState ? item[multiRule._itemState] :item.state;
-      var $itemState = $('<span>').html(_s(itemState));
-      $tr.append($('<td>').addClass('state').appendTo($tr).append("Application State - ").append($itemState));
+            itemRow: function(item, itemActions, multiRule, $tbody) {
+                var $tr = $('<tr>');
+                var itemName = multiRule._itemName ? item[multiRule._itemName] : item.name;
+                var $itemName = $('<span>').html(_s(itemName));
 
+                $tr.append($('<td>').addClass('name').appendTo($tr).append($itemName));
 
-      if (itemActions) {
-        var $itemActions = $('<td>').addClass('actions item-actions');
+                $itemName.click(function() {
+                    _medit.details(item, $('#browser .container'), {
+                        itemName: itemName,
+                        context: {
+                            instances: [item]
+                        }
+                    });
+                });
 
-        $.each(itemActions, function(itemActionID, itemAction) {
-          if (itemActionID == 'add') 
-            return true;
-                              
-          if(item._hideActions != null && $.inArray(itemActionID, item._hideActions) > -1)
-            return true;	
-
-          var $itemAction = $('<div>').addClass('action').addClass(itemActionID);
-
-          $itemAction.click(function() {
-            itemAction.action({
-              item: item,
-              multiRule: multiRule,
-              response: {
-                success: function(args) {
-                  if (itemActionID == 'destroy') {
-                    var notification = args.notification;
-                    var success = function(args) { $tr.remove(); };
-                    var successArgs = {};
-                    var error = function(args) {
-                      $tr.show();
-                      cloudStack.evenOdd($tbody, 'tr:visible', {
+                var itemState = multiRule._itemState ? item[multiRule._itemState] : item.state;
+                var $itemState = $('<span>').html(_s(itemState));
+                $tr.append($('<td>').addClass('state').appendTo($tr).append("Application State - ").append($itemState));
+
+
+                if (itemActions) {
+                    var $itemActions = $('<td>').addClass('actions item-actions');
+
+                    $.each(itemActions, function(itemActionID, itemAction) {
+                        if (itemActionID == 'add')
+                            return true;
+
+                        if (item._hideActions != null && $.inArray(itemActionID, item._hideActions) > -1)
+                            return true;
+
+                        var $itemAction = $('<div>').addClass('action').addClass(itemActionID);
+
+                        $itemAction.click(function() {
+                            itemAction.action({
+                                item: item,
+                                multiRule: multiRule,
+                                response: {
+                                    success: function(args) {
+                                        if (itemActionID == 'destroy') {
+                                            var notification = args.notification;
+                                            var success = function(args) {
+                                                $tr.remove();
+                                            };
+                                            var successArgs = {};
+                                            var error = function(args) {
+                                                $tr.show();
+                                                cloudStack.evenOdd($tbody, 'tr:visible', {
+                                                    even: function($elem) {
+                                                        $elem.removeClass('odd');
+                                                        $elem.addClass('even');
+                                                    },
+                                                    odd: function($elem) {
+                                                        $elem.removeClass('even');
+                                                        $elem.addClass('odd');
+                                                    }
+                                                });
+                                            };
+                                            var errorArgs = {};
+
+                                            $tr.hide();
+                                            cloudStack.evenOdd($tbody, 'tr:visible', {
+                                                even: function($elem) {
+                                                    $elem.removeClass('odd');
+                                                    $elem.addClass('even');
+                                                },
+                                                odd: function($elem) {
+                                                    $elem.removeClass('even');
+                                                    $elem.addClass('odd');
+                                                }
+                                            });
+                                            cloudStack.ui.notifications.add(notification,
+                                                success, successArgs,
+                                                error, errorArgs);
+                                        }
+                                    },
+                                    error: function(message) {
+                                        if (message) {
+                                            cloudStack.dialog.notice({
+                                                message: message
+                                            });
+                                        }
+                                    }
+                                }
+                            });
+                        });
+                        $itemAction.append($('<span>').addClass('icon'));
+                        $itemAction.appendTo($itemActions);
+
+                        return true;
+                    });
+
+                    $itemActions.appendTo($tr);
+                }
+
+                return $tr;
+            },
+
+            expandable: function(data, itemActions, multiRule) {
+                var $expandable = $('<div>').addClass('expandable-listing');
+                var $tbody = $('<tbody>').appendTo($('<table>').appendTo($expandable));
+
+                $(data).each(function() {
+                    var field = this;
+                    var $tr = _medit.multiItem.itemRow(field, itemActions, multiRule, $tbody).appendTo($tbody);
+
+                    cloudStack.evenOdd($tbody, 'tr', {
                         even: function($elem) {
-                          $elem.removeClass('odd');
-                          $elem.addClass('even');
+                            $elem.addClass('even');
                         },
                         odd: function($elem) {
-                          $elem.removeClass('even');
-                          $elem.addClass('odd');
+                            $elem.addClass('odd');
+                        }
+                    });
+                });
+
+                return $expandable.hide();
+            }
+        }
+    };
+
+    $.fn.multiEdit = function(args) {
+        var dataProvider = args.dataProvider;
+        var multipleAdd = args.multipleAdd;
+        var tags = args.tags;
+        var $multi = $('<div>').addClass('multi-edit').appendTo(this);
+        var $multiForm = $('<form>').appendTo($multi);
+        var $inputTable = $('<table>').addClass('multi-edit').appendTo($multiForm);
+        var $dataTable = $('<div>').addClass('data').appendTo($multi);
+        var $addVM;
+        var fields = args.fields;
+        var actions = args.actions;
+        var itemActions = multipleAdd ? args.itemActions : null;
+        var noSelect = args.noSelect;
+        var context = args.context;
+        var ignoreEmptyFields = args.ignoreEmptyFields;
+        var actionPreFilter = args.actionPreFilter;
+        var readOnlyCheck = args.readOnlyCheck;
+        var reorder = args.reorder;
+
+        var $thead = $('<tr>').appendTo(
+            $('<thead>').appendTo($inputTable)
+        );
+        var $inputForm = $('<tr>').appendTo(
+            $('<tbody>').appendTo($inputTable)
+        );
+        var $dataBody = $('<div>').addClass('data-body').appendTo($dataTable);
+
+        // Setup input table headers
+
+        if (reorder) {
+            $('<th>').addClass('reorder').appendTo($thead);
+            $('<td>').addClass('reorder').appendTo($inputForm);
+            $multi.find('.data-body').sortable({
+                handle: '.action.moveDrag',
+
+                update: function(event, ui) {
+                    var $loading = $('<div>').addClass('loading-overlay');
+
+                    $loading.prependTo($multi);
+                    reorder.moveDrag.action({
+                        targetIndex: ui.item.index(),
+                        context: $.extend(true, {}, context, {
+                            // Passes all rules, so that each index can be updated
+                            multiRule: [ui.item.data('json-obj')]
+                        }),
+                        response: {
+                            success: function(args) {
+                                $multi.trigger('refresh');
+                                $loading.remove();
+                            },
+                            error: function(msg) {
+                                $multi.trigger('refresh');
+                                cloudStack.dialog.notice(msg);
+                                $loading.remove();
+                            }
                         }
-                      });
-                    };
-                    var errorArgs = {};
-
-                    $tr.hide();
-                    cloudStack.evenOdd($tbody, 'tr:visible', {
-                      even: function($elem) {
-                        $elem.removeClass('odd');
-                        $elem.addClass('even');
-                      },
-                      odd: function($elem) {
-                        $elem.removeClass('even');
-                        $elem.addClass('odd');
-                      }
                     });
-                    cloudStack.ui.notifications.add(notification,
-                                                    success, successArgs,
-                                                    error, errorArgs);
-                  }
-                },
-                error: function(message) {
-                  if (message) {
-                    cloudStack.dialog.notice({ message: message });
-                  }
                 }
-              }
             });
-          });
-          $itemAction.append($('<span>').addClass('icon'));
-          $itemAction.appendTo($itemActions);
+        }
 
-          return true;
-        });
+        $.each(args.fields, function(fieldName, field) {
+            if (!field) return true;
 
-        $itemActions.appendTo($tr);
-      }
+            var $th = $('<th>').addClass(fieldName).html(_l(field.label.toString()));
+            $th.attr('rel', fieldName);
+            $th.appendTo($thead);
+            var $td = $('<td>').addClass(fieldName);
+            $td.attr('rel', fieldName);
+            $td.appendTo($inputForm);
 
-      return $tr;
-    },
+            if (field.isHidden) {
+                $th.hide();
+                $td.hide();
+            }
 
-    expandable: function(data, itemActions, multiRule) {
-      var $expandable = $('<div>').addClass('expandable-listing');
-      var $tbody = $('<tbody>').appendTo($('<table>').appendTo($expandable));
+            if (field.select) {
+                var $select = $('<select>');
 
-      $(data).each(function() {
-        var field = this;
-        var $tr = _medit.multiItem.itemRow(field, itemActions, multiRule, $tbody).appendTo($tbody);
+                $select.attr({
+                    name: fieldName
+                });
+                $select.appendTo($td);
+                field.select({
+                    context: context,
+                    $select: $select,
+                    $form: $multiForm,
+                    response: {
+                        success: function(args) {
+                            $(args.data).each(function() {
+                                $('<option>').val(this.name).html(_s(this.description))
+                                    .appendTo($select);
+                            });
+                            _medit.refreshItemWidths($multi);
+                        },
 
-        cloudStack.evenOdd($tbody, 'tr', {
-          even: function($elem) {
-            $elem.addClass('even');
-          },
-          odd: function($elem) {
-            $elem.addClass('odd');
-          }
-        });
-      });
-
-      return $expandable.hide();
-    }
-  }
-};
-
-$.fn.multiEdit = function(args) {
-  var dataProvider = args.dataProvider;
-  var multipleAdd = args.multipleAdd;
-  var tags = args.tags;
-  var $multi = $('<div>').addClass('multi-edit').appendTo(this);
-  var $multiForm = $('<form>').appendTo($multi);
-  var $inputTable = $('<table>').addClass('multi-edit').appendTo($multiForm);
-  var $dataTable = $('<div>').addClass('data').appendTo($multi);
-  var $addVM;
-  var fields = args.fields;
-  var actions = args.actions;
-  var itemActions = multipleAdd ? args.itemActions : null;
-  var noSelect = args.noSelect;
-  var context = args.context;
-  var ignoreEmptyFields = args.ignoreEmptyFields;
-  var actionPreFilter = args.actionPreFilter;
-  var readOnlyCheck = args.readOnlyCheck;
-  var reorder = args.reorder;
-
-  var $thead = $('<tr>').appendTo(
-    $('<thead>').appendTo($inputTable)
-  );
-  var $inputForm = $('<tr>').appendTo(
-    $('<tbody>').appendTo($inputTable)
-  );
-  var $dataBody = $('<div>').addClass('data-body').appendTo($dataTable);
-
-  // Setup input table headers
-
-  if (reorder) {
-    $('<th>').addClass('reorder').appendTo($thead);
-    $('<td>').addClass('reorder').appendTo($inputForm);
-    $multi.find('.data-body').sortable({
-      handle: '.action.moveDrag',
-      
-      update: function(event, ui) {
-        var $loading = $('<div>').addClass('loading-overlay');
-
-        $loading.prependTo($multi);
-        reorder.moveDrag.action({
-          targetIndex: ui.item.index(),
-          context: $.extend(true, {}, context, {
-            // Passes all rules, so that each index can be updated
-            multiRule: [ui.item.data('json-obj')]
-          }),
-          response: {
-            success: function(args) {
-              $multi.trigger('refresh');
-              $loading.remove();
-            },
-            error: function(msg) {
-              $multi.trigger('refresh');
-              cloudStack.dialog.notice(msg);
-              $loading.remove();
+                        error: function(args) {}
+                    }
+                });
+            } else if (field.edit && field.edit != 'ignore') {
+                if (field.range) {
+                    var $range = $('<div>').addClass('range').appendTo($td);
+
+                    $(field.range).each(function() { //e.g. field.range = ['privateport', 'privateendport'];
+                        var $input = $('<input>')
+                            .attr({
+                                name: this,
+                                type: 'text'
+                            })
+                        //.addClass(!field.isOptional ? 'required' : null)          //field.range[0] might be required while field.range[1] is optional (e.g. private start port is required while private end port is optional), so "isOptional" property should be on field.range level instead of field level.
+                        //.attr('disabled', field.isDisabled ? 'disabled' : false)  //field.range[0] might be enabled while field.range[1] is disabled  (e.g. private start port is enabled while private end port is disabled),  so "isDisabled" property should be on field.range level instead of field level.
+                        .appendTo(
+                            $('<div>').addClass('range-item').appendTo($range)
+                        );
+
+                        if (field.isDisabled) $input.hide();
+
+                        if (field.defaultValue) {
+                            $input.val(field.defaultValue);
+                            $input.data('multi-default-value', field.defaultValue);
+                        }
+                    });
+                } else {
+                    var $input = $('<input>')
+                        .attr({
+                            name: fieldName,
+                            type: field.isPassword ? 'password' : 'text'
+                        })
+                        .addClass(!field.isOptional ? 'required' : null)
+                        .attr('disabled', field.isDisabled ? 'disabled' : false)
+                        .appendTo($td);
+
+                    if (field.isDisabled) $input.hide();
+                    if (field.defaultValue) {
+                        $input.val(field.defaultValue);
+                        $input.data('multi-default-value', field.defaultValue);
+                    }
+                }
+            } else if (field.custom) {
+                $('<div>').addClass('button add-vm custom-action')
+                    .html(_l(field.custom.buttonLabel))
+                    .click(function() {
+                        if (field.custom.requireValidation && !$multiForm.valid()) return false;
+
+                        var formData = getMultiData($multi);
+
+                        field.custom.action({
+                            formData: formData,
+                            context: context,
+                            data: $td.data('multi-custom-data'),
+                            response: {
+                                success: function(args) {
+                                    $td.data('multi-custom-data', args.data);
+                                }
+                            }
+                        });
+
+                        return false;
+                    }).appendTo($td);
+            } else if (field.addButton) {
+                $addVM = $('<div>').addClass('button add-vm').html(
+                    _l('label.add')
+                ).appendTo($td);
             }
-          }
-        });
-      }
-    });
-  }
-
-  $.each(args.fields, function(fieldName, field) {
-    if (!field) return true;
-
-    var $th = $('<th>').addClass(fieldName).html(_l(field.label.toString()));
-      $th.attr('rel', fieldName);
-      $th.appendTo($thead);
-      var $td = $('<td>').addClass(fieldName);
-      $td.attr('rel', fieldName);
-      $td.appendTo($inputForm);
-
-      if (field.isHidden) {
-        $th.hide();
-        $td.hide();
-      }
-
-      if (field.select) {
-        var $select = $('<select>');
-
-        $select.attr({
-          name: fieldName
-        });
-        $select.appendTo($td);
-        field.select({
-          context: context,
-          $select: $select,
-          $form: $multiForm,
-          response: {
-            success: function(args) {
-              $(args.data).each(function() {
-                $('<option>').val(this.name).html(_s(this.description))
-                  .appendTo($select);
-              });
-              _medit.refreshItemWidths($multi);
-            },
 
-            error: function(args) { }
-          }
+            if (field.desc) $input.attr('title', field.desc);
         });
-      } else if (field.edit && field.edit != 'ignore') {
-        if (field.range) {
-          var $range = $('<div>').addClass('range').appendTo($td);
-
-          $(field.range).each(function() {  //e.g. field.range = ['privateport', 'privateendport'];
-            var $input = $('<input>')
-                  .attr({
-                    name: this,
-                    type: 'text'
-                  })
-                  //.addClass(!field.isOptional ? 'required' : null)          //field.range[0] might be required while field.range[1] is optional (e.g. private start port is required while private end port is optional), so "isOptional" property should be on field.range level instead of field level.
-                  //.attr('disabled', field.isDisabled ? 'disabled' : false)  //field.range[0] might be enabled while field.range[1] is disabled  (e.g. private start port is enabled while private end port is disabled),  so "isDisabled" property should be on field.range level instead of field level.
-                  .appendTo(
-                    $('<div>').addClass('range-item').appendTo($range)
-                  );
-
-            if (field.isDisabled) $input.hide();
-
-            if (field.defaultValue) {
-              $input.val(field.defaultValue);
-              $input.data('multi-default-value', field.defaultValue);
+
+        // Setup header fields
+        var showHeaderFields = args.headerFields ? true : false;
+        var headerForm = showHeaderFields ? cloudStack.dialog.createForm({
+            context: context,
+            noDialog: true,
+            form: {
+                fields: args.headerFields
+            },
+            after: function(args) {
+                // Form fields are handled by main 'add' action
             }
-          });
-        } else {
-          var $input = $('<input>')
-                .attr({
-                  name: fieldName,
-                  type: field.isPassword ? 'password' : 'text'
-                })
-                .addClass(!field.isOptional ? 'required' : null)
-                .attr('disabled', field.isDisabled ? 'disabled' : false)
-                .appendTo($td);
-
-          if (field.isDisabled) $input.hide();
-          if (field.defaultValue) {
-            $input.val(field.defaultValue);
-            $input.data('multi-default-value', field.defaultValue);
-          }
+        }) : null;
+        var $headerFields = $('<div>').addClass('header-fields').hide(); //make headerFields hidden as default
+
+        if (headerForm) {
+            $headerFields.append(headerForm.$formContainer)
+                .prependTo($multi);
         }
-      } else if (field.custom) {
-        $('<div>').addClass('button add-vm custom-action')
-          .html(_l(field.custom.buttonLabel))
-          .click(function() {
-            if (field.custom.requireValidation &&
-                !$multiForm.valid()) return false;
-            
-            var formData = getMultiData($multi);
-            
-            field.custom.action({
-              formData: formData,
-              context: context,
-              data: $td.data('multi-custom-data'),
-              response: {
-                success: function(args) {
-                  $td.data('multi-custom-data', args.data);
-                }
-              }
-            });
 
-            return false;
-          }).appendTo($td);
-      } else if (field.addButton) {
-        $addVM = $('<div>').addClass('button add-vm').html(
-          _l('label.add')
-        ).appendTo($td);
-      }
-
-      if (field.desc) $input.attr('title', field.desc);
-    });
-
-    // Setup header fields
-    var showHeaderFields = args.headerFields ? true : false;
-    var headerForm = showHeaderFields ? cloudStack.dialog.createForm({
-      context: context,
-      noDialog: true,
-      form: {
-        fields: args.headerFields
-      },
-      after: function(args) {
-        // Form fields are handled by main 'add' action
-      }
-    }) : null;
-    var $headerFields = $('<div>').addClass('header-fields').hide(); //make headerFields hidden as default
-		
-    if (headerForm) {
-      $headerFields.append(headerForm.$formContainer)
-        .prependTo($multi);
-    }
-
-    if (args.actions && !args.noHeaderActionsColumn) {
-      $thead.append($('<th></th>').html(_l('label.actions')).addClass('multi-actions'));
-      $inputForm.append($('<td></td>').addClass('multi-actions'));
-    }
-
-    $addVM.bind('click', function() {
-      // Validate form first
-      if (!$multiForm.valid()) {
-        if ($multiForm.find('input.error:visible').size()) {
-          return false;
+        if (args.actions && !args.noHeaderActionsColumn) {
+            $thead.append($('<th></th>').html(_l('label.actions')).addClass('multi-actions'));
+            $inputForm.append($('<td></td>').addClass('multi-actions'));
         }
-      }
 
-      var $dataList;
-      var addItem = function(itemData) {
-        var data = {};
+        $addVM.bind('click', function() {
+            // Validate form first
+            if (!$multiForm.valid()) {
+                if ($multiForm.find('input.error:visible').size()) {
+                    return false;
+                }
+            }
 
-        $.each(getMultiData($multi), function(key, value) {
-          if (value != '') {
-            data[key] = value;
-          }
-        });
+            var $dataList;
+            var addItem = function(itemData) {
+                var data = {};
 
-        // Append custom data
-        var $customFields = $multi.find('tbody td').filter(function() {
-          return $(this).data('multi-custom-data');
-        });
+                $.each(getMultiData($multi), function(key, value) {
+                    if (value != '') {
+                        data[key] = value;
+                    }
+                });
 
-        $customFields.each(function() {
-          var $field = $(this);
-          var fieldID = $field.attr('rel');
-          var fieldData = $field.data('multi-custom-data');
+                // Append custom data
+                var $customFields = $multi.find('tbody td').filter(function() {
+                    return $(this).data('multi-custom-data');
+                });
 
-          data[fieldID] = fieldData;
-        });
+                $customFields.each(function() {
+                    var $field = $(this);
+                    var fieldID = $field.attr('rel');
+                    var fieldData = $field.data('multi-custom-data');
 
-        // Loading appearance
-        var $loading = _medit.loadingItem($multi, _l('label.adding') + '...');
-        $dataBody.prepend($loading);
+                    data[fieldID] = fieldData;
+                });
 
-        // Clear out fields
-        $multi.find('input').each(function() {
-          var $input = $(this);
+                // Loading appearance
+                var $loading = _medit.loadingItem($multi, _l('label.adding') + '...');
+                $dataBody.prepend($loading);
 
-          if ($input.data('multi-default-value')) {
-            $input.val($input.data('multi-default-value'));
-          } else {
-            $input.val('');
-          }
-        });
-        $multi.find('tbody td').each(function() {
-          var $item = $(this);
+                // Clear out fields
+                $multi.find('input').each(function() {
+                    var $input = $(this);
 
-          if ($item.data('multi-custom-data')) {
-            $item.data('multi-custom-data', null);
-          }
-        });
+                    if ($input.data('multi-default-value')) {
+                        $input.val($input.data('multi-default-value'));
+                    } else {
+                        $input.val('');
+                    }
+                });
+                $multi.find('tbody td').each(function() {
+                    var $item = $(this);
 
-        // Apply action
-        args.add.action({
-          context: context,
-          data: data,
-          itemData: itemData,
-          $multi: $multi,
-          response: {
-            success: function(successArgs) {
-              var notification = successArgs ? successArgs.notification : null;
-              if (notification) {
-                $('.notifications').notifications('add', {
-                  section: 'network',
-                  desc: notification.label,
-                  interval: 3000,
-                  _custom: successArgs._custom,
-                  poll: function(pollArgs) {
-                    var complete = pollArgs.complete;
-                    var error = pollArgs.error;
-
-                    notification.poll({
-                      _custom: pollArgs._custom,
-                      complete: function(completeArgs) {
-                        complete(args);
-                        $loading.remove();
-                        getData();
-                      },
+                    if ($item.data('multi-custom-data')) {
+                        $item.data('multi-custom-data', null);
+                    }
+                });
 
-                      error: function(args) {
-                        error(args);
-                        $loading.remove();
+                // Apply action
+                args.add.action({
+                    context: context,
+                    data: data,
+                    itemData: itemData,
+                    $multi: $multi,
+                    response: {
+                        success: function(successArgs) {
+                            var notification = successArgs ? successArgs.notification : null;
+                            if (notification) {
+                                $('.notifications').notifications('add', {
+                                    section: 'network',
+                                    desc: notification.label,
+                                    interval: 3000,
+                                    _custom: successArgs._custom,
+                                    poll: function(pollArgs) {
+                                        var complete = pollArgs.complete;
+                                        var error = pollArgs.error;
+
+                                        notification.poll({
+                                            _custom: pollArgs._custom,
+                                            complete: function(completeArgs) {
+                                                complete(args);
+                                                $loading.remove();
+                                                getData();
+                                            },
+
+                                            error: function(args) {
+                                                error(args);
+                                                $loading.remove();
+
+                                                return cloudStack.dialog.error(args);
+                                            }
+                                        });
+                                    }
+                                });
+                            } else {
+                                $loading.remove();
+                                getData();
+                            }
+                        },
 
-                        return cloudStack.dialog.error(args);
-                      }
-                    });
-                  }
+                        error: cloudStack.dialog.error(function() {
+                            $loading.remove();
+                        })
+                    }
                 });
-              } else {
-                $loading.remove();
-                getData();
-              }
-            },
+            };
+
+            if (args.noSelect) {
+                // Don't append instance data
+                addItem([]);
+
+                return true;
+            }
 
-            error: cloudStack.dialog.error(function() {
-              $loading.remove();
-            })
-          }
+            _medit.vmList($multi,
+                args.listView,
+                args.context,
+                multipleAdd, _l('label.add.vms'),
+                addItem);
+
+            return true;
         });
-      };
-
-      if (args.noSelect) {
-        // Don't append instance data
-        addItem([]);
-
-        return true;
-      }
-
-      _medit.vmList($multi,
-                    args.listView,
-                    args.context,
-                    multipleAdd, _l('label.add.vms'),
-                    addItem);
-
-      return true;
-    });
-
-    var listView = args.listView;
-    var getData = function() {
-      dataProvider({
-        context: context,
-        $multi: $multi,
-        response: {
-          success: function(args) {
-            $multi.find('.data-item').remove();
-            $(args.data).each(function() {
-              var data = this;
-              var itemData = this._itemData;
-
-              _medit.addItem(
-                data,
-                fields,
-                $multi,
-                itemData,
-                actions,
-                {
-                  multipleAdd: multipleAdd,
-                  itemActions: itemActions,
-                  noSelect: noSelect,
-                  context: $.extend(true, {}, context, this._context),
-                  ignoreEmptyFields: ignoreEmptyFields,
-                  preFilter: actionPreFilter,
-                  listView: listView,
-                  tags: tags,
-                  reorder: reorder
+
+        var listView = args.listView;
+        var getData = function() {
+            dataProvider({
+                context: context,
+                $multi: $multi,
+                response: {
+                    success: function(args) {
+                        $multi.find('.data-item').remove();
+                        $(args.data).each(function() {
+                            var data = this;
+                            var itemData = this._itemData;
+
+                            _medit.addItem(
+                                data,
+                                fields,
+                                $multi,
+                                itemData,
+                                actions, {
+                                    multipleAdd: multipleAdd,
+                                    itemActions: itemActions,
+                                    noSelect: noSelect,
+                                    context: $.extend(true, {}, context, this._context),
+                                    ignoreEmptyFields: ignoreEmptyFields,
+                                    preFilter: actionPreFilter,
+                                    listView: listView,
+                                    tags: tags,
+                                    reorder: reorder
+                                }
+                            ).appendTo($dataBody);
+                        });
+
+                        if (readOnlyCheck && !readOnlyCheck(args)) {
+                            $multi.find('th.add-user, td.add-user').detach();
+                            $multiForm.find('tbody').detach();
+                        }
+                        if (args.hideFields) {
+                            $(args.hideFields).each(function() {
+                                $multi.find('th.' + this + ',td.' + this).hide();
+                            });
+                        }
+
+                        _medit.refreshItemWidths($multi);
+                    },
+                    error: cloudStack.dialog.error
                 }
-              ).appendTo($dataBody);
             });
+        };
 
-            if (readOnlyCheck && !readOnlyCheck(args)) {
-                $multi.find('th.add-user, td.add-user').detach();
-                $multiForm.find('tbody').detach();
-            }
-            if (args.hideFields) {
-              $(args.hideFields).each(function() {
-                $multi.find('th.' + this + ',td.' + this).hide();
-              });
-            }
-
-            _medit.refreshItemWidths($multi);
-          },
-          error: cloudStack.dialog.error
+        if (args.hideForm && args.hideForm()) {
+            $multiForm.find('tbody').detach();
         }
-      });
-    };
-
-    if (args.hideForm && args.hideForm()){
-      $multiForm.find('tbody').detach();
-    }
 
-    // Get existing data
-    setTimeout(function() { getData(); });
+        // Get existing data
+        setTimeout(function() {
+            getData();
+        });
 
-    var fullRefreshEvent = fun

<TRUNCATED>