You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/07/31 19:24:54 UTC

incubator-ignite git commit: IGNITE-843 Added support for moving focus by key enter key. Fixed several places with enter/esc/focus.

Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-843 fea607cd1 -> 824b7d74d


IGNITE-843 Added support for moving focus by key enter key. Fixed several places with enter/esc/focus.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/824b7d74
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/824b7d74
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/824b7d74

Branch: refs/heads/ignite-843
Commit: 824b7d74db3b632799df8742ce2e31d29ef5806d
Parents: fea607c
Author: AKuznetsov <ak...@gridgain.com>
Authored: Sat Aug 1 00:24:47 2015 +0700
Committer: AKuznetsov <ak...@gridgain.com>
Committed: Sat Aug 1 00:24:47 2015 +0700

----------------------------------------------------------------------
 .../main/js/controllers/caches-controller.js    |  4 +-
 .../src/main/js/controllers/common-module.js    | 47 ++++++++++-----
 .../main/js/controllers/models/metadata.json    |  4 ++
 .../src/main/js/views/includes/controls.jade    | 63 ++++++++++++--------
 .../src/main/js/views/login.jade                | 13 ++--
 5 files changed, 83 insertions(+), 48 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/824b7d74/modules/control-center-web/src/main/js/controllers/caches-controller.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/caches-controller.js b/modules/control-center-web/src/main/js/controllers/caches-controller.js
