Jitender Yadav
Jitender Yadav

Reputation: 365

applying ng-blur and keydown (to capture enter key) on the same input element shows $apply already in progress error

I am developing an application in which there are rows one after other which contain input boxes.I have attached ng-blur and ng-keydown events to the input boxes.

On ng-keydown, i check if an enter was pressed then set focus to the next input box but as ng-blur is also attached to the input, it also fires when i try to set focus to the next input which throws $apply already in progress error on the console and hence the code on ng-blur fails to run.

Html:

<div class="main" ng-app ng-controller="appCtrl">
    <input type="text" ng-repeat="name in names" ng-model="name" ng-blur="checkUpdate(name)" ng-keydown="keydownoperations(names,$event)"/>
</div>
<script src="http://code.jquery.com/jquery-2.1.1.js"></script>

JS:

function appCtrl($scope){
 $scope.names = ['John','Smith','Ravi'];

 $scope.checkUpdate = function(name){
    console.log(name);
 }

 $scope.keydownoperations = function(names,event){
     var $this = $(event.target);
     if(event.which === 13) // Enter key
     { 
            if($this.next().length) // if the adjacent sibling exists set focus
            {
                $this.next().focus();
            }
     }
   }
}

Please see this fiddle http://jsfiddle.net/jitender60/qDZa9/4/ to get a clear view of my problem

Upvotes: 1

Views: 3581

Answers (1)

runTarm
runTarm

Reputation: 11547

The $scope.$apply() is called automatically by both ng-blur and ng-keydown.

The problem occurred because you trigger the focus event programmatically inside the keydown event handler. That will eventually trigger a blur event on a previously active element which in this case also has ng-blur on it.

Angular doesn't know if the blur event come from a user interaction or is triggered programmatically.

You could avoid the problem by defer the .focus() execution, may be inject a $timeout service and use it like this:

$timeout(function () {
  $this.next().focus();
}, 0);

Hope this helps.

Upvotes: 3

Related Questions