AngularJS submit on blur and blur on keypress

12,232

Solution 1

Here's what's happening:

  • You press enter
  • ng-keydown triggers (digest begins)
  • You call target.blur()
  • ng-blur triggers and attempts to start another digest cycle
  • Angular complains

The blur is executed synchronously and immediately triggers the handler without finishing the first digest.

In my opinion, this is not a problem with your code, but rather an Angular bug. I've been trying to think of a better solution, but I can only find:

app.controller('BlurCtrl', function($scope, $timeout) {
  $scope.blurModel = "I'm the value"

    $scope.blurOnEnter = function( $event ) {
      if ( $event.keyCode != 13 )
        return

      // this will finish the current digest before triggering the blur
      $timeout(function () { $event.target.blur() }, 0, false);
    }

    $scope.onBlur = function() {
    $scope.result = this.blurModel
    }
})

Solution 2

You can checkout Angular UI @ http://angular-ui.github.io/ui-utils/

Provide details event handle related blur,focus,keydow,keyup,keypress

<input ui-event="{ blur : 'blurCallback()' }">
<textarea ui-keypress="{13:'keypressCallback($event)'}"></textarea>
<textarea ui-keydown="{'enter alt-space':'keypressCallback($event)'}"> </textarea>
<textarea ui-keydown="{27:'keydownCallback($event)'}"></textarea>
<textarea ui-keydown="{'enter alt-space':'keypressCallback($event)'}"> </textarea>
<textarea ui-keyup="{'enter':'keypressCallback($event)'}"> </textarea>

Solution 3

Here is a small directive :

    .directive('ngEnterBlur', function () {
    return function (scope, element, attrs) {
        element.bind("keydown keypress blur", function (event) {
            if(event.which === 13 || event.type === "blur") {
                scope.$apply(function (){
                    scope.$eval(attrs.ngEnterBlur);
                });

                event.preventDefault();
            }
        });
    };
})
Share:
12,232
ahoereth
Author by

ahoereth

Updated on July 09, 2022

Comments

  • ahoereth
    ahoereth almost 2 years

    I want to submit some data to the server when a input field is blurred. The User should also be able to blur the input field by pressing enter.

    Unfortunately this results in the following: $rootScope:inprog: $apply already in progress error.

    Plunkr - thanks in advance!

  • JimTheDev
    JimTheDev about 10 years
    Thank you for this. I was only seeing this on Safari mobile.
  • Tyler Forsythe
    Tyler Forsythe about 10 years
    I was having an issue with ng-blur double-firing. Switching to ui-event for blur instantly solved my problem and saved me a lot of headache. Thank you!
  • Design by Adrian
    Design by Adrian almost 10 years
    I had this problem in Chrome. On clicking a button, I wanted to call blur() on an input element. Adding the myInput.blur() inside a timeout fixed my problem!