AngularJS module for jQueryUI draggable and droppable


Last year, I played a lot with jQueryUI and mostly draggable/droppable along with AngularJS and it was a bit of a pain so I decided to write a directive for it which should make it easy for others to implement such functionalities.

Demos and much more

http://codef0rmer.github.com/angular-dragdrop/#/

Fork it on Github

https://github.com/codef0rmer/angular-dragdrop

and written test cases also 🙂
https://github.com/codef0rmer/angular-dragdrop/blob/master/test/index.html

Good Night!

If you found this article useful in anyway, feel free to donate me and receive my dilettante painting as a token of appreciation for your donation.

61 thoughts on “AngularJS module for jQueryUI draggable and droppable

  1. I get a “Error: Argument ‘oneCtrl’ is not a function, got undefined” when I define the controller as
    App.controller(‘oneCtrl’, function($scope, $timeout) {……

    But when I change it to
    var ExploreController = [‘$scope’,’$http’, ‘$timeout’, function($scope,$http,$timeout){….
    the error goes away, but the drag n drop does not work.. I am sure i am doing a rookie mistake.. any advice?

  2. Sorry, I meant var oneCtrl = [‘$scope’,’$http’, ‘$timeout’, function($scope,$http,$timeout){….
    in the previous line..

  3. Great module, exactly what I was looking for! The clone on the shopping cart demo isn’t working, do you know a quick fix for that before I dive into your code? Thanks!

  4. Thanks Amit! Its working good!
    I have one query. The animation doesn’t seems to work with table rows (by animation I mean, the dragged row should be moveable). The action drag does affect the model though and the swap happens. I am using this snippet:

    Thanks

  5. Thanks Amit. I need some Help. I wanted to store the Sequence of Drag & Drop Element in Database. Can U Explain that How Can i Solve the Problem?

    • Offcourse! jqyoui-draggable takes onDrop callback which triggers when a draggable is dropped inside some droppable area. In onDrop callback, just get the updated model data and store it in DB.

      • Hey swarup, all callbacks give access to event and ui objects so you can just grab the updated list using $scope.list1(draggable list) and $scope.list2(droppable list).

        Also using ui object in dropCallback, you can grab the draggable’s model with “angular.element(ui.draggable).scope().item” or the parent scope “angular.element(ui.draggable).scope().$parent” that lists all the models bound to the scope – list1 and list2 in this case.

        Hope this helps!

      • I think I’m Very Confused. Because It’s doesn’t work. Ok Will Show u The Code. & After that U Suggest Me.
        hello.js is my js File:-

        var App = angular.module(‘drag-and-drop’, [‘ngDragDrop’]);
        App.controller(‘oneCtrl’, function($scope, $timeout) {
        $scope.details = [{name:’John’, address:’New Town’, phone:’555-1276′},
        {name:’Mary’, address:’Old Town’, phone:’800-BIG-MARY’}];

        & Hello.html is my html File:-

        User Details 1

        {{info.name}}
        {{info.address}}
        {{info.phone}}

        I want to Store the Sequence of values… If I Arrange the Sequence . then Sequence will be store. I try But It Doesn’t working. & I’m New in JavaScript. So Please Help me…

      • I Don’t know Why Html File is not Display. Ok. My HTML has a Table where I want to arrange the Table Row Value & Store the Sequence of Table Row…
        On Table Tag I Defined
        data-drop=”true” ng-model=’details’ jqyoui-droppable=”{multiple:true}”
        & On Table Row Tag I Defined
        ng-repeat=’info in details’ data-drag=”true” data-jqyoui-options=”{revert: ‘invalid’, helper: ‘clone’}” ng-model=”details” jqyoui-draggable=”{index: {{$index}}, animate: true}”
        Now Tell Me What I’ll do???

  6. Is there a way for the Droppable to veto the drop. I had hoped that the overCallback or dropCallback could return true or false to indicate whether the drop is allowed or not. Is there another way?

      • Exactly – I have a list from which I drag and I drop into one or more containers. Items from the list can be dragged to one or more containers, i.e. the item in the list must remain after being dragged to one container to enable dragging to a second or third container. All that works. The restriction I now need is that an item from the list must only be dropped once into each container.

  7. I am trying to stay in the Angular “world” (I get the feeling that I need to drop into DOM territory if I am using “accept”) hence it would be nice if the callback methods could be used to indicate whether the item could be dropped or not.

  8. Thanks again for your reply – I tried the “accept” option and it works fine.
    Just one more thing – the source list contains one type of JSON objects while the destination lists should contain a different type of JSON objects that would contain some information from the source object. I guess I could do some object swapping in the “drop” callback, but is there a better way? Maybe a transformation “hook” just before the source object is added to the destination list, e.g. a “about-to-drop” callback.

    • Before drop event is not supported by jQueryUI as of now. onDrop callback is an ideal place to do some post drop stuff. May be you could send a PR to jQueryUI project on github to propose ‘beforeDrop’ callback.

  9. Amit, good job with the drag and drop directive. Do you have a demo any where which shows the onDrop implementation? For me, the code cannot find the bound event handler in the scope.

  10. do you have any example where you can drag one item inside a drop zone and then use this as a group that you can drag and drop into a new drop zone?

  11. Hey codeformer, loving the module! If this works, it will make my transition from jQuery to Angular much smoother. I am just running into one snag.

    The objects I am dragging are in scrollable divs, and I need to drag them into other scrollable divs. When I attempt to do this, they can’t be dragged outside of their parent.

    In data-jqyoui-options, I have tried setting options for containment, but the setting isn’t being honored. I have also tried to define a helper function in the jQuery options, but the helper function isn’t being linked… the code inside the function never fires.

    Have you encountered this before? Do you know of any workarounds?

    • Never mind, I figured it out… Containment had nothing to do with it.

      The answer is in figuring out why the helper function wasn’t firing. The module uses $scope.eval() to evaluate the attribute, which means the function must be visible using $scope.eval().

      Just in case anybody else has this issue, here is how I did it:

      1) place an empty in the document root.

      2) in your VM, be sure to attach the helper function to the VM.

      vm.draghelper = function(event){
      return $(event.target).parents(‘div.address’).clone()
      .insertAfter($(“#dragdrop_element_helper”));
      }

      3) If you use Controller As, be sure to include that in the directive attribute:

      data-jqyoui-options=”{revert: ‘invalid’, containment: ‘window’, opacity: 0.35, helper: addressVm.draghelper}”

  12. I really liked your idea. Did you ever try to hookup ngDragDrop with requireJs?? I am getting an error while hooking up with requirejs
    error is

    TypeError: undefined is not a function
    at angular.module.service.directive.link.updateDraggable

  13. Hi There CodeFormer.

    Great module, thank you so much for creating this. I am using the shopping carrt example and I want to remove the items in my cart I I added too many of one thing. How can I do that?

    On my controller I have this
    $scope.fadeOut = function ($event) {
    $event.preventDefault();
    $event.stopPropagation();
    // make it fade away and remove it from the list
    }

    Then On the Html I have this

    {{item.title}}

  14. Now I can do drag and drop using html table as below, but i want to replace the value where i drop not duplicates the values in target table.

    Help is really appreciated

  15. I am in same boat as @Ace here. In your demo of shopping cart, you allow user to add items to shopping cart. That’s fine. But what if user want to remove item from the shopping cart using drag & drop. Currently, in your demo, it doesn’t allow to remove an item from shopping cart. Is there any way to do it?

    • That’s because I’ve jqyoui-draggable="{placeholder: 'keep'}". If you remove the placeholder option, the dragged item will be removed from the source list once dropped.

      • Looks like you didn’t got my point i guess. I want to remove item from “shopping cart” – right section of of your demo. I don’t want remove item from product list.

      • Ohk. Again it’s because there is no drop region other than the right section. So you need to make the left sections droppable to make it work.

  16. But when i do that in angularjs app, the item which is dragged from shopping cart is getting added to left section or shows a duplicate item angularjs error. I only want to remove the item from shopping cart when user drags it out from shopping

  17. Hello codef0rmer
    How can i restrict a draggable to be dropped only once on the drop zone.

    Basically I need to get the data which i am dragging and then do some evaluation between current data which is available on the drop zone and the data which i am dragging and then allow the dragged item to be dropped on the drop zone

    Please help

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.