1

I have edited my code to extract only the required parts to make this question easier to understand. The whole code is big as it is a copy of an existing system and there would be too much code to read through.

So - in a nutshell, I have a webpage where I use jQuery hover() and jQueryContextMenu plugin.

My HTML page used to look like this:

<?php
foreach($characters as $character) {
  echo "<div class='player'>";
    echo "<div>". $character->name. "</div>"; //other character attributes
  echo "</div>";
}
?>

My hover function looks like this:

$('.player').hover(
    function(){
        $(this).addClass('hovering');
        alert("Class added");
    },
    function(){
        $(this).removeClass('hovering');
        alert("Class removed")
    }
);

This used to work just fine. I am now learning Angular and I decided to change my HTML to be loaded using AngularJS:

<div ng-controller="playerController">
  <div class='player' ng-repeat="character in characters">
      <div>{{character.name}}</div> //..and other character attributes
  </div>
</div>

I also have a playerController that fetches data from my php backend and converts it into a JSON that Angular consumes.

All of this works fine too.I get the player list and my context menu works as well, I can right click and perform actions.

ONLY my hover() function does not work! If I do a console.log($('.player').length) it prints 0. The context Menu Plugin is also bound to this same class but it works just fine:

$.contextMenu({
    selector: '.player',
    trigger: 'right',
    ... other options

I read that this could be because I have to bind the event since the DOM element is built by Angular. So I tried below two steps also without any luck (I tried click event for testing, in order to make it simple:

$(document).bind("click",".player",function(){alert("hi")});

$(document).on("click",".player",function(){alert("hi")});

I tried variations:

$('.player').bind("click",function(){alert("hi")});

$('.player').on("click",function(){alert("hi")});

All of these I tried in the ready() function of jQuery but did not work. (No alerts were shown).

Finally I wrapped these two statements inside a function named jQueryInit() and I tried triggering these two functions from AngularJS like so:

playerController:
... //other lines of code
$scope.$on('$viewContentLoaded', jqueryInit); 

But that didnt work either. So I am here, hoping someone will show me what is going on here, because I am pretty much clueless at the moment...

Undefined Variable
  • 4,196
  • 10
  • 40
  • 69

1 Answers1

4

You'll need to move the JQuery code to a directive:

directive('customHover', function () {
return {
    link: function (scope, element, attr) {
        element.hover(
 function () {
     $(this).addClass('hovering');
     alert("Class added");
 },
 function () {
     $(this).removeClass('hovering');
     alert("Class removed")
 }
 );
    }
}
});

And then use it like this:

<div ng-controller="playerController">
<div custom-hover ng-repeat="character in characters">
  <div>{{character.name}}</div> //..and other character attributes
</div>
</div>

Update: I created a jsFiddle

JoMendez
  • 880
  • 9
  • 22
  • Awesome! that worked!!Thank you, kind sir...you really did put a smile on my face :) Now let me go and read more on directives and links... – Undefined Variable Nov 05 '15 at 20:19
  • I have a question: Does the `element` variable represent a jquery object? As in, can I run `element.jqueryFunctions()` on it? – Undefined Variable Nov 05 '15 at 20:23
  • The `element` variable is a JQuery Lite element, meaning it is a lite version of Jquery, it doesn't contain all the JQuery functions – JoMendez Nov 05 '15 at 20:27
  • Thank you very much! I have one more question... In the HTML, in the div I have an attribute like `data-style={{player.style}}`. In the link function do you know how I can get its value? If I alert `element.attr('data-style')` it just prints `{{player.style}}`...Because what i want to do is, on mouseout get this data-style and apply it back to the div... – Undefined Variable Nov 05 '15 at 20:38
  • You can use `data-style=player.style` without {{}} and the get it with the `scope` instead of the `attr` I updated the [jsFiddle](http://jsfiddle.net/cuzzfxnp/27/) – JoMendez Nov 05 '15 at 20:49
  • I got it working :) But I am worried a bit about Angular now...it just seems too complex... I am wondering if I will hit more roadblocks if I continue down this path... – Undefined Variable Nov 05 '15 at 21:03