Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs directive attribute binding of left and top position after dragging

I'm writing a directive for jqueryui draggable, but I'm having some trouble getting the left and top position to bind to my scope after dragging. Could someone point me in the right direction?

myApp.directive('draggable', function () {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        element.draggable({
            cursor: "move",
            stop: function (event, ui) {
                attrs.$set('xpos', ui.position.left);
            }
        });
    }
};
});

Here's a fiddle of what I'm trying to do: http://jsfiddle.net/psinke/TmQeL/

like image 965
Peter Sinke Avatar asked Jan 08 '13 14:01

Peter Sinke


1 Answers

Add to your directive:

scope: { xpos: '=', ypos: '=' },

The '=' syntax sets up two-way databinding between your isolate scope and the parent scope. Any changes you make to these isolate scope properties in your directive also affect the parent scope too, and vice versa.

Then in the linking function:

stop: function (event, ui) {
  scope.xpos = ui.position.left;
  scope.ypos = ui.position.top;
  scope.$apply();
  scope.$apply();
}

There is a currently a bug in Angular where you have to call $apply() twice if you're setting an attribute on an isolate scope property bound with =. See https://github.com/angular/angular.js/issues/1276

Update: @Peter noted in the comments that the above breaks moving the draggable via the input textboxes. I was unable to get it to work with an isolate scope, so I just had the directive use the parent scope (i.e., the directive does not create a new scope). I used attrs to modify the specified scope attribute in the stop() method. This works with multiple draggables on the same page.

stop: function (event, ui) {
   scope[attrs.xpos] = ui.position.left;
   scope[attrs.ypos] = ui.position.top;
   scope.$apply();
}

Fiddle.

like image 163
Mark Rajcok Avatar answered Sep 29 '22 12:09

Mark Rajcok