30

I found this question very useful for submitting a form when someone presses the "enter" key:

Javascript:

angular.module('yourModuleName').directive('ngEnter', function() {
    return function(scope, element, attrs) {
        element.bind("keydown keypress", function(event) {
            if(event.which === 13) {
                scope.$apply(function(){
                    scope.$eval(attrs.ngEnter, {'event': event});
                });

                event.preventDefault();
            }
        });
    };
});

HTML:

<div ng-app="" ng-controller="MainCtrl">
    <input type="text" ng-enter="doSomething()">    
</div>

What I would like to do know, is to set the field to blur when the "enter" key is pressed. What would doSomething() look like to blur the sender field?

I would like to leave the ngEnter directive as it is, since I would like to re-use it for other functions.

Update: I know I can create a whole directive just for blurring (that's how I have it now), but what I'd like to do is be able to do something like this:

<input type="text" ng-enter="this.blur()">

Or how do I pass the current element as a parameter?

<input type="text" ng-enter="doBlur(this)">
6
  • possible duplicate of Angular js trigger blur event Commented Dec 1, 2014 at 18:58
  • Also, stackoverflow.com/questions/18389527/… Commented Dec 1, 2014 at 18:58
  • @SoluableNonagon I updated my question. I know I can make a custom directive just for blurring, but I want to keep the directive generic. Commented Dec 1, 2014 at 19:49
  • I think you will need a custom directive just for blurring. Don't know of a good way to do this except to pass an event to the doBlur function. Like so: stackoverflow.com/questions/12994710/… but you will need something to pass $event Commented Dec 1, 2014 at 20:20
  • I was afraid of that... Thanks for trying, though. Commented Dec 1, 2014 at 20:28

3 Answers 3

33

After trying a bunch of things, this is seems not possible, as you would need to pass $event to get the target element, so separate directive seems to be the only way to go:

What we desire:

You cannot pass this because it refers to the scope, so you need to pass the event.

<input type="text" ng-enter="doBlur($event)">

Once you have the event, you can get the target from it.

$scope.doBlur = function($event){
    var target = $event.target;

    // do more here, like blur or other things
    target.blur();
}

But, you can only get pass event in a directive like ng-click ... kinda unsatisfactory. If we could pass $event outside directive, we could blur in that reusable way you requested.

Sign up to request clarification or add additional context in comments.

4 Comments

I hate to say this, but it seems jQuery would be easier to use in this case
This solution worked with me only when I passed the event parameter as per this line of code: scope.$eval(attrs.ngEnter, {'event': event});. Thanks a lot.
Worked fine in Chrome, but in Firefox and Edge the focus was lost. To keep focus: target.focus()
@SoluableNonagon React has a more elegant approach than this too. You don't need jQuery. You just need a framework that is designed for the web, not for Java applications.
6

for Angular 2+

<input ... (keydown.enter)='$event.target.blur()'>

2 Comments

This needs more upvotes since angular 2+ is presumably gaining over angularjs.
to solve Property 'blur' does not exist on type 'EventTarget' error, use add an ID to the input element, and call blur on that: <input #myInput ... (keydown...)='myInput.blur()'
4

SoluableNonagon was very close to it. You just have to use the right argument. The directive declared the event parameter as event not $event. You could change the directive to use $event just as ngClick does (Or you keep it and use it as ng-enter="doSomething(event)".

angular.module("app", [])
  .controller('MainController', MainController)
  .directive('myEnter', myEnter);

function MainController() {
  var vm = this;
  vm.text = '';
  vm.enter = function($event) {
    $event.target.blur();
    vm.result = vm.text;
    vm.text = '';
  }
}

myEnter.$inject = ['$parse'];

function myEnter($parse) {
  return {
    restrict: 'A',
    compile: function($element, attr) {
      var fn = $parse(attr.myEnter, null, true);
      return function(scope, element) {
        element.on("keydown keypress", function(event) {
          if (event.which === 13) {
            
            // This will pass event where the expression used $event
            fn(scope, { $event: event });
            scope.$apply();
            event.preventDefault();
          }
        });
      };
    }
  };
}
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>

<div ng-app="app" ng-controller="MainController as view">
  <input my-enter="view.enter($event)" ng-model="view.text">
  <div ng-bind="view.result"></div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.