Charan Chillzz Charan Chillzz - 3 months ago 128
AngularJS Question

Angular js Move focus to next input field when max character length reached and move focus to previous input field when character length is minimum

My Task

Create 3 inputs each with maximum char. length 5 When entering the 5th char. in an input the cursor should jump to the next input right after the char has been inserted. When deleting the 1st char of an input the cursor should jump at the end of previous input right after that char has been deleted.

What I have done

Created 3 input fields and restricted the character length to 5 using watch group and it is working perfectly

My Problem

I need to move my cursor to next input field when a input field reaches maximum character length of 5 and if the first character has been deleted from an input field cursor should move automatically to the previous input field end

my plunker link is here https://plnkr.co/edit/Bcq6slz9gbK8r6Lm8MAh?p=preview

My angular code

var app = angular.module("task8", []);
app.controller("taskController8",["$scope", function ($scope) {

$scope.charLength=5

$scope.$watchGroup(['firstInput', 'secondInput', 'thirdInput'], function (newValue, oldValue) {
if (newValue) {
if (newValue[0].length > 5) {
$scope.firstInput = oldValue[0];
}
else if (newValue[1].length > 5) {
$scope.secondInput = oldValue[1];
newValue[2].focus();
}
else if (newValue[2].length > 5) {
$scope.thirdInput = oldValue[2];
}
$scope.charLength = 5 - newValue[0].length;
$scope.charLength = 5 - newValue[1].length;
$scope.charLength = 5 - newValue[2].length;
}
})

$scope.updateBody = function (event) {
return false;
};
}]);

Answer

Here is a working example with an AngularJS Directive:

angular
  .module('MyApp', [])
  .directive('moveFocus', function() {
    function getCaretPosition(elem) {
      // Internet Explorer Caret Position
      if (document.selection && document.selection.createRange) {
        var range = document.selection.createRange();
        var bookmark = range.getBookmark();
        return bookmark.charCodeAt(2) - 2;
      }

      // Firefox Caret Position
      return elem.setSelectionRange && elem.selectionStart;
    }

    return {
      restrict: 'A',
      link: function(scope, elem, attr) {
        var tabindex = parseInt(attr.tabindex);
        var maxlength = parseInt(attr.maxlength);

        elem.on('input, keydown', function(e) {
          var val = elem.val(),
              cp, 
              code = e.which || e.keyCode;

          if (val.length === maxlength && [8, 37, 38, 39, 40, 46].indexOf(code) === -1) {
            var next = document.querySelectorAll('#input' + (tabindex + 1));
            next.length && next[0].focus();
            return;
          }

          cp = getCaretPosition(this);
          if ((cp === 0 && code === 46) || (cp === 1 && code === 8)) {
            var prev = document.querySelectorAll('#input' + (tabindex - 1));
            e.preventDefault();
            elem.val(val.substring(1));
            prev.length && prev[0].focus();
            return;
          }
        });
      }
    };
  });
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="MyApp">
  <form name="form">
    <div class="form-group">
      <label for="input1">Input 1</label>
      <input type="text" class="form-control" id="input1" name="input1" tabindex="1" maxlength="5" move-focus placeholder="Input 1">
    </div>
    <div class="form-group">
      <label for="input2">Input 2</label>
      <input type="text" class="form-control" id="input2" name="input2" tabindex="2" maxlength="5" move-focus placeholder="Input 2">
    </div>
    <div class="form-group">
      <label for="input3">Input 3</label>
      <input type="text" class="form-control" id="input3" name="input3" tabindex="3" maxlength="5" move-focus placeholder="Input 3">
    </div>
  </form>
</div>