2

I'm trying to build a simple directive following the tutorial from this link: http://slides.com/djsmith/deep-dive-into-custom-directives (it's slides 11 and 12 I think, there is no numbering).

Since it just shows the JavaScript part and small part of the HTML part (just the text input). I made my own html page as follows:

<!DOCTYPE html>
  <html>
    <head>
      <title>Directives</title>
      <script src="Scripts/angular.min.js"></script>
      <script src="Scripts/angular-route.min.js"></script>
      <script src="Scripts/app.js"></script>
    </head>
    <body ng-app="MyDirectives" ng-controller="DirectivesController">
     <input type="text" select-all-on-focus />
    </body>
</html>

The JS file with the module and the controller (just an empty one, I thought not having one might be the problem) and the directive:

var myModule = angular.module('MyDirectives', []);

myModule.controller('DirectivesController', ['$scope', function ($scope) {

}]);

myModule.directive('selectAllOnFocus', function () {
    return {
        restrict: 'A', 
        link: function linkFn (scope, element, attrs) {
            element.mouseup(function (event) {
              alert("Lost focus!");
              event.preventDefault();
            });
            element.focus(function () {
              element.select();
              alert("Focused!");
            });
        }
      }
});

The error which appears on the Chrome console is:

TypeError: undefined is not a function at linkFn at J at f at J at f at ... at ... at h.$get.h.$eval at h.$get.h.$apply at http://

There seems to be a problem with the link function.

4
  • You don't need to name your link function. link: function(scope, element, attrs) will do Commented May 23, 2014 at 13:25
  • Still not working, the error is the same. Commented May 23, 2014 at 13:30
  • Are you getting undefined is not a function on mouseup by any chance? Commented May 23, 2014 at 13:33
  • you are defining the directive as an A (attribute). That is why mouseup/focus functions are not working Commented Jun 25, 2015 at 2:17

3 Answers 3

6

AngularJS's jqLite implementation doesn't have friendly methods for click, mouseup, etc. You should use .on instead:

myModule.directive('selectAllOnFocus', function () {
    return {
        restrict: 'A', 
        link: function(scope, element, attrs) {
            element.on("mouseup", function (event) {
              alert("Lost focus!");
              event.preventDefault();
            });
            element.on("focus", function () {
              element.select();
              alert("Focused!");
            });
        }
      }
});

jsFiddle

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

5 Comments

Hmm, there are no errors now, but obviously there is no select() function on the "focus" event (undefined error on select()). Mouseup event is not executing on the other side (if I'm getting it right this should execute when I lose focus?).
However these are issues of other essence so I guess the questions is solved. Thanks!
@RosenDimov Yup, just need to chain the events and not use alert! jsfiddle.net/qu6JD
Thanks for the fiddle, I just have one question - why this.select() worked and element.select() didn't? Is this.select() the way to select the input in AngularJS?
@RosenDimov Same issue that AngularJS does not provide shortcut methods. this.select() is not using jQuery, but using the default browser's select() method.
1

Why are you naming the link function? Just pass it an anonymous function.

link: function (scope, element, attrs) {
   //...
}

The problem though with the code is what is available to you when using angular.element. It is am implementation of jQuery Lite and doesnt give you access to all the methods.

So to bind event listeners you will need to use.

element.on('mousedown', function() {
  //...
}

This is the angular.element definition

2 Comments

It has nothing to do with the error and naming function is SUCH a good idea. (In fact all Angular's inline functions are named and it is trmendously helpful for stuff like debugging, profiling etc.)
You figure once you open the DevTools and try to debug some weird issue or profile your app or use Batarang or...
0

The tutorial works as given by Dave Smith but JQuery is required. See Plunk http://plnkr.co/edit/8EgmrYExKXlMzhwIO9Rv?p=info

If you check the angular.element docs at https://docs.angularjs.org/api/ng/function/angular.element you will see the mouseup() is not available with JQLite.

angular.module('myApp.directives',[])

.directive('selectAllOnFocus', function($timeout) {
  return {
    restrict: 'A',
    link: function(scope, element) {
      element.mouseup(function(event) {
        event.preventDefault();
      });
      element.focus(function() {
        element.select();
      });
    }
  }
})

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.