diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py
index 009f1c1..bb5da06 100644
--- a/web/pgadmin/browser/register_browser_preferences.py
+++ b/web/pgadmin/browser/register_browser_preferences.py
@@ -387,3 +387,18 @@ def register_browser_preferences(self):
         category_label=gettext('Keyboard shortcuts'),
         fields=fields
     )
+
+    self.preference.register(
+        'keyboard_shortcuts',
+        'add_grid_row',
+        gettext('Add grid row'),
+        'keyboardshortcut',
+        {
+            'alt': False,
+            'shift': True,
+            'control': True,
+            'key': {'key_code': 65, 'char': 'a'}
+        },
+        category_label=gettext('Keyboard shortcuts'),
+        fields=fields
+    )
diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js
index 9ad59b6..b50d025 100644
--- a/web/pgadmin/browser/static/js/keyboard.js
+++ b/web/pgadmin/browser/static/js/keyboard.js
@@ -41,6 +41,7 @@ _.extend(pgBrowser.keyboardNavigation, {
         'direct_debugging': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'direct_debugging').value),
         'drop_multiple_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'grid_menu_drop_multiple').value),
         'drop_cascade_multiple_objects': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'grid_menu_drop_cascade_multiple').value),
+        'add_grid_row': commonUtils.parseShortcutValue(pgBrowser.get_preference('browser', 'add_grid_row').value),
 
       };
       this.shortcutMethods = {
@@ -61,6 +62,7 @@ _.extend(pgBrowser.keyboardNavigation, {
         'bindDirectDebugging': {'shortcuts': this.keyboardShortcut.direct_debugging}, // Sub menu - Direct Debugging
         'bindDropMultipleObjects': {'shortcuts': this.keyboardShortcut.drop_multiple_objects}, // Grid Menu Drop Multiple
         'bindDropCascadeMultipleObjects': {'shortcuts': this.keyboardShortcut.drop_cascade_multiple_objects}, // Grid Menu Drop Cascade Multiple
+        'bindAddGridRow': {'shortcuts': this.keyboardShortcut.add_grid_row}, // Subnode Grid Add Row
       };
       this.bindShortcuts();
     }
@@ -330,6 +332,12 @@ _.extend(pgBrowser.keyboardNavigation, {
       $('button.delete_multiple_cascade').click();
     }
   },
+  bindAddGridRow: function() {
+    let subNode = $(document.activeElement).closest('.object.subnode');
+    if($(subNode).length) {
+      $(subNode).find('.add').click();
+    }
+  },
   isPropertyPanelVisible: function() {
     let isPanelVisible = false;
     _.each(pgAdmin.Browser.docker.findPanels(), (panel) => {
diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js
index b97fc38..156430d 100644
--- a/web/pgadmin/static/js/backform.pgadmin.js
+++ b/web/pgadmin/static/js/backform.pgadmin.js
@@ -10,8 +10,10 @@
 define([
   'sources/gettext', 'underscore', 'underscore.string', 'jquery',
   'backbone', 'backform', 'backgrid', 'codemirror', 'sources/sqleditor_utils',
+  'sources/keyboard_shortcuts',
   'spectrum', 'pgadmin.backgrid', 'select2', 'bootstrap.toggle',
-], function(gettext, _, S, $, Backbone, Backform, Backgrid, CodeMirror, SqlEditorUtils) {
+], function(gettext, _, S, $, Backbone, Backform, Backgrid, CodeMirror,
+  SqlEditorUtils, keyboardShortcuts) {
 
   var pgAdmin = (window.pgAdmin = window.pgAdmin || {}),
     pgBrowser = pgAdmin.Browser;
@@ -1269,6 +1271,13 @@ define([
 
       var $dialog = gridBody.append(subNodeGrid);
 
+      let preferences = pgBrowser.get_preferences_for_module('browser');
+      let addBtn = $dialog.find('.add');
+      // Add title to the buttons
+      $(addBtn)
+        .attr('title',
+          keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
+
       // Add button callback
       if (!(data.disabled || data.canAdd == false)) {
         $dialog.find('button.add').first().on('click',(e) => {
@@ -1554,6 +1563,14 @@ define([
 
       var $dialog = gridBody.append(subNodeGrid);
 
+      let preferences = pgBrowser.get_preferences_for_module('browser');
+      let addBtn = $dialog.find('.add');
+      // Add title to the buttons
+      $(addBtn)
+        .attr('title',
+          keyboardShortcuts.shortcut_title(gettext('Add new row'),preferences.add_grid_row));
+
+
       // Add button callback
       $dialog.find('button.add').on('click',(e) => {
         e.preventDefault();
diff --git a/web/pgadmin/static/js/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid.pgadmin.js
index c804609..86cc35c 100644
--- a/web/pgadmin/static/js/backgrid.pgadmin.js
+++ b/web/pgadmin/static/js/backgrid.pgadmin.js
@@ -9,15 +9,18 @@
 
 define([
   'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify',
-  'moment', 'bignumber', 'bootstrap.datetimepicker', 'backgrid.filter',
-  'bootstrap.toggle',
+  'moment', 'bignumber', 'sources/utils', 'sources/keyboard_shortcuts',
+  'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle',
 ], function(
-  gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber
+  gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber,
+  commonUtils, keyboardShortcuts
 ) {
   /*
    * Add mechanism in backgrid to render different types of cells in
    * same column;
    */
+  let pgAdmin = (window.pgAdmin = window.pgAdmin || {}),
+    pgBrowser = pgAdmin.Browser;
 
   // Add new property cellFunction in Backgrid.Column.
   _.extend(Backgrid.Column.prototype.defaults, {
@@ -37,6 +40,18 @@ define([
     },
   });
 
+  // bind shortcut in cell edit mode
+  _.extend(Backgrid.InputCellEditor.prototype.events, {
+    'keydown': function(e) {
+      let preferences = pgBrowser.get_preferences_for_module('browser');
+      if(keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,e)) {
+        pgBrowser.keyboardNavigation.bindAddGridRow();
+      } else {
+        Backgrid.InputCellEditor.prototype.saveOrCancel.apply(this, arguments);
+      }
+    },
+  });
+
   /* Overriding backgrid sort method.
    * As we are getting numeric, integer values as string
    * from server side, but on client side javascript truncates
@@ -189,7 +204,7 @@ define([
 
   var ObjectCellEditor = Backgrid.Extension.ObjectCellEditor = Backgrid.CellEditor.extend({
     modalTemplate: _.template([
-      '<div class="subnode-dialog" tabindex="1">',
+      '<div class="subnode-dialog" tabindex="0">',
       '    <div class="subnode-body"></div>',
       '</div>',
     ].join('\n')),
@@ -235,6 +250,18 @@ define([
         tabPanelClassName: function() {
           return 'sub-node-form col-sm-12';
         },
+        events: {
+          'keydown': function (event) {
+            let preferences = pgBrowser.get_preferences_for_module('browser');
+            if(keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,event)) {
+              pgBrowser.keyboardNavigation.bindAddGridRow();
+            } else if(keyboardShortcuts.validateShortcutKeys(preferences.save_grid_row,event)) {
+              pgBrowser.keyboardNavigation.bindSaveGridRow();
+            } else if(keyboardShortcuts.validateShortcutKeys(preferences.refresh_grid,event)) {
+              pgBrowser.keyboardNavigation.bindRefreshGrid();
+            }
+          },
+        },
       });
 
       this.objectView.render();
@@ -315,12 +342,18 @@ define([
 
       editorOptions['el'] = $(this.el);
       editorOptions['columns_length'] = this.column.collection.length;
-      editorOptions['el'].attr('tabindex', 1);
+      editorOptions['el'].attr('tabindex', 0);
 
       this.listenTo(this.model, 'backgrid:edit', function(model, column, cell, editor) {
         if (column.get('name') == this.column.get('name'))
           editor.extendWithOptions(editorOptions);
       });
+      // Listen for Tab key, open subnode dialog on space key
+      this.$el.on('keydown', function(e) {
+        if (e.keyCode == 32) {
+          $(this).click();
+        }
+      });
     },
     enterEditMode: function() {
       // Notify that we are about to enter in edit mode for current cell.
@@ -342,6 +375,10 @@ define([
           this.$el.html(
             '<i class=\'fa fa-pencil-square subnode-edit-in-process\' title=\'' + _('Edit row') + '\'></i>'
           );
+          let body = $(this.$el).parents()[1],
+            container = $(body).find('.tab-content:first > .tab-pane.active:first');
+          commonUtils.findAndSetFocus(container);
+          pgBrowser.keyboardNavigation.getDialogTabNavigator($(body).find('.subnode-dialog'));
           this.model.trigger(
             'pg-sub-node:opened', this.model, this
           );
@@ -362,14 +399,16 @@ define([
       return this;
     },
     exitEditMode: function() {
-      var index = $(this.currentEditor.objectView.el)
-        .find('.nav-tabs > .active > a[data-toggle="tab"]').first()
-        .data('tabIndex');
-      Backgrid.Cell.prototype.exitEditMode.apply(this, arguments);
-      this.model.trigger(
-        'pg-sub-node:closed', this, index
-      );
-      this.grabFocus = true;
+      if(!_.isUndefined(this.currentEditor) || !_.isEmpty(this.currentEditor)) {
+        var index = $(this.currentEditor.objectView.el)
+          .find('.nav-tabs > .active > a[data-toggle="tab"]').first()
+          .data('tabIndex');
+        Backgrid.Cell.prototype.exitEditMode.apply(this, arguments);
+        this.model.trigger(
+          'pg-sub-node:closed', this, index
+        );
+        this.grabFocus = true;
+      }
     },
     events: {
       'click': function(e) {
@@ -382,6 +421,17 @@ define([
         }
         e.preventDefault();
       },
+      'keydown': function(e) {
+        var model = this.model;
+        var column = this.column;
+        var command = new Backgrid.Command(e);
+
+        if (command.moveLeft()) {
+          setTimeout(function() {
+            model.trigger('backgrid:edited', model, column, command);
+          }, 20);
+        }
+      },
     },
   });
 
@@ -413,7 +463,16 @@ define([
           delete_title,
           delete_msg,
           function() {
+            let tbody = that.el.closest('tbody');
             that.model.collection.remove(that.model);
+            let row = $(tbody).find('tr');
+            if(row.length > 0) {
+              // set focus to first tr
+              row.first().children()[0].focus();
+            } else {
+              // set focus to add button
+              $(tbody).closest('.subnode').find('.add').focus();
+            }
           },
           function() {
             return true;
@@ -427,12 +486,54 @@ define([
         );
       }
     },
+    exitEditMode: function() {
+      this.$el.removeClass('editor');
+    },
     initialize: function() {
       Backgrid.Cell.prototype.initialize.apply(this, arguments);
     },
     render: function() {
+      var self = this;
       this.$el.empty();
+      $(this.$el).attr('tabindex', 0);
       this.$el.html('<i class=\'fa fa-trash\' title=\'' + _('Delete row') + '\'></i>');
+      // Listen for Tab/Shift-Tab key
+      this.$el.on('keydown', function(e) {
+        // with keyboard navigation on space key, mark row for deletion
+        if (e.keyCode == 32) {
+          self.$el.click();
+        }
+        var gotoCell;
+        if (e.keyCode == 9 || e.keyCode == 16) {
+          // go to Next Cell & if Shift is also pressed go to Previous Cell
+          gotoCell = e.shiftKey ? self.$el.prev() : self.$el.next();
+        }
+
+        if (gotoCell) {
+          let command = new Backgrid.Command({
+            key: 'Tab',
+            keyCode: 9,
+            which: 9,
+            shiftKey: e.shiftKey,
+          });
+          setTimeout(function() {
+            // When we have Editable Cell
+            if (gotoCell.hasClass('editable')) {
+              e.preventDefault();
+              e.stopPropagation();
+              self.model.trigger('backgrid:edited', self.model,
+                self.column, command);
+            }
+            else {
+              // When we have Non-Editable Cell
+              self.model.trigger('backgrid:edited', self.model,
+                self.column, command);
+            }
+          }, 20);
+        }
+      });
+
+
       this.delegateEvents();
       return this;
     },
@@ -488,6 +589,7 @@ define([
       'change input': 'onChange',
       'keyup': 'toggleSwitch',
       'blur input': 'exitEditMode',
+      'keydown': 'onKeyDown',
     },
 
     toggleSwitch: function(e) {
@@ -497,6 +599,13 @@ define([
       }
     },
 
+    onKeyDown: function(e) {
+      let preferences = pgBrowser.get_preferences_for_module('browser');
+      if(keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,e)) {
+        pgBrowser.keyboardNavigation.bindAddGridRow();
+      }
+    },
+
     onChange: function() {
       var model = this.model,
         column = this.column,
@@ -553,7 +662,11 @@ define([
           });
           setTimeout(function() {
             // When we have Editable Cell
-            if (gotoCell.hasClass('editable')) {
+            if (gotoCell.hasClass('editable') && gotoCell.hasClass('edit-cell')) {
+              e.preventDefault();
+              e.stopPropagation();
+              gotoCell.trigger('focus');
+            } else if (gotoCell.hasClass('editable')) {
               e.preventDefault();
               e.stopPropagation();
               self.model.trigger('backgrid:edited', self.model,
@@ -608,8 +721,7 @@ define([
     },
 
     saveOrCancel: function (e) {
-      var model = this.model;
-      var column = this.column;
+      var self = this;
 
       var command = new Backgrid.Command(e);
       var blurred = e.type === 'blur';
@@ -617,10 +729,32 @@ define([
       if (command.moveUp() || command.moveDown() || command.moveLeft() || command.moveRight() ||
           command.save() || blurred) {
 
-        this.exitEditMode();
-        e.preventDefault();
-        e.stopPropagation();
-        model.trigger('backgrid:edited', model, column, command);
+        let gotoCell;
+        // go to Next Cell & if Shift is also pressed go to Previous Cell
+        gotoCell = e.shiftKey ? self.$el.prev() : self.$el.next();
+
+        if (gotoCell) {
+          let command = new Backgrid.Command({
+            key: 'Tab',
+            keyCode: 9,
+            which: 9,
+            shiftKey: e.shiftKey,
+          });
+          setTimeout(function() {
+            // When we have Editable Cell
+            if (gotoCell.hasClass('editable')) {
+              e.preventDefault();
+              e.stopPropagation();
+              self.model.trigger('backgrid:edited', self.model,
+                self.column, command);
+            }
+            else {
+              // When we have Non-Editable Cell
+              self.model.trigger('backgrid:edited', self.model,
+                self.column, command);
+            }
+          }, 20);
+        }
       }
     },
     events: {
diff --git a/web/pgadmin/static/js/dialog_tab_navigator.js b/web/pgadmin/static/js/dialog_tab_navigator.js
index 4472172..37bff6b 100644
--- a/web/pgadmin/static/js/dialog_tab_navigator.js
+++ b/web/pgadmin/static/js/dialog_tab_navigator.js
@@ -46,13 +46,13 @@ class dialogTabNavigator {
 
     if(childTabData) {
       var res = this.navigate(shortcut, childTabData.childTab,
-        childTabData.childTabPane);
+        childTabData.childTabPane, event);
 
       if (!res) {
-        this.navigate(shortcut, this.tabs, currentTabPane);
+        this.navigate(shortcut, this.tabs, currentTabPane, event);
       }
     } else {
-      this.navigate(shortcut, this.tabs, currentTabPane);
+      this.navigate(shortcut, this.tabs, currentTabPane, event);
     }
   }
 
@@ -73,16 +73,16 @@ class dialogTabNavigator {
     return null;
   }
 
-  navigate(shortcut, tabs, tab_pane) {
+  navigate(shortcut, tabs, tab_pane, event) {
     if(shortcut == this.dialogTabBackward) {
-      return this.navigateBackward(tabs, tab_pane);
+      return this.navigateBackward(tabs, tab_pane, event);
     }else if (shortcut == this.dialogTabForward) {
-      return this.navigateForward(tabs, tab_pane);
+      return this.navigateForward(tabs, tab_pane, event);
     }
     return false;
   }
 
-  navigateBackward(tabs, tab_pane) {
+  navigateBackward(tabs, tab_pane, event) {
     var self = this,
       nextTabPane,
       innerTabContainer,
@@ -105,6 +105,7 @@ class dialogTabNavigator {
         self.tabSwitching = false;
       }, 200);
 
+      event.stopPropagation();
       return true;
     }
 
@@ -112,7 +113,7 @@ class dialogTabNavigator {
     return false;
   }
 
-  navigateForward(tabs, tab_pane) {
+  navigateForward(tabs, tab_pane, event) {
     var self = this,
       nextTabPane,
       innerTabContainer,
@@ -135,6 +136,8 @@ class dialogTabNavigator {
         self.tabSwitching = false;
       }, 200);
 
+      event.stopPropagation();
+
       return true;
     }
     this.tabSwitching = false;
diff --git a/web/pgadmin/static/scss/_backgrid.overrides.scss b/web/pgadmin/static/scss/_backgrid.overrides.scss
index b0b7475..41266eb 100644
--- a/web/pgadmin/static/scss/_backgrid.overrides.scss
+++ b/web/pgadmin/static/scss/_backgrid.overrides.scss
@@ -288,6 +288,10 @@ table.backgrid {
     background-color: $color-bg-theme !important;
   }
 
+  & td.edit-cell.editor:focus {
+    outline: $input-focus-border-color auto 5px !important;
+  }
+
   tr.editor-row  {
     background-color: $color-gray-light !important;
     & > td {
diff --git a/web/pgadmin/static/scss/_pgadmin.style.scss b/web/pgadmin/static/scss/_pgadmin.style.scss
index f5a8877..8f1e248 100644
--- a/web/pgadmin/static/scss/_pgadmin.style.scss
+++ b/web/pgadmin/static/scss/_pgadmin.style.scss
@@ -729,10 +729,17 @@ table tr th {
     padding: 0;
   }
   & button:focus {
-    outline: none;
+    outline: $input-focus-border-color auto 5px !important;
   }
 }
 
+table tr td {
+  td.edit-cell:focus,
+  td.delete-cell:focus,
+  td.string-cell:focus {
+    outline: $input-focus-border-color auto 5px !important;
+  }
+}
 
 .privilege_label{
   font-size: 10px!important;
diff --git a/web/pgadmin/static/vendor/backgrid/backgrid.js b/web/pgadmin/static/vendor/backgrid/backgrid.js
index 963ddca..1b3173b 100644
--- a/web/pgadmin/static/vendor/backgrid/backgrid.js
+++ b/web/pgadmin/static/vendor/backgrid/backgrid.js
@@ -8,32 +8,35 @@
 //////////////////////////////////////////////////////////////
 
 /*!
-  backgrid
-  http://github.com/wyuenho/backgrid
+  backgrid 0.3.8
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2014 Jimmy Yuen Ho Wong and contributors <wyuenho@gmail.com>
+  Copyright (c) 2017 Cloudflare, Inc. and contributors <jwong@cloudflare.com>
   Licensed under the MIT license.
 */
 
-(function (factory) {
+(function (root, factory) {
 
-  // CommonJS
-  if (typeof exports == "object") {
-    module.exports = factory(module.exports,
-                             require("underscore"),
-                             require("backbone"));
-  }
-  // Browser
-  else factory(this, this._, this.Backbone);
-}(function (root, _, Backbone) {
+  if (typeof define === "function" && define.amd) {
+    // AMD (+ global for extensions)
+    define(["underscore", "backbone"], function (_, Backbone) {
+      return (root.Backgrid = factory(_, Backbone));
+    });
+  } else if (typeof exports === "object") {
+    // CommonJS
+    module.exports = factory(require("underscore"), require("backbone"));
+  } else {
+    // Browser
+    root.Backgrid = factory(root._, root.Backbone);
+  }}(this, function (_, Backbone) {
 
   "use strict";
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -72,7 +75,7 @@ function lpad(str, length, padstr) {
 
 var $ = Backbone.$;
 
-var Backgrid = root.Backgrid = {
+var Backgrid = {
 
   Extension: {},
 
@@ -180,9 +183,9 @@ _.extend(Command.prototype, {
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -285,7 +288,7 @@ _.extend(NumberFormatter.prototype, {
   fromRaw: function (number, model) {
     if (_.isNull(number) || _.isUndefined(number)) return '';
 
-    number = number.toFixed(~~this.decimals);
+    number = parseFloat(number).toFixed(~~this.decimals);
 
     var parts = number.split('.');
     var integerPart = parts[0];
@@ -625,9 +628,9 @@ _.extend(SelectFormatter.prototype, {
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -825,7 +828,8 @@ var Cell = Backgrid.Cell = Backbone.View.extend({
 
   /** @property */
   events: {
-    "click": "enterEditMode"
+    "click": "enterEditMode",
+    "focus": "onFocus"
   },
 
   /**
@@ -873,9 +877,16 @@ var Cell = Backgrid.Cell = Backbone.View.extend({
                     }
                   });
 
-    if (Backgrid.callByNeed(column.editable(), column, model)) $el.addClass("editable");
-    if (Backgrid.callByNeed(column.sortable(), column, model)) $el.addClass("sortable");
-    if (Backgrid.callByNeed(column.renderable(), column, model)) $el.addClass("renderable");
+    this.updateStateClassesMaybe();
+  },
+
+  updateStateClassesMaybe: function () {
+    var model = this.model;
+    var column = this.column;
+    var $el = this.$el;
+    $el.toggleClass("editable", Backgrid.callByNeed(column.editable(), column, model));
+    $el.toggleClass("sortable", Backgrid.callByNeed(column.sortable(), column, model));
+    $el.toggleClass("renderable", Backgrid.callByNeed(column.renderable(), column, model));
   },
 
   /**
@@ -883,9 +894,18 @@ var Cell = Backgrid.Cell = Backbone.View.extend({
      model's raw value for this cell's column.
   */
   render: function () {
-    this.$el.empty();
+    var $el = this.$el;
+    $el.empty();
     var model = this.model;
-    this.$el.text(this.formatter.fromRaw(model.get(this.column.get("name")), model));
+    var columnName = this.column.get("name");
+    $el.text(this.formatter.fromRaw(model.get(columnName), model));
+    $el.addClass(columnName);
+    if(this.$el.hasClass('string-cell')) {
+      if(Backgrid.callByNeed(this.column.editable(), this.column, this.model)) {
+        $el.attr('tabindex', 0);
+      }
+    }
+    this.updateStateClassesMaybe();
     this.delegateEvents();
     return this;
   },
@@ -935,6 +955,12 @@ var Cell = Backgrid.Cell = Backbone.View.extend({
     }
   },
 
+  onFocus: function (e) {
+    if(e.keyCode == 9 && $(this).hasClass('string-cell') && $(this).hasClass('editable')) {
+      $(this).click();
+    }
+  },
+
   /**
      Put an `error` CSS class on the table cell.
   */
@@ -1408,7 +1434,15 @@ var SelectCellEditor = Backgrid.SelectCellEditor = CellEditor.extend({
   },
 
   /** @property {function(Object, ?Object=): string} template */
-  template: _.template('<option value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- text %></option>', null, {variable: null}),
+  template: _.template(
+    '<option value="<%- value %>" <%= selected ? \'selected="selected"\' : "" %>><%- text %></option>',
+    null,
+    {
+        variable    : null,
+        evaluate    : /<%([\s\S]+?)%>/g,
+        interpolate : /<%=([\s\S]+?)%>/g,
+        escape      : /<%-([\s\S]+?)%>/g
+    }),
 
   setOptionValues: function (optionValues) {
     this.optionValues = optionValues;
@@ -1651,9 +1685,9 @@ var SelectCell = Backgrid.SelectCell = Cell.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -1706,19 +1740,20 @@ var Column = Backgrid.Column = Backbone.Model.extend({
      this column is sortable. If the value is a string, a method will the same
      name will be looked up from the column instance to determine whether the
      column should be sortable. The method's signature must be `function
-     (Backgrid.Column, Backbone.Model): boolean`.
+     (Backbone.Model): boolean`. The function's context is the column instance.
 
      @cfg {boolean|string|function(): boolean} [defaults.editable=true] Whether
      this column is editable. If the value is a string, a method will the same
      name will be looked up from the column instance to determine whether the
      column should be editable. The method's signature must be `function
-     (Backgrid.Column, Backbone.Model): boolean`.
+     (Backbone.Model): boolean`. The function's context is the column instance.
 
      @cfg {boolean|string|function(): boolean} [defaults.renderable=true]
      Whether this column is renderable. If the value is a string, a method will
      the same name will be looked up from the column instance to determine
      whether the column should be renderable. The method's signature must be
-     `function (Backrid.Column, Backbone.Model): boolean`.
+     `function (Backbone.Model): boolean`. The function's context is the column
+     instance.
 
      @cfg {Backgrid.CellFormatter | Object | string} [defaults.formatter] The
      formatter to use to convert between raw model values and user input.
@@ -1824,24 +1859,33 @@ var Column = Backgrid.Column = Backbone.Model.extend({
   }
 
   /**
+     If you cannot always determine whether a column should be sortable before
+     the grid get initialized, you can override this method.
+
      @member Backgrid.Column
      @protected
      @method sortable
-     @return {function(Backgrid.Column, Backbone.Model): boolean | boolean}
+     @return {function(Backbone.Model): boolean | boolean}
   */
 
   /**
+     If you cannot always determine whether a column should be editable before
+     the grid get initialized, you can override this method.
+
      @member Backgrid.Column
      @protected
      @method editable
-     @return {function(Backgrid.Column, Backbone.Model): boolean | boolean}
+     @return {function(Backbone.Model): boolean | boolean}
   */
 
   /**
+     If you cannot always determine whether a column should be renderable before
+     the grid get initialized, you can override this method.
+
      @member Backgrid.Column
      @protected
      @method renderable
-     @return {function(Backgrid.Column, Backbone.Model): boolean | boolean}
+     @return {function(Backbone.Model): boolean | boolean}
   */
 });
 
@@ -1871,9 +1915,9 @@ var Columns = Backgrid.Columns = Backbone.Collection.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -2020,7 +2064,9 @@ var EmptyRow = Backgrid.EmptyRow = Backbone.View.extend({
 
     var td = document.createElement("td");
     td.setAttribute("colspan", this.columns.length);
-    td.appendChild(document.createTextNode(_.result(this, "emptyText")));
+    var span = document.createElement("span");
+    span.innerHTML = _.result(this, "emptyText");
+    td.appendChild(span);
 
     this.el.className = "empty";
     this.el.appendChild(td);
@@ -2031,9 +2077,9 @@ var EmptyRow = Backgrid.EmptyRow = Backbone.View.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -2052,7 +2098,7 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({
 
   /** @property */
   events: {
-    "click a": "onClick"
+    "click button": "onClick"
   },
 
   /**
@@ -2087,12 +2133,12 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({
     if (Backgrid.callByNeed(column.sortable(), column, collection)) $el.addClass("sortable");
     if (Backgrid.callByNeed(column.renderable(), column, collection)) $el.addClass("renderable");
 
-    this.listenTo(collection.fullCollection || collection, "sort", this.removeCellDirection);
+    this.listenTo(collection.fullCollection || collection, "backgrid:sorted", this.removeCellDirection);
   },
 
   /**
-     Event handler for the collection's `sort` event. Removes all the CSS
-     direction classes.
+     Event handler for the collection's `backgrid:sorted` event. Removes
+     all the CSS direction classes.
    */
   removeCellDirection: function () {
     this.$el.removeClass("ascending").removeClass("descending");
@@ -2151,7 +2197,7 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({
     var sortable = Backgrid.callByNeed(column.sortable(), column, this.collection);
     var label;
     if(sortable){
-      label = $("<a>").text(column.get("label")).append("<b class='sort-caret'></b>");
+      label = $("<button>").text(column.get("label")).append("<span class='sort-caret' aria-hidden='true'></span>");
     } else {
       label = document.createTextNode(column.get("label"));
     }
@@ -2173,8 +2219,6 @@ var HeaderCell = Backgrid.HeaderCell = Backbone.View.extend({
  */
 var HeaderRow = Backgrid.HeaderRow = Backgrid.Row.extend({
 
-  requiredOptions: ["columns", "collection"],
-
   /**
      Initializer.
 
@@ -2259,9 +2303,9 @@ var Header = Backgrid.Header = Backbone.View.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -2298,7 +2342,7 @@ var Body = Backgrid.Body = Backbone.View.extend({
       this.columns = new Columns(this.columns);
     }
 
-    this.row = options.row || Row;
+    this.row = options.row || this.row || Row;
     this.rows = this.collection.map(function (model) {
       var row = new this.row({
         columns: this.columns,
@@ -2318,14 +2362,19 @@ var Body = Backgrid.Body = Backbone.View.extend({
     this.listenTo(collection, "reset", this.refresh);
     this.listenTo(collection, "backgrid:sort", this.sort);
     this.listenTo(collection, "backgrid:edited", this.moveToNextCell);
+
+    this.listenTo(this.columns, "add remove", this.updateEmptyRow);
   },
 
   _unshiftEmptyRowMayBe: function () {
     if (this.rows.length === 0 && this.emptyText != null) {
-      this.rows.unshift(new EmptyRow({
+      this.emptyRow = new EmptyRow({
         emptyText: this.emptyText,
         columns: this.columns
-      }));
+      });
+
+      this.rows.unshift(this.emptyRow);
+      return true
     }
   },
 
@@ -2413,7 +2462,9 @@ var Body = Backgrid.Body = Backbone.View.extend({
     // removeRow() is called directly
     if (!options) {
       this.collection.remove(model, (options = collection));
-      this._unshiftEmptyRowMayBe();
+      if (this._unshiftEmptyRowMayBe()) {
+        this.render();
+      }
       return;
     }
 
@@ -2422,12 +2473,25 @@ var Body = Backgrid.Body = Backbone.View.extend({
     }
 
     this.rows.splice(options.index, 1);
-    this._unshiftEmptyRowMayBe();
+    if (this._unshiftEmptyRowMayBe()) {
+      this.render();
+    }
 
     return this;
   },
 
   /**
+     Rerender the EmptyRow which empties the DOM element, creates the td with the
+     updated colspan, and appends it back into the DOM
+  */
+
+  updateEmptyRow: function () {
+    if (this.emptyRow != null) {
+      this.emptyRow.render();
+    }
+  },
+
+  /**
      Reinitialize all the rows inside the body and re-render them. Triggers a
      Backbone `backgrid:refresh` event from the collection along with the body
      instance as its sole parameter when done.
@@ -2503,7 +2567,7 @@ var Body = Backgrid.Body = Backbone.View.extend({
      Triggers a Backbone `backgrid:sorted` event from the collection when done
      with the column, direction and a reference to the collection.
 
-     @param {Backgrid.Column} column
+     @param {Backgrid.Column|string} column
      @param {null|"ascending"|"descending"} direction
 
      See [Backbone.Collection#comparator](http://backbonejs.org/#Collection-comparator)
@@ -2545,19 +2609,20 @@ var Body = Backgrid.Body = Backbone.View.extend({
         }
         collection.fullCollection.sort();
         collection.trigger("backgrid:sorted", column, direction, collection);
+        column.set("direction", direction);
       }
       else collection.fetch({reset: true, success: function () {
         collection.trigger("backgrid:sorted", column, direction, collection);
+        column.set("direction", direction);
       }});
     }
     else {
       collection.comparator = comparator;
       collection.sort();
       collection.trigger("backgrid:sorted", column, direction, collection);
+      column.set("direction", direction);
     }
 
-    column.set("direction", direction);
-
     return this;
   },
 
@@ -2596,6 +2661,9 @@ var Body = Backgrid.Body = Backbone.View.extend({
     var j = this.columns.indexOf(column);
     var cell, renderable, editable, m, n;
 
+    // return if model being edited in a different grid
+    if (j === -1) return this;
+
     this.rows[i].cells[j].exitEditMode();
 
     if (command.moveUp() || command.moveDown() || command.moveLeft() ||
@@ -2625,7 +2693,11 @@ var Body = Backgrid.Body = Backbone.View.extend({
           cell = this.rows[m].cells[n];
           renderable = Backgrid.callByNeed(cell.column.renderable(), cell.column, cell.model);
           editable = Backgrid.callByNeed(cell.column.editable(), cell.column, model);
-          if (renderable && editable) {
+          if(cell && cell.$el.hasClass('edit-cell') &&
+            !cell.$el.hasClass('privileges') || cell.$el.hasClass('delete-cell')) {
+            model.trigger("backgrid:next", m, n, false);
+            break;
+          } else if (renderable && editable) {
             cell.enterEditMode();
             model.trigger("backgrid:next", m, n, false);
             break;
@@ -2644,9 +2716,9 @@ var Body = Backgrid.Body = Backbone.View.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -2684,9 +2756,9 @@ var Footer = Backgrid.Footer = Backbone.View.extend({
 
 /*
   backgrid
-  http://github.com/wyuenho/backgrid
+  http://github.com/cloudflare/backgrid
 
-  Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
+  Copyright (c) 2013-present Cloudflare, Inc. and contributors
   Licensed under the MIT license.
 */
 
@@ -2760,6 +2832,7 @@ var Grid = Backgrid.Grid = Backbone.View.extend({
      @param {Object} options
      @param {Backbone.Collection.<Backgrid.Columns>|Array.<Backgrid.Column>|Array.<Object>} options.columns Column metadata.
      @param {Backbone.Collection} options.collection The collection of tabular model data to display.
+     @param {string} [options.caption=string] An optional caption to be added to the table.
      @param {Backgrid.Header} [options.header=Backgrid.Header] An optional Header class to override the default.
      @param {Backgrid.Body} [options.body=Backgrid.Body] An optional Body class to override the default.
      @param {Backgrid.Row} [options.row=Backgrid.Row] An optional Row class to override the default.
@@ -2769,10 +2842,12 @@ var Grid = Backgrid.Grid = Backbone.View.extend({
     // Convert the list of column objects here first so the subviews don't have
     // to.
     if (!(options.columns instanceof Backbone.Collection)) {
-      options.columns = new Columns(options.columns);
+      options.columns = new Columns(options.columns || this.columns);
     }
     this.columns = options.columns;
 
+    this.caption = options.caption;
+
     var filteredOptions = _.omit(options, ["el", "id", "attributes",
                                            "className", "tagName", "events"]);
 
@@ -2851,13 +2926,17 @@ var Grid = Backgrid.Grid = Backbone.View.extend({
   },
 
   /**
-     Renders the grid's header, then footer, then finally the body. Triggers a
+     Renders the grid's caption, then header, then footer, then finally the body. Triggers a
      Backbone `backgrid:rendered` event along with a reference to the grid when
      the it has successfully been rendered.
    */
   render: function () {
     this.$el.empty();
 
+    if (this.caption) {
+      this.$el.append($("<caption>").text(this.caption));
+    }
+
     if (this.header) {
       this.$el.append(this.header.render().$el);
     }
@@ -2888,5 +2967,5 @@ var Grid = Backgrid.Grid = Backbone.View.extend({
   }
 
 });
-return Backgrid;
+  return Backgrid;
 }));
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index 8f43b2a..5f2e48c 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -170,7 +170,8 @@ var webpackShimConfig = {
     'backbone': path.join(__dirname, './node_modules/backbone/backbone'),
     'backbone.undo': path.join(__dirname, './node_modules/backbone-undo/Backbone.Undo'),
     'backform': path.join(__dirname, './pgadmin/static/vendor/backform/backform'),
-    'backgrid': path.join(__dirname, './node_modules/backgrid/lib/backgrid'),
+    // 'backgrid': path.join(__dirname, './node_modules/backgrid/lib/backgrid'),
+    'backgrid': path.join(__dirname, './pgadmin/static/vendor/backgrid/backgrid'),
     'bootstrap.datetimepicker': path.join(__dirname, './node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min'),
     'bootstrap.toggle': path.join(__dirname, './node_modules/bootstrap4-toggle/js/bootstrap4-toggle'),
     'select2': path.join(__dirname, './node_modules/select2/dist/js/select2.full'),
