Home

Awesome

ember-sortablejs

Build Status Ember Observer Score

This addon allows you to use drag and drop in your ember application using SortableJS/Sortable

Compatibility

Installation

NOTE: The beta version is out. Please give me a hand and test it out.

ember install ember-sortablejs@beta

This addon has a peer dependency on sortablejs that will be installed with the addon

Still to do

Refer to the upcoming project

Library support

Currently supported:

Usage

{{!-- this.list = [{ name: 'item one' }, { name: 'item two' },..]  --}}
<SortableJs
  @items={{this.list}}
  @options={{hash animation=150 ghostClass="ghost-class" group="shared-list"}}
  @onStart={{this.onStart}}
  @onEnd={{this.onEnd}}
  as |list|
>
  {{#each list as |item|}}
    <div class="list-group-item bg-yellow">{{item.value.name}}</div>
  {{/each}}
</SortableJs>

How it works

SortableJs works by manipulating the DOM directly this is NOT compatible with the Glimmer VM. To mitigate this we need tu use SortableJs as a middle man and use the events it emits to update state and prevent the DOM manipulation the library does.

This is accomplished by maintaining an internal list. This list is a copy of the array supplied via @items. The events onStart, onEnd, onUpdate, onAdd, onRemove are intercepted to prevent DOM manipulation and maintaining the internal list.

You HAVE to provide an object. As the addon uses a WeakMap to cache the items supplied. When SortableJs emits we update the list and the cache to make changes that will update the DOM. The addon will yield an array of objects. Each object contains the key value, which is the original object supplied via @items.

I you have ideas on how to approach this better. Please open an issue 😄

Caveats

Options

The addon supports all the options that sortable accepts, see: https://github.com/SortableJS/Sortable#options

Component API

argtypedescription
@itemsArray<Object>A list of objecs to be managed by the addon
@optionsObjectA hash options supported by SortableJs
@tagStringThe element to be used to render the list (default: "div")
@onChooseFunction(SortablejsEvent) => {...}
@onUnchooseFunction(SortablejsEvent) => {...}
@onStartFunction(SortablejsEvent) => {...}
@onEndFunction(SortablejsEvent, cancelDnD) => {...}
@onAddFunction(SortablejsEvent) => {...}
@onUpdateFunction(SortablejsEvent) => {...}
@onSortFunction(SortablejsEvent) => {...}
@onRemoveFunction(SortablejsEvent) => {...}
@onMoveFunction(SortablejsMoveEvent) => {...}
@onCloneFunction(SortablejsEvent) => {...}
@onChangeFunction(SortablejsEvent) => {...}
@scrollFnFunction(SortablejsEvent) => {...}
@setDataFunction(SortablejsEvent) => {...}
@onFilterFunction(SortablejsEvent) => {...}
@onSpillFunction(SortablejsEvent) => {...}

SortablejsEvent - A CustomEvent provided by SortableJS

SortablejsMoveEvent - A CustomEvent provided by SortableJS

cancelDnD - A callback provided by the ember addon to basically undo you last drag and drop or sort;

{{yield}} - An array of objects with the key value where its value is the object supplied. { value: <Object> }

Migrating from 1.x

v1

<SortableJs
  @options={{hash animation=150 ghostClass="ghost-class" group="shared-list"}}
>
  <ul class="list-group">
    <li class="list-group-item">Item 1</li>
    <li class="list-group-item">Item 2</li>
    <li class="list-group-item">Item 3</li>
    <li class="list-group-item">Item 4</li>
    <li class="list-group-item">Item 5</li>
  </ul>
</SortableJs>

v2

{{!-- this.list = [{ name: 'item one' }, { name: 'item two' },..]  --}}
<SortableJs
  class="list-group"
  @items={{this.list}}
  @options={{hash animation=150 ghostClass="ghost-class" group="shared-list"}}
  as |list|
>
  {{#each list as |item|}}
    <div class="list-group-item">{{item.value.name}}</div>
  {{/each}}
</SortableJs>

License

This project is licensed under the GPL-3.0 License.