0

Here is the view

.container(ng-controller="activityCtrl")
  h3 Edit your plan
  .row
    .one-half.column
      div(draggable="true" ondragstart="onDrag()") I am draggable

And i have defined a function inside controller like

$scope.onDrag = (evt)=>{
  console.log(evt);
  ev.dataTransfer.setData("text", ev.target.id);
}

The error that i am getting is Reference error onDrag not defined. I am guessing that it is somewhat because i need to reference the function defined in $scope in ondragstart. How can i do the same ?

3
  • If you are manipulating DOM You should use Directives in angularJS Commented Feb 25, 2017 at 12:19
  • check my answer Commented Feb 25, 2017 at 12:38
  • Anyone got the answer for Angular (v2+) ? Commented Jan 20, 2018 at 21:04

2 Answers 2

11

You are getting the error Reference error onDrag not defined because you're referencing a function in HTML5 event which is defined in Angular's scope.

If you really want to access $scope.onDrag function in ondragstart event, change your html like below:

div(draggable="true" ondragstart="angular.element(this).scope().onDrag()") I am draggable

Ideally angular.element(this).scope() would be used for debugging purpose so I would prefer to write a directive for drag and drop.


Below is the HTML5 drag and drop implementation in AngularJS.
I've replicated the same behavior as shown in w3schools.

Since you are manipulating DOM you should use directives in AngularJS.

I've implemented two directives

  • drag-me for drag
  • drop-me-on for drop.

You could also use single directive for both, however I prefer separation of concerns.

HTML:

<div id="div1" drop-on-me>
  <img src="https://www.w3schools.com/html/img_w3slogo.gif" drag-me  id="drag1" width="88" height="31">
</div>

<div id="div2" drop-on-me></div>

JS

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

angular
  .module('myApp')
  .directive('dragMe', dragMe)
  .directive('dropOnMe', dropOnMe);

dragMe.$inject = [];

function dragMe() {
  var DDO = {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.prop('draggable', true);
      element.on('dragstart', function(event) {
        event.dataTransfer.setData('text', event.target.id)
      });
    }
  };
  return DDO;
}
dropOnMe.$inject = [];
function dropOnMe() {
  var DDO = {
    restrict: 'A',
    link: function(scope, element, attrs) {
      element.on('dragover', function(event) {
        event.preventDefault();
      });
      element.on('drop', function(event) {
        event.preventDefault();
        var data = event.dataTransfer.getData("text");
        event.target.appendChild(document.getElementById(data));
      });
    }
  };
  return DDO;
}

DEMO

Have a look at my fiddle

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

5 Comments

I occasionally see a great and well laid out answer like this one :D
I implemented these two directives and I tried to use it on the cells of a table, but event.srcElement seems to be undefined. event.dataTransfer.setData also does not work. Why is that?
@Adi Which browser are you using?
@Adi try to create a plunker/fiddle so that I can look into it!
I managed to do it, finnaly. There is a known problem with jQuery. I found the workaround here: jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop
0

OnDragStart is not something from the angular context, so you can't use functions defined in $scope or in your controller.

You could use some third party libraries like angular-dragdrop or ui-sortable or roll your own (see How to Create simple drag and Drop in angularjs for more details).

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.