2

I am trying to capture the event when the user close or cancel the File Upload Window

<input type="file">

Since there's no built in listener for the close event of the file upload, I am trying to capture it via the document.body.focus event, something like the one suggested here

I'm getting it to run using javascript

document.body.onfocus = function() { console.log("hit me") }

Now I need to implement it in Angular in my directive so that I could put logic inside the focus event using the objects in the controller.

How to access the onfocus event of document.body inside an angular controller?

From @Phil suggestion (using link)

 ... this is a directive with controller
angular.directive("addPost", addPost);

addPost.$inject = ["$document", "$log"];

function addPost($document, $log) {

    return {
        ...
        link: link,
        ...
    };

    function link() {
        $document.find('body').on('focus', function (e) {
            $log.debug('HIT ME!');
        });
    }
Community
  • 1
  • 1
Linc Abela
  • 797
  • 2
  • 12
  • 26
  • 3
    Try to use `ng-focus`. – Alberto I.N.J. Jul 07 '15 at 04:29
  • @AlbertoI.N.J. in my application the `` element is outside the angular scope, i mean it is on an MVC view. How can I attach ng-focus on it? – Linc Abela Jul 07 '15 at 04:33
  • 1
    You could try `$document.find('body').on('focus', function(e) { ... })` – Phil Jul 07 '15 at 04:34
  • @Phil I already injected the `$document` but im getting `$document.find is not a function`? – Linc Abela Jul 07 '15 at 04:38
  • 1
    @LincAbela that's odd, it's certainly there in my app. Can you show your code? You could also try `angular.element($document[0].body).on(...` – Phil Jul 07 '15 at 04:41
  • please show some code .. – Vinay Jul 07 '15 at 04:42
  • Why don't you try `angular.element(document.querySelector("body"))` – Vineet Jul 07 '15 at 04:48
  • Do you really need a controller there? I'd just use the `link` function and inject `$document` at the directive level. That's where you're meant to do DOM manipulation anyway – Phil Jul 07 '15 at 04:48
  • @Phil also no luck using `angular.element` im getting `Cannot read property 'body' of undefined` – Linc Abela Jul 07 '15 at 04:48
  • @Vineet because that's not testable – Phil Jul 07 '15 at 04:49
  • @Phil no, the controller not meant to manipulat dom - this is just special case, im just trying to get the element focus event. most of the code in the controller is not DOM manipulation – Linc Abela Jul 07 '15 at 04:50
  • @Phil, Will you please elaborate it for me ? Please. – Vineet Jul 07 '15 at 04:50
  • @LincAbela I'd still do that part in the `link` – Phil Jul 07 '15 at 04:51
  • @Vineet ive tried `angular.element(document.querySelector("body")).on('focus', function (e) { console.log("HIT ME"); });` no error but the focus event doesnt get hit – Linc Abela Jul 07 '15 at 04:51
  • 2
    Start from the beginning, what does: document.find('body') return? My guess is nothing b/c the controller is instantiated before the directive is attached to the DOM. Use the link function for this as suggested above. – Sunil D. Jul 07 '15 at 04:52
  • @Vineet global variables are difficult to mock and inject so it makes testing difficult. That's why Angular provides the [`$window`](https://docs.angularjs.org/api/ng/service/$window) service for example – Phil Jul 07 '15 at 04:52
  • Can I use `link` even with a controller? I just dont want to refactor much on this. Since I was just needed a simple stuff on the onfocus event. if you know what I mean – Linc Abela Jul 07 '15 at 04:53
  • @LincAbela yes, of course. See https://docs.angularjs.org/api/ng/service/$compile – Phil Jul 07 '15 at 04:53
  • Ok, ill try `link` @Phil thanks.. – Linc Abela Jul 07 '15 at 04:54
  • Thanks for your words @Phil – Vineet Jul 07 '15 at 04:55
  • if I use `link: function($scope, element, attr)` - how to call the `document.body.onfocus`? is the suggestions above still relevant? – Linc Abela Jul 07 '15 at 04:56

1 Answers1

3

Use the link / postLink function to perform DOM operations. For example

.directive('addPost', ['$document', '$log', function($document, $log) {
    return {
        // snip
        require: 'addPost',
        link: function postLink(scope, element, attr, addPostCtrl) {
            // scope is shared with the controller
            // you can also access properties on the controller itself
            // via addPostCtrl
            $document.find('body').on('focusin', function(e) {
                $log.debug('HIT ME!');
            });
        }
    };
}]);
Phil
  • 157,677
  • 23
  • 242
  • 245
  • Tried it. Somehow - The focus event doesn't get hit. – Linc Abela Jul 07 '15 at 05:04
  • @LincAbela do any *focus* events actually happen? – Phil Jul 07 '15 at 05:05
  • this is my use case, i have a `File Upload`, and I expect when I close the `file upload window`, it should hit the `document.body.focus` - I tested it via javascript and it does hit the focus event. just trying to implement it in angular. does that make sense? – Linc Abela Jul 07 '15 at 05:07
  • @LincAbela I don't think "focus" events propagate up to the body. See http://stackoverflow.com/questions/9577971/focus-and-blur-jquery-events-not-bubbling – Phil Jul 07 '15 at 05:08
  • hmmmm. But I tried in javascript a` – Linc Abela Jul 07 '15 at 05:10
  • Im using by the way. – Linc Abela Jul 07 '15 at 05:11
  • @LincAbela This is starting to sound like an [*XY problem*](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Perhaps you should go back to the start and describe what you're trying to do instead of how you think you should do it – Phil Jul 07 '15 at 05:11
  • I also mention there why I want it to access in the controller. because i am going to use the object inside the controller on the focus event. – Linc Abela Jul 07 '15 at 05:18
  • @LincAbela I've added some extra info about communicating with the controller – Phil Jul 07 '15 at 05:21
  • I see! now we just need to hit the `focus` event which is still im not succesfull – Linc Abela Jul 07 '15 at 05:22
  • @LincAbela did you try `focusin`? – Phil Jul 07 '15 at 05:22
  • no luck using `on("focus")` neither `on("focusin")` though :( – Linc Abela Jul 07 '15 at 05:23
  • yeah ive tried exactly what you suggest. but the focus event never gets hit when I open and close/cancel the fileupload - I am also expecting to hit it when I refresh the page. but the focus event never gets fired. – Linc Abela Jul 07 '15 at 05:25