Skip to content

Instantly share code, notes, and snippets.

@EpokK
Last active January 7, 2022 13:57
Show Gist options
  • Save EpokK/5884263 to your computer and use it in GitHub Desktop.
Save EpokK/5884263 to your computer and use it in GitHub Desktop.
ngEnter directive if you can use submit form(https://twitter.com/ririlepanda)
app.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.preventDefault();
}
});
};
});
@dougrchamberlain
Copy link

This is silly. angular provides ng-keypress. what functionality is this providing that ng-keypress doesn't already? This directive has been around since at least 1.2.29 https://code.angularjs.org/1.2.29/docs/api/ng/directive/ngKeypress I looked at the source code too, it's

/*
               * A collection of directives that allows creation of custom event handlers that are defined as
               * angular expressions and are compiled and executed within the current scope.
               */
              var ngEventDirectives = {};

              // For events that might fire synchronously during DOM manipulation
              // we need to execute their event handlers asynchronously using $evalAsync,
              // so that they are not executed in an inconsistent state.
              var forceAsyncEvents = {
                'blur': true,
                'focus': true
              };
              forEach(
                'click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste'.split(' '),
                function(eventName) {
                  var directiveName = directiveNormalize('ng-' + eventName);
                  ngEventDirectives[directiveName] = ['$parse', '$rootScope', function($parse, $rootScope) {
                    return {
                      restrict: 'A',
                      compile: function($element, attr) {
                        // We expose the powerful $event object on the scope that provides access to the Window,
                        // etc. that isn't protected by the fast paths in $parse.  We explicitly request better
                        // checks at the cost of speed since event handler expressions are not executed as
                        // frequently as regular change detection.
                        var fn = $parse(attr[directiveName], /* interceptorFn */ null, /* expensiveChecks */ true);
                        return function ngEventHandler(scope, element) {
                          element.on(eventName, function(event) {
                            var callback = function() {
                              fn(scope, {$event:event});
                            };
                            if (forceAsyncEvents[eventName] && $rootScope.$$phase) {
                              scope.$evalAsync(callback);
                            } else {
                              scope.$apply(callback);
                            }
                          });
                        };
                      }
                    };
                  }];
                }
              );

@jose-marin
Copy link

jose-marin commented Aug 11, 2016

You don't need to use eval if you bind the function passed. It also makes the scope isolate, so the directive doesn't depend on a parent controller.

app.directive('onEnter', function() {
    return {
        restrict: "A",
        scope: {
            action: "&onEnter"
        },
        link: function(scope, element, attrs) {
            element.on("keydown keypress", function(event) {
                if(event.which === 13) {
                    scope.$apply(scope.action);
                    event.preventDefault();
                }
            });
        }
    };
});

@adilbenmoussa
Copy link

No was is asking the question if element.on("keydown keypress", fun) should be unbind? when destroying the element?

@georgeportillo
Copy link

georgeportillo commented Sep 21, 2016

@jose-marin thanks for the snippet!

@michalpanek
Copy link

attrs is no needed.

  link: function(scope, element, attrs) {

@w0nderw0man
Copy link

@jbaroudi thanks for typescript users

@developerant
Copy link

@jose-marin - nicely done. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment