Popup dialog that follow the mouse in AngularJS

I’m using Angular 1.0.6 and jQuery and I need to create a hint that will follow the mouse (change position). What I have so far is the show/hide:

<div ng-repeat="item in items">
    <span ng-mouseover="item.show_description=true" ng-mouseleave="item.show_description=false">
       {{item.text}}
    </span>
    <div class="description-popup" ng-show="item.description && item.show_description">
       {{item.description}}
    </div>
</div>

How should I change x and y position of the popup depend on mousemove event? I was thinking that I could have something like this:

<div pointer="{x: item.x, y: item.y}">Hello</div>
<div class="popup" style="left: {{item.x}}; top: {{item: y}}">
  Popup
</div>

But don’t know how to create directive like this.

Answer

I came up with this utility that can be used as a service (it require $parse):

function objectParser(expr) {
    var strip = expr.replace(/s*{s*|s*}s*/g, '');
    var pairs = strip.split(/s*,s*/);
    if (pairs.length) {
        var getters = {};
        var tmp;
        for (var i=pairs.length; i--;) {
            tmp = pairs[i].split(/s*:s*/);
            if (tmp.length != 2) {
                throw new Error(expr + " is Invalid Object");
            }
            getters[tmp[0]] = $parse(tmp[1]);
        }
        return {
            assign: function(context, object) {
                for (var key in object) {
                    if (object.hasOwnProperty(key)) {
                        if (getters[key]) {
                            getters[key].assign(context, object[key]);
                        }
                    }
                }
            }
        }
    }
}

This function will parse values from object (string) as scope values, and returned object will allow to change those values based on other object. It can be used in directive like this:

{
    restrict: 'A',
    link: function(scope, element, attrs) {
        var expr = objectParser(attrs.pointer);
        element.mousemove(function(e) {
            var offest = element.offset();
            scope.$apply(function() {
                expr.assign(scope, {
                    x: e.pageX - offest.left,
                    y: e.pageY - offest.top
                });
            });
        });
    }
};

Leave a Reply

Your email address will not be published. Required fields are marked *