tobento / js-sortable
A simple and lightweight JavaScript library for reorderable drag-and-drop lists or items.
Installs: 1
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:JavaScript
README
A simple and lightweight JavaScript library for reorderable drag-and-drop lists or items. It uses the HTML Drag and Drop API which is sadly not supported by touch devices.
You may visit the docs.tobento.ch/js-sortable page for demo.
Table of Contents
Getting started
Browser support
Modern browser only. No touch devices.
Documentation
Basic Usage
1. Include JS
<script src="sortables.js" type="module"></script>
2. Register
Use the data-sortable
attribute to automatically register a sortable.
<ul data-sortable='{"id": "uniqueID", "selector": "li", "nestable": true}'> <li><div class="box">1 - List Item</div></li> <li><div class="box">2 - List Item</div></li> <li><div class="box">3 - List Item</div></li> <li><div class="box">4 - List Item</div></li> <li><div class="box">5 - List Item</div> <ul> <li><div class="box">5.1 - List Item</div></li> <li><div class="box">5.2 - List Item</div></li> </ul> </li> <li><div class="box">6 - List Item</div></li> <li><div class="box">7 - List Item</div></li> <li><div class="box">8 - List Item</div></li> </ul> <div data-sortable='{"id": "cards", "selector": ".card", "handle": ".handle"}'> <div class="card">1 - Card<span class="handle">Drag</span></div> <div class="card">2 - Card<span class="handle">Drag</span></div> <div class="card">3 - Card<span class="handle">Drag</span></div> <div class="card">4 - Card<span class="handle">Drag</span></div> </div>
Thats all.
You may get the sorted items
<script type="module"> import sortables from "sortables.js"; document.addEventListener('DOMContentLoaded', (e) => { const items = sortables.get('uniqueID').items(); // or using the drop event sortables.get('uniqueID').listen('drop', (event, sortable) => { const items = sortable.items(); }); }); </script>
Manually creating
Instead of using the data-sortable
attribute to register the sortable automatically, you can create sortables manually by using the create
function:
<script type="module"> import sortables from "sortables.js"; document.addEventListener('DOMContentLoaded', (e) => { // create it manually: const sortable = sortables.create(document.querySelector('#container'), { id: 'uniqueID', selector: '.item' }); // you may get the sorted items using the drop event: sortable.listen('drop', (event, sortable) => { const items = sortable.items(); }); }); </script>
Options
<ul data-sortable='{"id": "uniqueID", "selector": "li", "nestable": true, "handle": ".drag"}'>
Option | Value | Description |
---|---|---|
"id" |
"ID" |
A unique id. |
"selector" |
".item" |
The items selector |
"nestable" |
true or false |
When true, items can be nested if "li" selector. But you may set to false if you want only a one depth list. (optional) |
"handle" |
.handle |
A handle selector to drag items only with. (optional) |
"allow" |
["id", "anotherId"] |
You may set the allowed ids to be sorted within. (optional) |
"clone" |
true or false |
When true, the drag item will be cloned. (optional) |
"ghost" |
true or false |
When false, the ghost image will not be displayed. (optional) |
Methods
<script type="module"> import sortables from "sortables.js"; document.addEventListener('DOMContentLoaded', (e) => { // create a sortable object: const sortable = sortables.create(document.querySelector('#container'), { id: 'ID', selector: '.item' }); // you may get a sortable object by id: const sortable = sortable.get('ID'); // you may check if a sortable object exists: if (sortable.has('ID')) { // } // you may get the sortable items: const items = sortable.items(); // you may delete a sortable: sortables.delete('ID'); // you may register newly added sortables with the data-sortable attribute: sortables.register(); }); </script>
Events
Event | Description |
---|---|
dragstart |
This event is fired when the user starts dragging an element. |
dragend |
This event is fired when a drag operation ends. |
dragover |
This event is fired when an element is being dragged over a valid drop target. |
dragleave |
This event is fired when a dragged element leaves a valid drop target. |
drop |
This event is fired when an element is dropped on a valid drop target. |
sortables.get('uniqueID').listen('drop', (event, sortable) => { const items = sortable.items(); });
Learn More
Updating A Sortable List
This example shows a possible way to update a reoredered list.
<script type="module"> import sortables from "sortables.js"; document.addEventListener('DOMContentLoaded', (e) => { const sortable = sortables.get('list'); sortable.listen('drop', (event, sortable) => { // Get the ul element where the item was dropped: const ul = sortable.draggable.closest('ul'); // Determine the parent id: let parentId = 0; const parent = ul.parentNode; if (parent && parent.hasAttribute('data-id')) { parentId = parent.getAttribute('data-id'); } // Get only those li elements within the current ul element (without children): const items = ul.querySelectorAll(':scope > li'); // Build your data structure to update your items using the Fetch API. const data = {}; const length = items.length; for (let i = 0; i < length; i++) { data[i] = {}; data[i]['id'] = items[i].getAttribute('data-menu-id'); data[i]['parent_id'] = parentId; data[i]['sortorder'] = i+1; } console.log(data); }); }); </script> <ul data-sortable='{"id": "list", "selector": "li", "nestable": true}'> <li data-id="1"><div class="box">1 - List Item</div></li> <li data-id="2"><div class="box">2 - List Item</div></li> <li data-id="3"><div class="box">3 - List Item</div></li> <li data-id="4"><div class="box">4 - List Item</div></li> <li data-id="5"><div class="box">5 - List Item</div> <ul> <li data-id="9"><div class="box">5.1 - List Item</div></li> <li data-id="10"><div class="box">5.2 - List Item</div></li> </ul> </li> <li data-id="6"><div class="box">6 - List Item</div></li> <li data-id="7"><div class="box">7 - List Item</div></li> <li data-id="8"><div class="box">8 - List Item</div></li> </ul>
Supporting Touch Devices
To support touch devices you may consider a polyfill such as the Dragdroptouch.