index c103650..4f1e342 100644
--- a/modules/control-center-web/src/main/js/controllers/caches-controller.js
+++ b/modules/control-center-web/src/main/js/controllers/caches-controller.js
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-controlCenterModule.controller('cachesController', ['$scope', '$http', '$common', '$confirm', '$copy', '$table', function ($scope, $http, $common, $confirm, $copy, $table) {
+controlCenterModule.controller('cachesController', ['$scope', '$http', '$common', '$focus', '$confirm', '$copy', '$table', function ($scope, $http, $common, $focus, $confirm, $copy, $table) {
         $scope.joinTip = $common.joinTip;
         $scope.getModel = $common.getModel;
         $scope.javaBuildInTypes = $common.javaBuildInTypes;
@@ -348,4 +348,4 @@ controlCenterModule.controller('cachesController', ['$scope', '$http', '$common'
             );
         };
     }]
-);
\ No newline at end of file
+);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/824b7d74/modules/control-center-web/src/main/js/controllers/common-module.js
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/common-module.js b/modules/control-center-web/src/main/js/controllers/common-module.js
index 7803b85..bc4005a 100644
--- a/modules/control-center-web/src/main/js/controllers/common-module.js
+++ b/modules/control-center-web/src/main/js/controllers/common-module.js
@@ -377,12 +377,14 @@ controlCenterModule.directive('match', function ($parse) {
 });
 
 // Directive to bind ENTER key press with some user action.
-controlCenterModule.directive('ngEnter', function () {
+controlCenterModule.directive('onEnter', function ($timeout) {
     return function (scope, element, attrs) {
         element.bind('keydown keypress', function (event) {
             if (event.which === 13) {
                 scope.$apply(function () {
-                    scope.$eval(attrs.ngEnter);
+                    $timeout(function () {
+                        scope.$eval(attrs.onEnter)
+                    });
                 });
 
                 event.preventDefault();
@@ -392,12 +394,12 @@ controlCenterModule.directive('ngEnter', function () {
 });
 
 // Directive to bind ESC key press with some user action.
-controlCenterModule.directive('ngEscape', function () {
+controlCenterModule.directive('onEscape', function () {
     return function (scope, element, attrs) {
         element.bind('keydown keyup', function (event) {
             if (event.which === 27) {
                 scope.$apply(function () {
-                    scope.$eval(attrs.ngEscape);
+                    scope.$eval(attrs.onEscape);
                 });
 
                 event.preventDefault();
@@ -407,7 +409,7 @@ controlCenterModule.directive('ngEscape', function () {
 });
 
 // Factory function to focus element.
-controlCenterModule.factory('focus', function ($timeout, $window) {
+controlCenterModule.factory('$focus', function ($timeout, $window) {
     return function (id) {
         // Timeout makes sure that is invoked after any other event has been triggered.
         // E.g. click events that need to run before the focus or inputs elements that are
@@ -421,11 +423,24 @@ controlCenterModule.factory('focus', function ($timeout, $window) {
     };
 });
 
+// Directive to focus next element on ENTER key.
+controlCenterModule.directive('enterFocusNext', function ($focus) {
+    return function (scope, element, attrs) {
+        element.bind("keydown keypress", function (event) {
+            if (event.which === 13) {
+                event.preventDefault();
+
+                $focus(attrs.enterFocusNextId);
+            }
+        });
+    };
+});
+
 // Directive to mark elements to focus.
-controlCenterModule.directive('eventFocus', function (focus) {
+controlCenterModule.directive('eventFocus', function ($focus) {
     return function (scope, elem, attr) {
         elem.on(attr.eventFocus, function () {
-            focus(attr.eventFocusId);
+            $focus(attr.eventFocusId);
         });
 
         // Removes bound events in the element itself when the scope is destroyed
@@ -445,8 +460,8 @@ controlCenterModule.controller('activeLink', [
 
 // Login popup controller.
 controlCenterModule.controller('auth', [
-    '$scope', '$modal', '$alert', '$http', '$window', '$common',
-    function ($scope, $modal, $alert, $http, $window, $common) {
+    '$scope', '$modal', '$alert', '$http', '$window', '$common', '$focus',
+    function ($scope, $modal, $alert, $http, $window, $common, $focus) {
         $scope.errorMessage = $common.errorMessage;
 
         $scope.action = 'login';
@@ -467,7 +482,11 @@ controlCenterModule.controller('auth', [
 
         $scope.login = function () {
             // Show when some event occurs (use $promise property to ensure the template has been loaded)
-            authModal.$promise.then(authModal.show);
+            authModal.$promise.then(function () {
+                authModal.show();
+
+                $focus('user_email');
+            });
         };
 
         $scope.auth = function (action, user_info) {
@@ -484,7 +503,7 @@ controlCenterModule.controller('auth', [
     }]);
 
 // Navigation bar controller.
-controlCenterModule.controller('notebooks', ['$scope', '$http','$common', function ($scope, $http, $common) {
+controlCenterModule.controller('notebooks', ['$scope', '$http', '$common', function ($scope, $http, $common) {
     $scope.notebooks = [];
 
     // When landing on the page, get clusters and show them.
@@ -494,8 +513,8 @@ controlCenterModule.controller('notebooks', ['$scope', '$http','$common', functi
 
             if ($scope.notebooks.length > 0) {
                 $scope.notebookDropdown = [
-                    { text: 'Create new notebook', href: '/notebooks/new', target: '_self' },
-                    { divider: true }
+                    {text: 'Create new notebook', href: '/notebooks/new', target: '_self'},
+                    {divider: true}
                 ];
 
                 _.forEach($scope.notebooks, function (notebook) {
@@ -506,4 +525,4 @@ controlCenterModule.controller('notebooks', ['$scope', '$http','$common', functi
         .error(function (errMsg) {
             $common.showError(errMsg);
         });
-}]);
\ No newline at end of file
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/824b7d74/modules/control-center-web/src/main/js/controllers/models/metadata.json
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/controllers/models/metadata.json b/modules/control-center-web/src/main/js/controllers/models/metadata.json
index 65725b8..34157d0 100644
--- a/modules/control-center-web/src/main/js/controllers/models/metadata.json
+++ b/modules/control-center-web/src/main/js/controllers/models/metadata.json
@@ -94,6 +94,8 @@
       "keyName": "name",
       "valueName": "className",
       "hide": "backupItem.kind == 'query' || isJavaBuildInType()",
+      "focusNewItemId": "newKeyFields",
+      "focusCurItemId": "curKeyFields",
       "addTip": "Add key field.",
       "removeTip": "Remove key field.",
       "tip": [
@@ -107,6 +109,8 @@
       "keyName": "name",
       "valueName": "className",
       "hide": "backupItem.kind != 'both' && backupItem.kind == 'query'",
+      "focusNewItemId": "newValFields",
+      "focusCurItemId": "curValFields",
       "addTip": "Add value field.",
       "removeTip": "Remove value field.",
       "tip": [

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/824b7d74/modules/control-center-web/src/main/js/views/includes/controls.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/includes/controls.jade b/modules/control-center-web/src/main/js/views/includes/controls.jade
index faa3b96..dca31bc 100644
--- a/modules/control-center-web/src/main/js/views/includes/controls.jade
+++ b/modules/control-center-web/src/main/js/views/includes/controls.jade
@@ -38,7 +38,7 @@ mixin ico-exclamation(mdl, err, msg)
     i.fa.fa-exclamation-triangle.form-control-feedback(ng-show='inputForm["#{mdl}"].$error.#{err}' bs-tooltip data-title='#{msg}' type='button')
 
 mixin btn-save(show, click)
-    i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip data-title='Save item')
+    i.tipField.fa.fa-floppy-o(ng-show=show ng-click=click bs-tooltip data-title='Save item' data-trigger='hover')
 
 mixin btn-add(click, tip, focusId)
     i.tipField.fa.fa-plus(ng-click=click bs-tooltip=tip event-focus='click' event-focus-id=focusId)
@@ -53,22 +53,27 @@ mixin btn-down(show, click)
     i.tipField.fa.fa-arrow-down(ng-show=show ng-click=click bs-tooltip data-title='Move item down')
 
 mixin table-pair-edit(keyModel, valModel, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes, focusId, index)
+    -var focusIdNext = focusId + '_next'
+
     .col-sm-6
         label.fieldSep /
         .input-tip
             if keyJavaBuildInTypes
-                input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+                input.form-control(id=focusId enter-focus-next enter-focus-next-id=focusIdNext type='text' ng-model=keyModel placeholder=keyPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' on-escape='tableReset()')
             else
-                input.form-control(id=focusId type='text' ng-model=keyModel placeholder=keyPlaceholder ng-escape='tableReset()')
+                input.form-control(id=focusId enter-focus-next enter-focus-next-id=focusIdNext type='text' ng-model=keyModel placeholder=keyPlaceholder on-escape='tableReset()')
     .col-sm-6
         -var arg = keyModel + ', ' + valModel
+        -var btnVisible = 'tablePairSaveVisible(' + arg + ')'
+        -var btnSave = 'tablePairSave(tablePairValid, backupItem, field, '+ arg +', ' + index + ')'
+        -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
 
-        +btn-save('tablePairSaveVisible(' + arg + ')', 'tablePairSave(tablePairValid, backupItem, field, '+ arg +', ' + index + ')')
+        +btn-save(btnVisible, btnSave)
         .input-tip
             if valueJavaBuildInTypes
-                input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+                input.form-control(id=focusIdNext type='text' ng-model=valModel placeholder=valPlaceholder bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' on-enter=btnVisibleAndSave on-escape='tableReset()')
             else
-                input.form-control(type='text' ng-model=valModel placeholder=valPlaceholder ng-escape='tableReset()')
+                input.form-control(id=focusIdNext type='text' ng-model=valModel placeholder=valPlaceholder on-enter=btnVisibleAndSave on-escape='tableReset()')
 
 mixin table-pair(header, tblMdl, keyFld, valFld, keyPlaceholder, valPlaceholder, keyJavaBuildInTypes, valueJavaBuildInTypes)
     .col-sm-6
@@ -150,7 +155,7 @@ mixin details-row
                                 label.labelField {{$index + 1}})
                                 +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, detail, curValue, $index)')
                                 .input-tip.form-group.has-feedback
-                                    input.form-control(id='{{::detail.focusCurItemId}}' name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' ng-escape='tableReset()')&attributes(customValidators)
+                                    input.form-control(id='{{::detail.focusCurItemId}}' name='{{detail.model}}.edit' type='text' ng-model='curValue' placeholder='{{::detail.placeholder}}' on-escape='tableReset()')&attributes(customValidators)
                                     +ico-exclamation('{{detail.model}}.edit', 'ipaddress', 'Invalid address, see help for format description.')
             button.btn.btn-primary.fieldButton(ng-disabled='!newValue' ng-click='tableSimpleSave(tableSimpleValid, backupItem, detail, newValue, -1)') Add
             +tipField('detail.tip')
@@ -158,11 +163,13 @@ mixin details-row
                 input.form-control(name='{{detail.model}}' type='text' ng-model='newValue' ng-focus='tableNewItem(detail)' placeholder='{{::detail.placeholder}}')&attributes(customValidators)
                 +ico-exclamation('{{detail.model}}', 'ipaddress', 'Invalid address, see help for format description.')
 
-mixin table-db-field-edit(databaseName, databaseType, javaName, javaType, index)
+mixin table-db-field-edit(databaseName, databaseType, javaName, javaType, focusId, index)
+    -var focusIdNext = focusId + '_next'
+
     .col-sm-3
         label.fieldSep /
         .input-tip
-            input.form-control(type='text' ng-model=databaseName placeholder='DB name' ng-escape='tableReset()')
+            input.form-control(id=focusId enter-focus-next enter-focus-next-id=focusIdNext type='text' ng-model=databaseName placeholder='DB name' on-escape='tableReset()')
     .col-sm-3
         label.fieldSep /
         .input-tip
@@ -170,27 +177,33 @@ mixin table-db-field-edit(databaseName, databaseType, javaName, javaType, index)
     .col-sm-3
         label.fieldSep /
         .input-tip
-            input.form-control(type='text' ng-model=javaName placeholder='Java name' ng-escape='tableReset()')
+            input.form-control(id=focusIdNext type='text' ng-model=javaName placeholder='Java name' on-escape='tableReset()')
     .col-sm-3
-        - var args = databaseName + ', ' + databaseType + ', ' + javaName + ', ' + javaType
+        -var args = databaseName + ', ' + databaseType + ', ' + javaName + ', ' + javaType
+        -var btnVisible = 'tableDbFieldSaveVisible(' + args + ')'
+        -var btnSave = 'tableDbFieldSave(field, ' + args + ', ' + index +')'
 
-        +btn-save('tableDbFieldSaveVisible(' + args + ')', 'tableDbFieldSave(field, ' + args + ', ' + index +')')
+        +btn-save(btnVisible, btnSave)
         .input-tip
             button.form-control(ng-model=javaType bs-select data-placeholder='Java type' bs-options='item.value as item.label for item in {{javaTypes}}')
 
 mixin table-group-item-edit(fieldName, className, direction, focusId, index)
+    -var focusIdNext = focusId + '_next'
+    - var args = fieldName + ', ' + className
+    -var btnVisible = 'tableGroupItemSaveVisible(' + args + ')'
+    -var btnSave = 'tableGroupItemSave(' + args + ', ' + direction + ', groupIndex, ' + index +')'
+    -var btnVisibleAndSave = btnVisible + ' && ' + btnSave
+
     .col-sm-4
         label.fieldSep /
         .input-tip
-            input.form-control(id=focusId type='text' ng-model=fieldName placeholder='Field name' ng-escape='tableReset()')
+            input.form-control(id=focusId enter-focus-next enter-focus-next-id=focusIdNext type='text' ng-model=fieldName placeholder='Field name' on-escape='tableReset()')
     .col-sm-5
         label.fieldSep /
         .input-tip
-            input.form-control(type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' ng-escape='tableReset()')
+            input.form-control(id=focusIdNext type='text' ng-model=className placeholder='Class name' bs-typeahead data-min-length='1' bs-options='javaType for javaType in javaBuildInTypes' on-enter=btnVisibleAndSave on-escape='tableReset()')
     .col-sm-3
-        - var args = fieldName + ', ' + className
-
-        +btn-save('tableGroupItemSaveVisible(' + args + ')', 'tableGroupItemSave(' + args + ', ' + direction + ', groupIndex, ' + index +')')
+        +btn-save(btnVisible, btnSave)
         .input-tip
             button.form-control(ng-model=direction bs-select data-placeholder='Sort' bs-options='item.value as item.label for item in {{sortDirections}}')
 
@@ -284,13 +297,13 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                             label.labelField {{$index + 1}})
                                             +btn-save('tableSimpleSaveVisible(curValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)')
                                             .input-tip
-                                                input.form-control(id='{{::field.focusCurItemId}}' type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' ng-escape='tableReset()')
+                                                input.form-control(id='{{::field.focusCurItemId}}' type='text' ng-model='curValue' placeholder='{{::field.placeholder}}' on-enter='tableSimpleSaveVisible(curValue) && tableSimpleSave(tableSimpleValid, backupItem, field, curValue, $index)' on-escape='tableReset()')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
                                         +btn-save('tableSimpleSaveVisible(newValue)', 'tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)')
                                         .input-tip
-                                            input.form-control(id='{{::field.focusNewItemId}}' type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' ng-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' ng-escape='tableReset()')
+                                            input.form-control(id='{{::field.focusNewItemId}}' type='text' ng-model='newValue' placeholder='{{::field.placeholder}}' on-enter='tableSimpleSaveVisible(newValue) && tableSimpleSave(tableSimpleValid, backupItem, field, newValue, -1)' on-escape='tableReset()')
         div(ng-switch-when='indexedTypes')
             +table-pair('Index key-value type pairs', fieldMdl, 'keyClass', 'valueClass', 'Key class full name', 'Value class full name', true, false)
         div(ng-switch-when='queryFields' ng-hide=fieldHide)
@@ -299,7 +312,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
             .col-sm-6
                 label.table-header {{::field.label}}:
                 +tipLabel('field.tip')
-                +btn-add('tableNewItem(field)', 'field.addTip', 'field.focusNewItemId')
+                +btn-add('tableNewItem(field)', 'field.addTip', '{{::field.focusNewItemId}}')
             .col-sm-12(ng-show='(#{fieldMdl} && #{fieldMdl}.length > 0) || tableNewItemActive(field)')
                 .col-sm-6
                     .table-details
@@ -308,14 +321,14 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                 tr(ng-repeat='item in #{fieldMdl}')
                                     td.col-sm-12
                                         div(ng-show='!tableEditing(field, $index)')
-                                            a.labelFormField(ng-click='curField = tableStartEdit(backupItem, field, $index); curDatabaseName = curField.databaseName; curDatabaseType = curField.databaseType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.databaseName}} / {{item.databaseType}} / {{item.javaName}} / {{item.javaType}}
+                                            a.labelFormField(event-focus='click' event-focus-id='{{::field.focusCurItemId}}' ng-click='curField = tableStartEdit(backupItem, field, $index); curDatabaseName = curField.databaseName; curDatabaseType = curField.databaseType; curJavaName = curField.javaName; curJavaType = curField.javaType') {{$index + 1}}) {{item.databaseName}} / {{item.databaseType}} / {{item.javaName}} / {{item.javaType}}
                                             +btn-remove('tableRemove(backupItem, field, $index)', 'field.removeTip')
                                         div(ng-if='tableEditing(field, $index)')
-                                            +table-db-field-edit('curDatabaseName', 'curDatabaseType', 'curJavaName', 'curJavaType', '$index')
+                                            +table-db-field-edit('curDatabaseName', 'curDatabaseType', 'curJavaName', 'curJavaType', '{{::field.focusCurItemId}}', '$index')
                             tfoot(ng-show='tableNewItemActive(field)')
                                 tr
                                     td.col-sm-12
-                                        +table-db-field-edit('newDatabaseName', 'newDatabaseType', 'newJavaName', 'newJavaType', '-1')
+                                        +table-db-field-edit('newDatabaseName', 'newDatabaseType', 'newJavaName', 'newJavaType', '{{::field.focusNewItemId}}', '-1')
         div(ng-switch-when='queryGroups' ng-hide=fieldHide)
             .col-sm-6
                 label.table-header {{::field.label}}:
@@ -337,7 +350,7 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                                 label.labelField {{$index + 1}})
                                                 +btn-save('tableGroupSaveVisible(curGroupName)', 'tableGroupSave(curGroupName, $index)')
                                                 .input-tip
-                                                    input#curGroupId.form-control(type='text' ng-model='curGroupName' placeholder='Index name' ng-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' ng-escape='tableReset()')
+                                                    input#curGroupId.form-control(type='text' ng-model='curGroupName' placeholder='Index name' on-enter='tableGroupSaveVisible(curGroupName) && tableGroupSave(curGroupName, $index)' on-escape='tableReset()')
                                             div
                                                 table.links-edit.col-sm-12(st-table='group.fields' ng-init='groupIndex = $index')
                                                     tbody
@@ -357,4 +370,4 @@ mixin form-row-custom(lblClasses, fieldClasses)
                                     td.col-sm-12
                                         +btn-save('tableGroupSaveVisible(newGroupName)', 'tableGroupSave(newGroupName, -1)')
                                         .input-tip
-                                            input#newGroupId.form-control(type='text' ng-model='newGroupName' placeholder='Group name' ng-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' ng-escape='tableReset()')
\ No newline at end of file
+                                            input#newGroupId.form-control(type='text' ng-model='newGroupName' placeholder='Group name' on-enter='tableGroupSaveVisible(newGroupName) && tableGroupSave(newGroupName, -1)' on-escape='tableReset()')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/824b7d74/modules/control-center-web/src/main/js/views/login.jade
----------------------------------------------------------------------
diff --git a/modules/control-center-web/src/main/js/views/login.jade b/modules/control-center-web/src/main/js/views/login.jade
index a580c01..d32378f 100644
--- a/modules/control-center-web/src/main/js/views/login.jade
+++ b/modules/control-center-web/src/main/js/views/login.jade
@@ -33,23 +33,22 @@ mixin lbl(txt)
                         .details-row(ng-show='action == "register"')
                             +lbl('Full Name:')
                             .col-sm-9
-                                input.form-control(type='text' ng-model='user_info.username' placeholder='John Smith' focus-me='action=="register"' ng-required='action=="register"')
+                                input#user_name.form-control(enter-focus-next enter-focus-next-id='user_email' type='text' ng-model='user_info.username' placeholder='John Smith' ng-required='action=="register"')
                         .details-row
                             +lbl('Email:')
                             .col-sm-9
-                                input.form-control(type='email' ng-model='user_info.email' placeholder='you@domain.com' focus-me='action=="login"' required)
+                                input#user_email.form-control(enter-focus-next enter-focus-next-id='user_password' type='email' ng-model='user_info.email' placeholder='you@domain.com' required)
                         .details-row
                             +lbl('Password:')
                             .col-sm-9
-                                input.form-control(type='password' ng-model='user_info.password' placeholder='Password' required ng-enter='action == "login" && auth(action, user_info)')
+                                input#user_password.form-control(enter-focus-next enter-focus-next-id='user_confirm' type='password' ng-model='user_info.password' placeholder='Password' required on-enter='action == "login" && auth(action, user_info)')
                         .details-row(ng-show='action == "register"')
                             +lbl('Confirm:')
                             .col-sm-9.input-tip.has-feedback
-                                input.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required ng-enter='auth(action, user_info)')
-
+                                input#user_confirm.form-control(type='password' ng-model='user_info.confirm' match='user_info.password' placeholder='Confirm password' required on-enter='auth(action, user_info)')
             .modal-footer
-                a.show-signup.ng-hide(ng-show='action != "login"' ng-click='action = "login";') log in
-                a.show-signup(ng-show='action != "register"' ng-click='action = "register"') sign up
+                a.show-signup.ng-hide(event-focus='click' event-focus-id='user_email' ng-show='action != "login"' ng-click='action = "login";') log in
+                a.show-signup(event-focus='click' event-focus-id='user_name' ng-show='action != "register"' ng-click='action = "register"') sign up
                 | &nbsp;or&nbsp;
                 button.btn.btn-primary(ng-show='action == "login"' ng-click='auth(action, user_info)') Log In
                 button.btn.btn-primary(ng-show='action == "register"' ng-disabled='loginForm.$invalid || user_info.password != user_info.confirm' ng-click='auth(action, user_info)') Sign Up