Reputation: 9411
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
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
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
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