risinghero / angular-drag-and-drop-lists

Angular directives for sorting nested lists using the HTML5 Drag & Drop API

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

angular-drag-and-drop-lists

Angular directives that allow you to build sortable lists with the native HTML5 drag & drop API. The directives can also be nested to bring drag & drop to your WYSIWYG editor, your tree, or whatever fancy structure you are building.

Demo

Supported browsers

Implementation for all (including touch) devices

Internet Explorer 8 or lower is not supported, but all modern browsers are (see changelog for list of tested browsers).

Download & Installation

  • Download angular-drag-and-drop-lists.js (or the minified version) and include it in your application. If you use bower or npm, just include the angular-drag-and-drop-lists package.
  • Add the dndLists module as a dependency to your angular app.

dnd-draggable directive

Use the dnd-draggable directive to make your element draggable

Attributes

  • dnd-draggable Required attribute. The value has to be an object that represents the data of the element. In case of a drag and drop operation the object will be serialized and unserialized on the receiving end.
  • dnd-disable-if You can use this attribute to dynamically disable the draggability of the element. This is useful if you have certain list items that you don't want to be draggable, or if you want to disable drag & drop completely without having two different code branches (e.g. only allow for admins). Note: If your element is not draggable, the user is probably able to select text or images inside of it. Since a selection is always draggable, this breaks your UI. You most likely want to disable user selection via CSS (see user-select). Demo

Callbacks

  • dnd-moved Callback that is invoked when the element was moved. Usually you will remove your element from the original list in this callback, since the directive is not doing that for you automatically. The original dragend event will be provided in the local event variable. Demo
  • dnd-canceled Callback that is invoked if the element was dragged, but the operation was canceled and the element was not dropped. The original dragend event will be provided in the local event variable. Demo
  • dnd-dragstart Callback that is invoked when the element was dragged. The original dragstart event will be provided in the local event variable. Demo
  • dnd-dragend Callback that is invoked when the drag operation ended. Available local variables are event and dropEffect. Demo
  • dnd-selected Callback that is invoked when the element was clicked but not dragged. The original click event will be provided in the local event variable. Demo

CSS classes

  • dndDragging This class will be added to the element while the element is being dragged. It will affect both the element you see while dragging and the source element that stays at it's position. Do not try to hide the source element with this class, because that will abort the drag operation.

dnd-list directive

Use the dnd-list attribute to make your list element a dropzone. Usually you will add a single li element as child with the ng-repeat directive. If you don't do that, we will not be able to position the dropped element correctly. If you want your list to be sortable, also add the dnd-draggable directive to your li element(s). Both the dnd-list and it's direct children must have position: relative CSS style, otherwise the positioning algorithm will not be able to determine the correct placeholder position in all browsers.

Attributes

  • dnd-list Required attribute. The value has to be the array in which the data of the dropped element should be inserted.
  • dnd-horizontal-list Optional boolean expression. When it evaluates to true, the positioning algorithm will use the left and right halfs of the list items instead of the upper and lower halfs. Demo

Callbacks

  • dnd-dragover Optional expression that is invoked when an element is dragged over the list. If the expression is set, but does not return true, the element is not allowed to be dropped. The following variables will be available:
    • event The original dragover event sent by the browser.
    • index The position in the list at which the element would be dropped.
    • type The dnd-type set on the dnd-draggable, or undefined if unset.
    • external Whether the element was dragged from an external source. See dnd-external-sources.
    • Demo
  • dnd-drop Optional expression that is invoked when an element is dropped on the list.
    • The following variables will be available:
      • event The original drop event sent by the browser.
      • index The position in the list at which the element would be dropped.
      • item The transferred object.
      • type The dnd-type set on the dnd-draggable, or undefined if unset.
      • external Whether the element was dragged from an external source. See dnd-external-sources.
    • The return value determines the further handling of the drop:
      • false The drop will be canceled and the element won't be inserted.
      • true Signalises that the drop is allowed, but the dnd-drop callback will take care of inserting the element.
      • Otherwise: All other return values will be treated as the object to insert into the array. In most cases you simply want to return the item parameter, but there are no restrictions on what you can return.
  • dnd-inserted Optional expression that is invoked after a drop if the element was actually inserted into the list. The same local variables as for dnd-drop will be available. Note that for reorderings inside the same list the old element will still be in the list due to the fact that dnd-moved was not called yet. Demo

CSS classes

  • dndPlaceholder When an element is dragged over the list, a new placeholder child element will be added. This element is of type li and has the class dndPlaceholder set. Alternatively, you can define your own placeholder by creating a child element with dndPlaceholder class.
  • dndDragover This class will be added to the list while an element is being dragged over the list.

Demo

Required CSS styles

Both the dnd-list and it's children require relative positioning, so that the directive can determine the mouse position relative to the list and thus calculate the correct drop position.

ul[dnd-list], ul[dnd-list] > li {
    position: relative;
}

Why another drag & drop library?

There are tons of other drag & drop libraries out there, but none of them met my three requirements:

  • Angular: If you use angular.js, you really don't want to throw a bunch of jQuery into your app. Instead you want to use libraries that were build the "angular way" and support two-way data binding to update your data model automatically.
  • Nested lists: If you want to build a WYSIWYG editor or have some fancy tree structure, the library has to support nested lists.

If this doesn't fit your requirements, check out one of the other awesome drag & drop libraries:

  • angular-ui-tree: Very similar to this library, but does not use the HTML5 API. Therefore you need to write some more markup to see what you are dragging and it will create another DOM node that you have to style. However, if you plan to support touch devices this is probably your best choice.
  • angular-dragdrop: One of many libraries with the same name. This one uses the HTML5 API, but if you want to build (nested) sortable lists, you're on your own, because it does not calculate the correct element position for you.
  • more...

License

Copyright (c) 2014 Marcel Juenemann

Copyright (c) 2014-2016 Google Inc.

This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.

MIT License

About

Angular directives for sorting nested lists using the HTML5 Drag & Drop API

License:MIT License


Languages

Language:TypeScript 56.2%Language:JavaScript 42.3%Language:HTML 1.5%