AngularJS: move to the next form input element after successful validation

I wrote a special directive to check my form fields. When certain criteria are met (i.e., it is dirty and valid), I want to automatically adjust the focus to the next input element. This is a requirement from my users, so that they can most effectively navigate forms.

A simplified directive is as follows:

directive('custom', ['$parse', function($parse) { return { restrict: 'A', require: ['ngModel', '^ngController'], link: function(scope, element, attrs, ctrls) { var model=ctrls[0], form=ctrls[1]; scope.next = function(){ return model.$valid } scope.$watch(scope.next, function(newValue, oldValue){ if (newValue && model.$dirty){ ??? } }) 

Now my question is: how can I determine - the next input element (which is the next sibling) or perhaps through tabindex - and focus on it without using jQuery?

It is currently unclear to me how to go to the next input element from the available "scope" or "element" attributes without jQuery; and JQlite does not have a focus method. Basically, I need a working replacement ??? in my code.

Any help is greatly appreciated. thanks JΓΌrgen

+4
source share
4 answers

You can use [0] to get the basic input element (which has the focus() function) from the angular / jqLite object (which is not the case).

 app.directive('custom', ['$parse', function($parse) { return { restrict: 'A', require: ['ngModel'], link: function(scope, element, attrs, ctrls) { var model=ctrls[0], form=ctrls[1]; scope.next = function(){ return model.$valid; } scope.$watch(scope.next, function(newValue, oldValue){ if (newValue && model.$dirty) { var nextinput = element.next('input'); if (nextinput.length === 1) { nextinput[0].focus(); } } }) } } }]) 

http://jsfiddle.net/Y2XLA/

+5
source

element.next().focus() may not work if you have a complex shape and input is nested in different divs. I finished writing this directive (here I move the focus to Enter, but can be adapted to any event):

 .directive('enterToTab', function($timeout) { return { restrict: 'A', link: function(scope, element, attrs) { var procAttr = 'data-ett-processed'; $timeout(function() { // Use $timeout to run the directive when the DOM is fully rendered var formElements = element[0].querySelectorAll('input:not([' + procAttr + '="true"]), select:not([' + procAttr + '="true"]), textarea:not([' + procAttr + '="true"])'); // Run through all elements in form var formElementsLength = formElements.length; for (var i = 0; i < formElementsLength; i++) { // Add tabindex attribute formElements[i].setAttribute('tabindex', i + 1); // Go to next element on Enter key press formElements[i].addEventListener('keypress', function(event) { if (event.keyCode === 13) { // Enter // Prevent Angular from validating all the fields and submitting if (event.target.tagName !== 'TEXTAREA') { // Not on textarea, otherwise not possible to add new line event.stopPropagation(); event.preventDefault(); } var nextIndex = parseInt(event.target.getAttribute('tabindex')) + 1; // Move focus to next element // TODO: find next visible element var nextElem = element[0].querySelector('[tabIndex="' + (nextIndex) + '"]'); if (nextElem) { nextElem.focus(); } } }); formElements[i].setAttribute(procAttr, true); // Add attribute to prevent adding 2 listeners on same element } }); } }; }); 
+3
source
  • The event must be in the HTML component (keypress) = "keyFocus($event)"
  • The shoulb method will look like .ts .

    keyFocus(input1){ input1.srcElement.nextElementSibling.focus(); }

+1
source

AngularJS already contains a light version of jQuery so you can use it ... http://docs.angularjs.org/api/angular.element

You can try something like this:

element.next (). Focus()

0
source

Source: https://habr.com/ru/post/1494328/


All Articles