onkami
onkami

Reputation: 9411

AngularJS directive for text input: focus on next input on Enter

I would like to implement such a directive for AngularJS: if used in input[text], on hitting enter the focus would move to next input. What would be the best way to accomplish this?

I have a very large form and would like to implement a way to go over the fields in a fast way.

Upvotes: 1

Views: 5535

Answers (3)

Eduardo Cuomo
Eduardo Cuomo

Reputation: 18937

Create a custom directive:

.directive('nextOnEnter', function () {
    return {
        restrict: 'A',
        link: function ($scope, selem, attrs) {
            selem.bind('keydown', function (e) {
                var code = e.keyCode || e.which;
                if (code === 13) {
                    e.preventDefault();
                    var pageElems = document.querySelectorAll('input, select, textarea'),
                        elem = e.srcElement
                        focusNext = false,
                        len = pageElems.length;
                    for (var i = 0; i < len; i++) {
                        var pe = pageElems[i];
                        if (focusNext) {
                            if (pe.style.display !== 'none') {
                                pe.focus();
                                break;
                            }
                        } else if (pe === e.srcElement) {
                            focusNext = true;
                        }
                    }
                }
            });
        }
    }
})

Source: https://stackoverflow.com/a/36960376/717267

Upvotes: 0

HumanCEO
HumanCEO

Reputation: 2561

Another solution, use this directive:

angular.module('myApp').directive("nextFocus", nextFocus);

/** Usage:
  <input next-focus id="field1">
  <input next-focus id="field2">
  <input id="field3">
  Upon pressing ENTER key the directive will switch focus to
  the next field id e.g field2
  The last field should not have next-focus directive to avoid
  focusing on non-existing element.
  Works for Web, iOS (Go button) & Android (Next button) browsers, 
**/

function nextFocus() {
  var directive = {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      elem.bind('keydown', function(e) {
        var partsId = attrs.id.match(/field(\d{1})/);
        var currentId = parseInt(partsId[1]);

        var code = e.keyCode || e.which;
        if (code === 13) {
          e.preventDefault();
          document.querySelector('#field' + (currentId + 1)).focus();
        }
      });
    }
  };
  return directive;

}

Related: angularjs move focus to next control on enter

Upvotes: 0

Cem &#214;zer
Cem &#214;zer

Reputation: 1283

Check this FIDDLE

There is ngKeypress directive in AngularJS, you can read more in here.

If your form is static as you mentioned, easiest way to accomplish what you need is passing next input's id (or index in my example). It's up to you how to provide ids, you can pass entire id or an index.

<input type="text" ng-model="field1" id="f_1"
       ng-keypress="keypressHandler($event, 2)"/>
<br/>
<input type="text" ng-model="field2" id="f_2" 
       ng-keypress="keypressHandler($event, 3)"/>
<br/>

Then in your controller, if key is enter, get element by given id, then focus it.

$scope.keypressHandler = function(event, nextIdx){
    if(event.keyCode == 13){
        angular.element(
            document.querySelector('#f_'+nextIdx))[0].focus();

    }
}

As you can see, you can use ng-repeat like that by passing $index instead of hardcoded numbers and creating ids dynamically.

Upvotes: 4

Related Questions