Lightweight vanillajs micro-library for creating sortable lists and grids using native HTML5 drag and drop API.
- Only 2KB (minified and gzipped).
- Built using native HTML5 drag and drop API. No dependencies.
- Supports both list and grid style layouts.
- Supported Browsers: Current versions of all major browsers (Chrome, Firefox, Safari, Opera), IE10
- Supports exports as AMD, CommonJS or global
Demo: Check out the examples
| Browser | Chrome | Firefox | Safari | Opera | IE | |---|---|---|---|---|---|---| | Tested version | 39 | 34 | 7.1.2 | 26 | IE9 |
You need to install the package using npm
or downloading it manually. Afterwards you need to load dist/html.sortable.js
or the minified version, dist/html.sortable.min.js
. Make sure to grab the file from the dist/
directory.
npm install html5sortable --save
Still using bower? Look here.
You can find the examples online or test locally. Warning: the online demo is just to show off the features and is most likely not up to date. Please study this readme file for the current way of implementing and using html5sortable
.
1. Clone and install the project
You will need npm
, choose any way you like to install npm.
git clone https://github.com/lukasoppermann/html5sortable
cd html5sortable
npm install
2. Send a PR If you send a pull request make sure it passes the tests & linting. Please see CONTRIBUTING for details.
npm test
Use sortable
method to create a sortable list:
sortable('.sortable');
Use .sortable-placeholder
CSS selectors to change the styles of the placeholder. You may change the class by setting the placeholderClass
option in the config object.
sortable('.sortable', {
placeholderClass: 'my-placeholder fade'
});
NOTE: Events can be listened on any element from the group (when using connectWith
), since the same event will be dispatched on all of them.
Use sortstart
event if you want to do something when sorting starts:
sortable('.sortable')[0].addEventListener('sortstart', function(e) {
/*
This event is triggered when the user starts sorting and the DOM position has not yet changed.
e.detail.item contains the current dragged element
e.detail.placeholder contains the placeholder element
e.detail.startparent contains the element that the dragged item comes from
*/
});
Use the sortstop
event if you want to do something when sorting stops:
sortable('.sortable')[0].addEventListener('sortstop', function(e) {
/*
This event is triggered when the user stops sorting. The DOM position may have changed.
e.detail.item contains the element that was dragged.
e.detail.startparent contains the element that the dragged item came from.
*/
});
Use sortupdate
event if you want to do something when the order changes (e.g. storing the new order):
sortable('.sortable')[0].addEventListener('sortupdate', function(e) {
/*
This event is triggered when the user stopped sorting and the DOM position has changed.
e.detail.item contains the current dragged element.
e.detail.index contains the new index of the dragged element (considering only list items)
e.detail.oldindex contains the old index of the dragged element (considering only list items)
e.detail.elementIndex contains the new index of the dragged element (considering all items within sortable)
e.detail.oldElementIndex contains the old index of the dragged element (considering all items within sortable)
e.detail.startparent contains the element that the dragged item comes from
e.detail.endparent contains the element that the dragged item was added to (new parent)
*/
});
Use items
option to specify which items inside the element should be sortable:
sortable('.sortable', {
items: ':not(.disabled)'
});
Use handle
option to restrict drag start to the specified element:
sortable('.sortable', {
handle: 'h2'
});
Setting forcePlaceholderSize
option to true, forces the placeholder to have a height:
sortable('.sortable', {
forcePlaceholderSize: true
});
Use connectWith
option to create connected lists:
sortable('.js-sortable, .js-second-sortable', {
connectWith: 'connected' // unique string, which is not used for other connectWith sortables
});
Use placeholder
option to specify the markup of the placeholder:
sortable('.sortable', {
items: 'tr' ,
placeholder: '<tr><td colspan="7"> </td></tr>'
});
Use hoverClass
option to specify applying a css class to the hovered element rather than relying on :hover
. This can eliminate some potential drag and drop issues where another element thinks it is being hovered over.
sortable('.sortable', {
hoverClass: 'is-hovered' // Defaults to false
});
To remove the sortable functionality completely:
sortable('.sortable', 'destroy');
To disable the sortable temporarily:
sortable('.sortable', 'disable');
To enable a disabled sortable:
sortable('.sortable', 'enable');
When you add a new item to a sortable, it will not automatically be a draggable item, so you will need to reinit the sortable. Your previously added options will be preserved.
sortable('.sortable');
The plugin has limited support for sorting table rows. To sort table rows:
- Initialize plugin on
tbody
element - Keep in mind that different browsers may display different ghost image of the row during the drag action. Webkit browsers seem to hide entire contents of
td
cell if there are any inline elements inside thetd
. This may or may not be fixed by setting thetd
to beposition: relative;
This version is maintained by Lukas Oppermann and many other contributors. Thanks for your help! đź‘Ť
Contributions are always welcome. Please check out the contribution guidelines to make it fast & easy for us to merge your PR.
Your code should be as self-documenting as possible, but because this is an open source project with multiple contributors please add comments whenever possible/sensible.
Every function should have a docblock above stating what the function does and what parameters it is supposed to get.
/*
* remove event handlers from sortable
* @param: {Element} sortable
*/
You do not need to comment on everything you do, but if you make a decision that could be confusion or something could be potentially seen as an error (e.g. because it is not the default way or not the most obvious way) please comment on why you did this. This prevents people from “fixing” stuff that is not broken.
Please add tests using mocha and jsdom, to verify & test your changes. Make sure to make your test fail first, so you are sure they work. Your PR will fail, if you do not include tests.
Just add a new .js
file to the test
folder, or add a test to one of the files that already exist.
If you want to help us by working on any of the points below, please let me know and I add you and your branch to the list.
- clean up & add comments (wip)
- mocha tests (wip)
- Refactor & break code into functions (wip)
- Nesting via drag & drop