Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drag and Drop using AngularJS (with or without jQuery), how?

what i want to do is exactly this , but that is in jQuery and i want to know if is there a way to do that in AngularJS, or if someone has alredy done it with the Angular way, and if not, how it suppouse that Angular allows you to customize directives to solve this kind of problems.

I know to use jQuery but i want to move on into AngularJS and its very confusing, so i'm sorry if my question isn't good enough, but all what i've found is this and that doesn't help at all. I'd really apreciate any advice you can say me about this.

like image 808
Rubén Marrero Avatar asked Feb 25 '14 00:02

Rubén Marrero


People also ask

What is AngularJS used for?

AngularJS is a structural framework for dynamic web apps. It lets you use HTML as your template language and lets you extend HTML's syntax to express your application's components clearly and succinctly. AngularJS's data binding and dependency injection eliminate much of the code you would otherwise have to write.


2 Answers

Here is how I did it, it is a little more complicated, since I included the ability to add event handlers (start, drag, stop), and a container element. Here is a working fiddle for demonstration JSFiddle Without jQuery. Here is another fiddle with a version using jQuery and jQueryUI [JSFiddle w/ jQuery]. Hope it helps. JSFiddle With jQuery and jQueryUI.

You can use it like this

ng-draggable='dragOptions'

where in your controller you have

$scope.dragOptions = {
    start: function(e) {
      console.log("STARTING");
    },
    drag: function(e) {
      console.log("DRAGGING");
    },
    stop: function(e) {
      console.log("STOPPING");
    },
    container: 'container-id'
}

Here is the directive.

.directive('ngDraggable', function($document) {
  return {
    restrict: 'A',
    scope: {
      dragOptions: '=ngDraggable'
    },
    link: function(scope, elem, attr) {
      var startX, startY, x = 0, y = 0,
          start, stop, drag, container;

      var width  = elem[0].offsetWidth,
          height = elem[0].offsetHeight;

      // Obtain drag options
      if (scope.dragOptions) {
        start  = scope.dragOptions.start;
        drag   = scope.dragOptions.drag;
        stop   = scope.dragOptions.stop;
        var id = scope.dragOptions.container;
        container = document.getElementById(id).getBoundingClientRect();
      }

      // Bind mousedown event
      elem.on('mousedown', function(e) {
        e.preventDefault();
        startX = e.clientX - elem[0].offsetLeft;
        startY = e.clientY - elem[0].offsetTop;
        $document.on('mousemove', mousemove);
        $document.on('mouseup', mouseup);
        if (start) start(e);
      });

      // Handle drag event
      function mousemove(e) {
        y = e.clientY - startY;
        x = e.clientX - startX;
        setPosition();
        if (drag) drag(e);
      }

      // Unbind drag events
      function mouseup(e) {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
        if (stop) stop(e);
      }

      // Move element, within container if provided
      function setPosition() {
        if (container) {
          if (x < container.left) {
            x = container.left;
          } else if (x > container.right - width) {
            x = container.right - width;
          }
          if (y < container.top) {
            y = container.top;
          } else if (y > container.bottom - height) {
            y = container.bottom - height;
          }
        }

        elem.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }
    }
  }

})
like image 170
Zack Argyle Avatar answered Oct 07 '22 21:10

Zack Argyle


Best example of Drag and Drop using AngularJS. Designed with easy steps.

First of all define anguler application (ng-app) name, define two directives and one controller as mentioned below. Also apply some css which will improve a look and feel of html

Just run the snippet and enjoy the coding.

var module = angular.module('my-app', []);

module.directive('draggable', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      element[0].addEventListener('dragstart', scope.handleDragStart, false);
      element[0].addEventListener('dragend', scope.handleDragEnd, false);
    }
  }
});

module.directive('droppable', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      element[0].addEventListener('drop', scope.handleDrop, false);
      element[0].addEventListener('dragover', scope.handleDragOver, false);
    }
  }
});

function MainController($scope)
{
    $scope.drag_types = [
        {name: "Charan"},
        {name: "Vijay"},
        {name: "Mahesh"},
      {name: "Dhananjay"},
    ];
    $scope.items = [];
    
    $scope.handleDragStart = function(e){
        this.style.opacity = '0.4';
        e.dataTransfer.setData('text/plain', this.innerHTML);
    };
    
    $scope.handleDragEnd = function(e){
        this.style.opacity = '1.0';
    };
    
    $scope.handleDrop = function(e){
        e.preventDefault();
        e.stopPropagation();
        var dataText = e.dataTransfer.getData('text/plain');
        $scope.$apply(function() {
            $scope.items.push(dataText);
        });
        console.log($scope.items);
    };
    
    $scope.handleDragOver = function (e) {
        e.preventDefault(); // Necessary. Allows us to drop.
        e.dataTransfer.dropEffect = 'move';  // See the section on the DataTransfer object.
        return false;
  };
           
}
.container {
  width: 600px;
  border: 1px solid #CCC;
  box-shadow: 0 1px 5px #CCC;
  border-radius: 5px;
  font-family: verdana;
  margin: 25px auto;
}

.container header {
  background: #f1f1f1;
  background-image: -webkit-linear-gradient( top, #f1f1f1, #CCC );
  background-image: -ms-linear-gradient( top, #f1f1f1, #CCC );
  background-image: -moz-linear-gradient( top, #f1f1f1, #CCC );
  background-image: -o-linear-gradient( top, #f1f1f1, #CCC );
  box-shadow: 0 1px 2px #888;
  padding: 10px;
}

.container h1 {
  padding: 0;
  margin: 0;
  font-size: 16px;
  font-weight: normal;
  text-shadow: 0 1px 2px white;
  color: #888;
  text-align: center;
}

.container section {
  padding: 10px 30px; 
  font-size: 12px;
  line-height: 175%;
  color: #333;
}
<script src="http://code.angularjs.org/1.2.13/angular.js"></script>
<div ng-app="my-app" ng-controller="MainController">
    <div class="container">
        <header><h1>Drag students from here</h1></header>
        <section>
            <div draggable="true" ng-repeat="drag_type in drag_types">{{drag_type.name}}</div>
        </section>
    </div>
    <div class="container">
        <header><h1>Drop students here</h1></header>
        <section droppable="true">
            <div><span>You dragged in: </span>
                <span ng-repeat="name in items track by $index">
                    <span ng-show="$index != 0">,</span>
                    {{name}}
                </span>
            </div>
        </section>
    </div>
    
     See the JSON: <pre>{{items|json}}</pre>
</div>
like image 6
Charan Ghate Avatar answered Oct 07 '22 22:10

Charan Ghate