Focus on the next input when reaching the maximum number of characters

2

I created a directive to move the cursor to the next field when it reaches the maximum size of characters, as follows:

var app = angular.module("myApp", []);

app.directive("moverProximoCampo", function() {
    return {
        restrict: "A",
        link: function($scope, element) {
            element.on("input", function(e) {
                if(element.val().length == element.attr("maxlength")) {
                    var $nextElement = element.next();
                    if($nextElement.length) {
                        $nextElement[0].focus();
                    }
                }
            });
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script><divng-app="myApp">
    <form>
    <input type="text" id="part1" ng-model="form.part1" maxlength="3" placeholder="3 caracteres" mover-proximo-campo />
    <input  placeholder="2 caracteres"  type="text" id="part2" ng-model="form.part2" maxlength="2" mover-proximo-campo /> 
    <input  placeholder="7 caracteres"  type="text" id="part3" ng-model="form.part3" maxlength="7" mover-proximo-campo />
</form>
</div>

But if I put any element between these inputs , such as div , the next input is not focused. See:

var app = angular.module("myApp", []);

app.directive("moverProximoCampo", function() {
    return {
        restrict: "A",
        link: function($scope, element) {
            element.on("input", function(e) {
                if(element.val().length == element.attr("maxlength")) {
                    var $nextElement = element.next();
                    if($nextElement.length) {
                        $nextElement[0].focus();
                    }
                }
            });
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script><divng-app="myApp">
    <form>
    <input type="text" id="part1" ng-model="form.part1" maxlength="3" placeholder="3 caracteres" mover-proximo-campo />
    <div> Tem uma div aqui entre os inputs</div>
    <input  placeholder="2 caracteres"  type="text" id="part2" ng-model="form.part2" maxlength="2" mover-proximo-campo /> 
    <div> Tem outra div aqui entre os inputs</div>
    <input  placeholder="7 caracteres"  type="text" id="part3" ng-model="form.part3" maxlength="7" mover-proximo-campo />
</form>
</div>

Actually, the idea would be to focus on the next input , but not on the next element. What would be the most practical way to resolve this?

    
asked by anonymous 25.06.2018 / 21:53

2 answers

2

I get the parent element and look for the input elements. I search for the position of the current element and assign the element of the next index into a variable and then use it to focus. I used the angle of forEach to find the content, but not mind JQuery would in html to use inArray . (include a commented example). I changed the event from input to keyup .

var app = angular.module("myApp", []);
app.directive("moverProximoCampo", function() {
return {
    restrict: "A",
    link: function($scope, element) {
        var inputs = element.parent().find('input');
        //com JQlite
        var $nextElement = []; 
        angular.forEach(inputs, function(elem,index){
            if(elem == element[0]){
                $nextElement = inputs.eq(index+1);
            }
        })
        //Se usar o JQuery ao invés do JQlite
        //var index = angular.element.inArray(element[0], inputs);
        //var $nextElement = inputs.eq(index+1);
        
        element.on("keyup", function(e) {
            if(element.val().length == element.attr("maxlength")) {
                if($nextElement.length) {
                    $nextElement[0].focus();
                }
            }
        });
    }
}
});
<!-- <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>--><scriptsrc="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
    <form>
    <input type="text" id="part1" ng-model="form.part1" maxlength="3" placeholder="3 caracteres" mover-proximo-campo />
    <div> Tem uma div aqui entre os inputs</div>
    <input  placeholder="2 caracteres"  type="text" id="part2" ng-model="form.part2" maxlength="2" mover-proximo-campo /> 
    <div> Tem outra div aqui entre os inputs</div>
    <input  placeholder="7 caracteres"  type="text" id="part3" ng-model="form.part3" maxlength="7" mover-proximo-campo />
</form>
</div>
    
05.07.2018 / 09:09
2

I particularly like to make things easier. Why should the directive guess what the next input , and can I even tell you in the mover-proximo-campo directive statement?

See the example I made:

var app = angular.module("myApp", []);

app.directive("moverProximoCampo", function() {
    return {
        restrict: "A",
        link: function($scope, element, attr) {
          
            var proximoId = attr.moverProximoCampo;
            
            element.on("input", function(e) {
                if(element.val().length == element.attr("maxlength")) {
                    
                    document.querySelector(proximoId).focus();
                }
            });
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script><divng-app="myApp">
    <form>
    <input type="text" id="part1" ng-model="form.part1" maxlength="3" placeholder="3 caracteres" mover-proximo-campo="#part2" />
    <div> Tem uma div aqui entre os inputs</div>
    <input  placeholder="2 caracteres"  type="text" id="part2" ng-model="form.part2" maxlength="2" mover-proximo-campo="#part3" /> 
    <div> Tem outra div aqui entre os inputs</div>
    <input  placeholder="7 caracteres"  type="text" id="part3" ng-model="form.part3" maxlength="7" />
</form>
</div>

Note that what I did was to change the declaration of the directives of your inputs, stating, as a parameter, which is the next element that I should focus on. That is, in the directive, you pass id of the next desired element to the focus when the condition is met.

More or less like this:

<input mover-proximo-campo="#campo2" id="campo1" />
<input id="campo2" mover-proximo-campo="#campo3" />
<input id="campo3"  />
    
04.07.2018 / 16:32