Reorderable drag-and-drop lists for modern browsers and touch devices. No jQuery or framework required.

Overview

Sortable   Financial Contributors on Open Collective CircleCI DeepScan grade npm

Sortable is a JavaScript library for reorderable drag-and-drop lists.

Demo: http://sortablejs.github.io/Sortable/

Features

  • Supports touch devices and modern browsers (including IE9)
  • Can drag from one list to another or within the same list
  • CSS animation when moving items
  • Supports drag handles and selectable text (better than voidberg's html5sortable)
  • Smart auto-scrolling
  • Advanced swap detection
  • Smooth animations
  • Multi-drag support
  • Support for CSS transforms
  • Built using native HTML5 drag and drop API
  • Supports
  • Supports any CSS library, e.g. Bootstrap
  • Simple API
  • Support for plugins
  • CDN
  • No jQuery required (but there is support)
  • Typescript definitions at @types/sortablejs

Articles


Getting Started

Install with NPM:

$ npm install sortablejs --save

Install with Bower:

$ bower install --save sortablejs

Import into your project:

// Default SortableJS
import Sortable from 'sortablejs';

// Core SortableJS (without default plugins)
import Sortable from 'sortablejs/modular/sortable.core.esm.js';

// Complete SortableJS (with all plugins)
import Sortable from 'sortablejs/modular/sortable.complete.esm.js';

Cherrypick plugins:

// Cherrypick extra plugins
import Sortable, { MultiDrag, Swap } from 'sortablejs';

Sortable.mount(new MultiDrag(), new Swap());


// Cherrypick default plugins
import Sortable, { AutoScroll } from 'sortablejs/modular/sortable.core.esm.js';

Sortable.mount(new AutoScroll());

Usage

<ul id="items">
	<li>item 1</li>
	<li>item 2</li>
	<li>item 3</li>
</ul>
var el = document.getElementById('items');
var sortable = Sortable.create(el);

You can use any element for the list and its elements, not just ul/li. Here is an example with divs.


Options

var sortable = new Sortable(el, {
	group: "name",  // or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
	sort: true,  // sorting inside list
	delay: 0, // time in milliseconds to define when the sorting should start
	delayOnTouchOnly: false, // only delay if user is using touch
	touchStartThreshold: 0, // px, how many pixels the point should move before cancelling a delayed drag event
	disabled: false, // Disables the sortable if set to true.
	store: null,  // @see Store
	animation: 150,  // ms, animation speed moving items when sorting, `0` — without animation
	easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
	handle: ".my-handle",  // Drag handle selector within list items
	filter: ".ignore-elements",  // Selectors that do not lead to dragging (String or Function)
	preventOnFilter: true, // Call `event.preventDefault()` when triggered `filter`
	draggable: ".item",  // Specifies which items inside the element should be draggable

	dataIdAttr: 'data-id', // HTML attribute that is used by the `toArray()` method

	ghostClass: "sortable-ghost",  // Class name for the drop placeholder
	chosenClass: "sortable-chosen",  // Class name for the chosen item
	dragClass: "sortable-drag",  // Class name for the dragging item

	swapThreshold: 1, // Threshold of the swap zone
	invertSwap: false, // Will always use inverted swap zone if set to true
	invertedSwapThreshold: 1, // Threshold of the inverted swap zone (will be set to swapThreshold value by default)
	direction: 'horizontal', // Direction of Sortable (will be detected automatically if not given)

	forceFallback: false,  // ignore the HTML5 DnD behaviour and force the fallback to kick in

	fallbackClass: "sortable-fallback",  // Class name for the cloned DOM Element when using forceFallback
	fallbackOnBody: false,  // Appends the cloned DOM Element into the Document's Body
	fallbackTolerance: 0, // Specify in pixels how far the mouse should move before it's considered as a drag.

	dragoverBubble: false,
	removeCloneOnHide: true, // Remove the clone element when it is not showing, rather than just hiding it
	emptyInsertThreshold: 5, // px, distance mouse must be from empty sortable to insert drag element into it


	setData: function (/** DataTransfer */dataTransfer, /** HTMLElement*/dragEl) {
		dataTransfer.setData('Text', dragEl.textContent); // `dataTransfer` object of HTML5 DragEvent
	},

	// Element is chosen
	onChoose: function (/**Event*/evt) {
		evt.oldIndex;  // element index within parent
	},

	// Element is unchosen
	onUnchoose: function(/**Event*/evt) {
		// same properties as onEnd
	},

	// Element dragging started
	onStart: function (/**Event*/evt) {
		evt.oldIndex;  // element index within parent
	},

	// Element dragging ended
	onEnd: function (/**Event*/evt) {
		var itemEl = evt.item;  // dragged HTMLElement
		evt.to;    // target list
		evt.from;  // previous list
		evt.oldIndex;  // element's old index within old parent
		evt.newIndex;  // element's new index within new parent
		evt.oldDraggableIndex; // element's old index within old parent, only counting draggable elements
		evt.newDraggableIndex; // element's new index within new parent, only counting draggable elements
		evt.clone // the clone element
		evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
	},

	// Element is dropped into the list from another list
	onAdd: function (/**Event*/evt) {
		// same properties as onEnd
	},

	// Changed sorting within list
	onUpdate: function (/**Event*/evt) {
		// same properties as onEnd
	},

	// Called by any change to the list (add / update / remove)
	onSort: function (/**Event*/evt) {
		// same properties as onEnd
	},

	// Element is removed from the list into another list
	onRemove: function (/**Event*/evt) {
		// same properties as onEnd
	},

	// Attempt to drag a filtered element
	onFilter: function (/**Event*/evt) {
		var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
	},

	// Event when you move an item in the list or between lists
	onMove: function (/**Event*/evt, /**Event*/originalEvent) {
		// Example: https://jsbin.com/nawahef/edit?js,output
		evt.dragged; // dragged HTMLElement
		evt.draggedRect; // DOMRect {left, top, right, bottom}
		evt.related; // HTMLElement on which have guided
		evt.relatedRect; // DOMRect
		evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
		originalEvent.clientY; // mouse position
		// return false; — for cancel
		// return -1; — insert before target
		// return 1; — insert after target
		// return true; — keep default insertion point based on the direction
		// return void; — keep default insertion point based on the direction
	},

	// Called when creating a clone of element
	onClone: function (/**Event*/evt) {
		var origEl = evt.item;
		var cloneEl = evt.clone;
	},

	// Called when dragging element changes position
	onChange: function(/**Event*/evt) {
		evt.newIndex // most likely why this event is used is to get the dragging element's current index
		// same properties as onEnd
	}
});

group option

To drag elements from one list into another, both lists must have the same group value. You can also define whether lists can give away, give and keep a copy (clone), and receive elements.

  • name: String — group name
  • pull: true|false|["foo", "bar"]|'clone'|function — ability to move from the list. clone — copy the item, rather than move. Or an array of group names which the elements may be put in. Defaults to true.
  • put: true|false|["baz", "qux"]|function — whether elements can be added from other lists, or an array of group names from which elements can be added.
  • revertClone: boolean — revert cloned element to initial position after moving to a another list.

Demo:


sort option

Allow sorting inside list.

Demo: https://jsbin.com/jayedig/edit?js,output


delay option

Time in milliseconds to define when the sorting should start. Unfortunately, due to browser restrictions, delaying is not possible on IE or Edge with native drag & drop.

Demo: https://jsbin.com/zosiwah/edit?js,output


delayOnTouchOnly option

Whether or not the delay should be applied only if the user is using touch (eg. on a mobile device). No delay will be applied in any other case. Defaults to false.


swapThreshold option

Percentage of the target that the swap zone will take up, as a float between 0 and 1.

Read more

Demo: http://sortablejs.github.io/Sortable#thresholds


invertSwap option

Set to true to set the swap zone to the sides of the target, for the effect of sorting "in between" items.

Read more

Demo: http://sortablejs.github.io/Sortable#thresholds


invertedSwapThreshold option

Percentage of the target that the inverted swap zone will take up, as a float between 0 and 1. If not given, will default to swapThreshold.

Read more


direction option

Direction that the Sortable should sort in. Can be set to 'vertical', 'horizontal', or a function, which will be called whenever a target is dragged over. Must return 'vertical' or 'horizontal'.

Read more

Example of direction detection for vertical list that includes full column and half column elements:

Sortable.create(el, {
	direction: function(evt, target, dragEl) {
		if (target !== null && target.className.includes('half-column') && dragEl.className.includes('half-column')) {
			return 'horizontal';
		}
		return 'vertical';
	}
});

touchStartThreshold option

This option is similar to fallbackTolerance option.

When the delay option is set, some phones with very sensitive touch displays like the Samsung Galaxy S8 will fire unwanted touchmove events even when your finger is not moving, resulting in the sort not triggering.

This option sets the minimum pointer movement that must occur before the delayed sorting is cancelled.

Values between 3 to 5 are good.


disabled options

Disables the sortable if set to true.

Demo: https://jsbin.com/sewokud/edit?js,output

var sortable = Sortable.create(list);

document.getElementById("switcher").onclick = function () {
	var state = sortable.option("disabled"); // get

	sortable.option("disabled", !state); // set
};

handle option

To make list items draggable, Sortable disables text selection by the user. That's not always desirable. To allow text selection, define a drag handler, which is an area of every list element that allows it to be dragged around.

Demo: https://jsbin.com/numakuh/edit?html,js,output

Sortable.create(el, {
	handle: ".my-handle"
});
<ul>
	<li><span class="my-handle">::</span> list item text one
	<li><span class="my-handle">::</span> list item text two
</ul>
.my-handle {
	cursor: move;
	cursor: -webkit-grabbing;
}

filter option

Sortable.create(list, {
	filter: ".js-remove, .js-edit",
	onFilter: function (evt) {
		var item = evt.item,
			ctrl = evt.target;

		if (Sortable.utils.is(ctrl, ".js-remove")) {  // Click on remove button
			item.parentNode.removeChild(item); // remove sortable item
		}
		else if (Sortable.utils.is(ctrl, ".js-edit")) {  // Click on edit link
			// ...
		}
	}
})

ghostClass option

Class name for the drop placeholder (default sortable-ghost).

Demo: https://jsbin.com/henuyiw/edit?css,js,output

.ghost {
  opacity: 0.4;
}
Sortable.create(list, {
  ghostClass: "ghost"
});

chosenClass option

Class name for the chosen item (default sortable-chosen).

Demo: https://jsbin.com/hoqufox/edit?css,js,output

.chosen {
  color: #fff;
  background-color: #c00;
}
Sortable.create(list, {
  delay: 500,
  chosenClass: "chosen"
});

forceFallback option

If set to true, the Fallback for non HTML5 Browser will be used, even if we are using an HTML5 Browser. This gives us the possibility to test the behaviour for older Browsers even in newer Browser, or make the Drag 'n Drop feel more consistent between Desktop , Mobile and old Browsers.

On top of that, the Fallback always generates a copy of that DOM Element and appends the class fallbackClass defined in the options. This behaviour controls the look of this 'dragged' Element.

Demo: https://jsbin.com/sibiput/edit?html,css,js,output


fallbackTolerance option

Emulates the native drag threshold. Specify in pixels how far the mouse should move before it's considered as a drag. Useful if the items are also clickable like in a list of links.

When the user clicks inside a sortable element, it's not uncommon for your hand to move a little between the time you press and the time you release. Dragging only starts if you move the pointer past a certain tolerance, so that you don't accidentally start dragging every time you click.

3 to 5 are probably good values.


dragoverBubble option

If set to true, the dragover event will bubble to parent sortables. Works on both fallback and native dragover event. By default, it is false, but Sortable will only stop bubbling the event once the element has been inserted into a parent Sortable, or can be inserted into a parent Sortable, but isn't at that specific time (due to animation, etc).

Since 1.8.0, you will probably want to leave this option as false. Before 1.8.0, it may need to be true for nested sortables to work.


removeCloneOnHide option

If set to false, the clone is hidden by having it's CSS display property set to none. By default, this option is true, meaning Sortable will remove the cloned element from the DOM when it is supposed to be hidden.


emptyInsertThreshold option

The distance (in pixels) the mouse must be from an empty sortable while dragging for the drag element to be inserted into that sortable. Defaults to 5. Set to 0 to disable this feature.

Demo: https://jsbin.com/becavoj/edit?js,output

An alternative to this option would be to set a padding on your list when it is empty.

For example:

ul:empty {
  padding-bottom: 20px;
}

Warning: For :empty to work, it must have no node inside (even text one).

Demo: https://jsbin.com/yunakeg/edit?html,css,js,output


Event object (demo)

  • to:HTMLElement — list, in which moved element
  • from:HTMLElement — previous list
  • item:HTMLElement — dragged element
  • clone:HTMLElement
  • oldIndex:Number|undefined — old index within parent
  • newIndex:Number|undefined — new index within parent
  • oldDraggableIndex: Number|undefined — old index within parent, only counting draggable elements
  • newDraggableIndex: Number|undefined — new index within parent, only counting draggable elements
  • pullMode:String|Boolean|undefined — Pull mode if dragging into another sortable ("clone", true, or false), otherwise undefined

move event object

  • to:HTMLElement
  • from:HTMLElement
  • dragged:HTMLElement
  • draggedRect:DOMRect
  • related:HTMLElement — element on which have guided
  • relatedRect:DOMRect
  • willInsertAfter:Booleantrue if will element be inserted after target (or false if before)

Methods

option(name:String[, value:*]):*

Get or set the option.

closest(el:HTMLElement[, selector:String]):HTMLElement|null

For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.

toArray():String[]

Serializes the sortable's item data-id's (dataIdAttr option) into an array of string.

sort(order:String[], useAnimation:Boolean)

Sorts the elements according to the array.

var order = sortable.toArray();
sortable.sort(order.reverse(), true); // apply
save()

Save the current sorting (see store)

destroy()

Removes the sortable functionality completely.


Store

Saving and restoring of the sort.

<ul>
	<li data-id="1">order</li>
	<li data-id="2">save</li>
	<li data-id="3">restore</li>
</ul>
Sortable.create(el, {
	group: "localStorage-example",
	store: {
		/**
		 * Get the order of elements. Called once during initialization.
		 * @param   {Sortable}  sortable
		 * @returns {Array}
		 */
		get: function (sortable) {
			var order = localStorage.getItem(sortable.options.group.name);
			return order ? order.split('|') : [];
		},

		/**
		 * Save the order of elements. Called onEnd (when the item is dropped).
		 * @param {Sortable}  sortable
		 */
		set: function (sortable) {
			var order = sortable.toArray();
			localStorage.setItem(sortable.options.group.name, order.join('|'));
		}
	}
})

Bootstrap

Demo: https://jsbin.com/visimub/edit?html,js,output

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css"/>


<!-- Latest Sortable -->
<script src="http://SortableJS.github.io/Sortable/Sortable.js"></script>


<!-- Simple List -->
<ul id="simpleList" class="list-group">
	<li class="list-group-item">This is <a href="http://SortableJS.github.io/Sortable/">Sortable</a></li>
	<li class="list-group-item">It works with Bootstrap...</li>
	<li class="list-group-item">...out of the box.</li>
	<li class="list-group-item">It has support for touch devices.</li>
	<li class="list-group-item">Just drag some elements around.</li>
</ul>

<script>
    // Simple list
    Sortable.create(simpleList, { /* options */ });
</script>

Static methods & properties

Sortable.create(el:HTMLElement[, options:Object]):Sortable

Create new instance.


Sortable.active:Sortable

The active Sortable instance.


Sortable.dragged:HTMLElement

The element being dragged.


Sortable.ghost:HTMLElement

The ghost element.


Sortable.clone:HTMLElement

The clone element.


Sortable.get(element:HTMLElement):Sortable

Get the Sortable instance on an element.


Sortable.mount(plugin:...SortablePlugin|SortablePlugin[])

Mounts a plugin to Sortable.


Sortable.utils
  • on(el:HTMLElement, event:String, fn:Function) — attach an event handler function
  • off(el:HTMLElement, event:String, fn:Function) — remove an event handler
  • css(el:HTMLElement):Object — get the values of all the CSS properties
  • css(el:HTMLElement, prop:String):Mixed — get the value of style properties
  • css(el:HTMLElement, prop:String, value:String) — set one CSS properties
  • css(el:HTMLElement, props:Object) — set more CSS properties
  • find(ctx:HTMLElement, tagName:String[, iterator:Function]):Array — get elements by tag name
  • bind(ctx:Mixed, fn:Function):Function — Takes a function and returns a new one that will always have a particular context
  • is(el:HTMLElement, selector:String):Boolean — check the current matched set of elements against a selector
  • closest(el:HTMLElement, selector:String[, ctx:HTMLElement]):HTMLElement|Null — for each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree
  • clone(el:HTMLElement):HTMLElement — create a deep copy of the set of matched elements
  • toggleClass(el:HTMLElement, name:String, state:Boolean) — add or remove one classes from each element
  • detectDirection(el:HTMLElement):String — automatically detect the direction of the element as either 'vertical' or 'horizontal'

Plugins

Extra Plugins (included in complete versions)

Default Plugins (included in default versions)


CDN

<!-- jsDelivr :: Sortable :: Latest (https://www.jsdelivr.com/package/npm/sortablejs) -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

Contributing (Issue/PR)

Please, read this.


Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

MIT LICENSE

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Comments
  • Swap Feature

    Swap Feature

    This is a rough implementation of a swapping feature. Setting the new "swap" option to true will cause a dragged item to be swapped with the item you drop it on (instead of inserted next to it). The item being hovered over (and potentially swapped with) will be highlighted by adding the class specified in the new "swapHighlightClass" option (defaults to "sortable-swap-highlight"). When swapping is enabled, the "end" event's "to" property will be set to the item being dropped on and swapped with.

    It's a bit hackish, but it works as a solution to issues #1211, #1082, #1072, #891, #869, and #469. Maybe it can at least serve as a starting off point to adding this feature to master eventually? Thanks!

    opened by gazugafan 37
  • Use rollup to bundle.

    Use rollup to bundle.

    This PR is really just to test the waters and see how you feel about modernising the codebase and using a modern bundler.

    With this PR, we can incrementally start modularising functionality and have the ability to tree-shake in the future.

    I've left the tabbing level of Sortable.js as-is to avoid doing too much code change, but it can all go in a level now.

    As for the main distribution, I think it would make sense to have it inside dist - but obviously changing this path is a pretty big breaking change, so you may prefer to just move Sortable.js to src/sortable.js and keep Sortable.js and Sortable.min.js where they are, so they will be the main bundled/dist code.

    Let me know your thoughts.

    opened by garygreen 33
  • Problem with nested lists

    Problem with nested lists

    I'm using nested lists:

    parent list: accept from A child list: accept from B

    The problem is that when I drag an element from A into the child list, sometimes it allows me to drop it inside.

    The same happens if I set the put attribute to allow only from B or if I just use the same group name for B and for the child list.

    opened by FezVrasta 31
  • Safari 13 loses drag event

    Safari 13 loses drag event

    Problem:

    On Safari Version 13.0 (14608.1.32 / 15608.1.31.1.2) the drag event is broken after initial drag & drop:

    1. Go to http://sortablejs.github.io/Sortable/
    2. Drag & drop an item in the list
    3. Drag again: there is no drag event, instead the text gets selected.
    4. Click once
    5. Drag event is back

    page demonstrating the problem:

    http://sortablejs.github.io/Sortable/

    bug safari 
    opened by rienswagerman 30
  • Dragging in mobile is buggy - scrolls page and triggers error

    Dragging in mobile is buggy - scrolls page and triggers error

    When I switch to mobile mode in Chrome 55 and I try to drag some sortable element, I get this error on every "finger" move:

    Sortable.js?1:565 Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

    In addition, if the page has where to scroll, it scrolls.

    If you want to see for yourself you can go to the official Sortable.js demo (http://rubaxa.github.io/Sortable/), open up dev tools, enable device emulation mode and start moving elements around.

    bug 
    opened by itaibh 30
  • SSR problem in vue.draggable context

    SSR problem in vue.draggable context

    Problem:

    Hello @owen-m1 , version 1.1.0.0 of sortable.js introduced a call to navigator global property. This is breaking SSR usage of vue.draggable: building the template on the server-side using node (none browser context).

    I tried a fix to require sortable.js only in browser context (https://github.com/SortableJS/Vue.Draggable/issues/724), but it seems

    • not to cover all scenarios (see discusrion on https://github.com/SortableJS/Vue.Draggable/issues/724)
    • to introduce regressions (https://github.com/SortableJS/Vue.Draggable/issues/731, https://github.com/SortableJS/Vue.Draggable/issues/730, https://github.com/SortableJS/Vue.Draggable/issues/728)

    I can not think of another fix on vue.draggable side thougth. Could it be possible to check for navigator early in sortable.js to avoid to raise exception when navigator is not defined?

    opened by David-Desmaisons 29
  • Sorting a list with checked checkboxes causes intentionally unchecked boxes to revert to checked

    Sorting a list with checked checkboxes causes intentionally unchecked boxes to revert to checked

    Example: http://jsbin.com/belacoreki/edit?html,js,output

    Reproduction steps:

    1. Uncheck "ID"
    2. Drag the sort handle anywhere in the list.

    What should happen: List is reordered with checkboxes maintaining their current state (ID unchecked)

    What happens: List is reordered with the ID checkbox being re-checked.

    Verified issue against master and 1.5.1 release. Regression from 1.4.2, verified does not have this issue (you can change the CDN link to https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.4.2/Sortable.js to verify).

    opened by gavbaa 29
  • When using multiple lists, dropping back the item in the list where it was dragged cause item creation in the last other list it has been dragged over

    When using multiple lists, dropping back the item in the list where it was dragged cause item creation in the last other list it has been dragged over

    So I was reading Issue #633 on this github, and agree that the issue describe can be a feature but i think this one is a bug because it works when sort is enabled...

    So here is the full description of the steps to reproduce the problem :

    1. I pick an item from list 1 where settings are:
      • group: { name: 'blocks', pull: 'clone', put: false }
      • sort : false
    2. I drag it over the other list which settings are:
      • group: { name: 'blocks', pull: true, put: true }
      • sort : true
    3. The ghost item appears well in the 2nd list
    4. Drag it out of the 2nd list, ghost item is still there
    5. Drag it BACK over the 1st list, ghost item disappear (which is what is wanted)
    6. Drop it in the list where it was originally dragged : item is created in the 2nd list !!! (BUG)

    NB : if I activate the sort on the first list, the bug is gone, but my item possibly change place in that list and I don't want that behavior... I'll try to dig in the code and fix the bug

    opened by jamendub 29
  • Drag multiple items at once

    Drag multiple items at once

    Thanks for the great project. Right now I am working on the task where I should drag and drop multiple items. I have checked the documentation, same as the issues thread; however, I have not found any relative info regarding how to drag multiple items same time.

    That's why I am wondering whether the library supports the functionality or someone had success to achieve it by using the library.

    Thanks

    feature 
    opened by omytryniuk 27
  • delay option doesn't work

    delay option doesn't work

    Hi,

    I am checking the demo: http://jsbin.com/videlojafi/edit?html,js,output

    It doesn't work for me on either firefox, or IE (10). Once removing the delay line, or changing it to 0, everything starts to work

    opened by bhecht2 26
  • [Angular] Javascript error when moving items between two lists very fast

    [Angular] Javascript error when moving items between two lists very fast

    Hey all,

    I know it's been reported in a previously closed issue (https://github.com/RubaXa/Sortable/issues/553), so feel free to close this and tell me to stop asking haha.

    I was just wondering what the fix for this is going to be, and when it will likely make it into master - this is proving to be a showstopper for a project I'm on, and Sortable is easily the best drag and drop library I have found, so I don't want to move away from it. The issue is still present on the demo page (http://rubaxa.github.io/Sortable/ - using the same test instructions that are in the issue I linked to).

    Thanks for your time.

    -Dave

    opened by grug 26
  • Bump json5 from 2.2.0 to 2.2.3

    Bump json5 from 2.2.0 to 2.2.3

    Bumps json5 from 2.2.0 to 2.2.3.

    Release notes

    Sourced from json5's releases.

    v2.2.3

    v2.2.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)
    Changelog

    Sourced from json5's changelog.

    v2.2.3 [code, diff]

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1 [code, diff]

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)
    Commits
    • c3a7524 2.2.3
    • 94fd06d docs: update CHANGELOG for v2.2.3
    • 3b8cebf docs(security): use GitHub security advisories
    • f0fd9e1 docs: publish a security policy
    • 6a91a05 docs(template): bug -> bug report
    • 14f8cb1 2.2.2
    • 10cc7ca docs: update CHANGELOG for v2.2.2
    • 7774c10 fix: add proto to objects and arrays
    • edde30a Readme: slight tweak to intro
    • 97286f8 Improve example in readme
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [Vuejs 2.6] How to deselect in VueDraggable Multi

    [Vuejs 2.6] How to deselect in VueDraggable Multi

    Now, i using lib VueDraggable Multi in my code: https://www.npmjs.com/package/vuedraggable-multi

    But in VueDraggable Multi, i don't use sortable.utils.deselect(item)

    So, i want to something like that or idea for deselect(item) with VueDraggable Multi

    Please!! Many thank

    opened by tranducchung 0
  • Clone + Nesting : Allow only certain elements

    Clone + Nesting : Allow only certain elements

    It is possible to allow only certain elements to be nested inside others?

    Example: Application element can contain only Container elements. Container only Queries, and Queries different types of Components.

    CodePen Example

    image

    opened by Blackcode 0
  • Table interchange column encountered a problem

    Table interchange column encountered a problem

    When a table exchanges columns, the width of the exchange column becomes the width of the target column.

    It will change back only when the exchange is completed

    How to solve this problem

    opened by 422884549 0
  • Bump qs from 6.5.2 to 6.5.3

    Bump qs from 6.5.2 to 6.5.3

    Bumps qs from 6.5.2 to 6.5.3.

    Changelog

    Sourced from qs's changelog.

    6.5.3

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Fix] utils.merge: avoid a crash with a null target and a truthy non-array source
    • [Fix] correctly parse nested arrays
    • [Fix] stringify: fix a crash with strictNullHandling and a custom filter/serializeDate (#279)
    • [Fix] utils: merge: fix crash when source is a truthy primitive & no options are provided
    • [Fix] when parseArrays is false, properly handle keys ending in []
    • [Fix] fix for an impossible situation: when the formatter is called with a non-string value
    • [Fix] utils.merge: avoid a crash with a null target and an array source
    • [Refactor] utils: reduce observable [[Get]]s
    • [Refactor] use cached Array.isArray
    • [Refactor] stringify: Avoid arr = arr.concat(...), push to the existing instance (#269)
    • [Refactor] parse: only need to reassign the var once
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] Clean up license text so it’s properly detected as BSD-3-Clause
    • [Docs] Clarify the need for "arrayLimit" option
    • [meta] fix README.md (#399)
    • [meta] add FUNDING.yml
    • [actions] backport actions from main
    • [Tests] always use String(x) over x.toString()
    • [Tests] remove nonexistent tape option
    • [Dev Deps] backport from main
    Commits
    • 298bfa5 v6.5.3
    • ed0f5dc [Fix] parse: ignore __proto__ keys (#428)
    • 691e739 [Robustness] stringify: avoid relying on a global undefined (#427)
    • 1072d57 [readme] remove travis badge; add github actions/codecov badges; update URLs
    • 12ac1c4 [meta] fix README.md (#399)
    • 0338716 [actions] backport actions from main
    • 5639c20 Clean up license text so it’s properly detected as BSD-3-Clause
    • 51b8a0b add FUNDING.yml
    • 45f6759 [Fix] fix for an impossible situation: when the formatter is called with a no...
    • f814a7f [Dev Deps] backport from main
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [bug] Source element ID removed when cloned

    [bug] Source element ID removed when cloned

    Describe the bug

    When draggable elements have an id, this one is removed when one of those elements is cloned.

    To Reproduce

    1. Go to https://jsbin.com/ruxecon/1/edit?html,js,output
    2. Drag an item from the first list, eg "foo" to the second list
    3. Inspect the HTML and observe that the dragged item from the first list, eg "foo", doesn't have its ID, ie "A1" anymore.

    Expected behavior

    The IDs of the elements having been dragged should still be present.

    It makes sense that the IDs are removed on the cloned elements, ie the new ones, but not on the original elements.

    Information

    sortablejs = "^1.15.0

    opened by mwillema 0
Releases(1.15.0)
  • 1.15.0(Mar 20, 2022)

    • #2072: Make sure dragged element is inserted after last dragged element
    • #2084: Added avoidImplicitDeselect option to MultiDrag
    • #2093: Remove ID from cloned element
    • #2095: Remove ignoring click on Chrome for Android when dragging (wasn't necessary)
    Source code(tar.gz)
    Source code(zip)
  • 1.14.0(Jul 4, 2021)

    • Clarify dataIdAttr option docs
    • #1942: Check if ghost is first
    • #2021: Fix multidrag indicies
    • #2025: Fix reverting with nested sortables
    • Added forceAutoScrollFallback option
    • Add trick for empty sortables to README
    • Use minified version main field of package.json
    Source code(tar.gz)
    Source code(zip)
  • 1.13.0(Jan 8, 2021)

    • #1681: Fix clicking select tags
    • #1784: Fix "insertBefore error" issue on nested lists
    • #1834: Improve repaint function for compressor scripts
    • Throw error when mounting duplicate plugins
    • #1904: Fix IE11 error when dragging element
    • Improve docs
    • #1571: Ignore pointer events on Safari (Fixes issue with Safari 13+)
    • #1954: Add useAnimation option to sort()
    Source code(tar.gz)
    Source code(zip)
  • 1.10.2(Dec 25, 2019)

    • #1674: add MSCSSMatrix to matrixFn options
    • #1639: disable delayed drag events during destroy
    • #1644: Remove transform on drop
    • #1689: Added type check for 'dragStarted' variable
    • #1647: Fix(utils): Chrome < 44 not support scrollingElement
    • #1699: Fixed multiplying ghost transform
    • Added Open Collective
    Source code(tar.gz)
    Source code(zip)
  • 1.10.1(Oct 1, 2019)

  • 1.10.0(Sep 15, 2019)

    • #1556: Fix delayOnTouchOnly for android
    • Add tests
    • #1580: Fix plugins' references to options
    • Improve OnSpill support with multiple sortables + fix drop events
    • #1611: Remove MultiDrag events on GLOBAL destroy
    • #1597: Fix docs for enabling plugins
    • #1599: Support for transforms on ghost element
    • Animation performance improvements
    • #1634: Fix onSpill plugins on mobile
    • #1598: Allow selecting with SHIFT key without multiDragKey being down
    Source code(tar.gz)
    Source code(zip)
  • 1.10.0-rc3(Jun 27, 2019)

  • 1.10.0-rc2(Jun 7, 2019)

  • 1.10.0-rc1(Jun 6, 2019)

  • 1.9.0(Apr 20, 2019)

    • #1471: Use real event properties when doing empty insert
    • #1475: Fixed _lastChild failing to ignore display:none
    • #1476: Stricter requirements for supportPointer
    • Better fix for unwanted IE event capturing
    • Optimize nearestEmptyInsertDetectEvent callback (#1483)
    • #1472: Added oldDraggableIndex + newDraggableIndex
    • #1487: Detect for empty insert always if not inserted
    • #1489: Fix infinite loop in detecting shadow DOM
    • #1492: Improved repaint trigger
    • #1469: Fixed delay option on Android
    • #1482: Added delayOnTouchOnly option
    Source code(tar.gz)
    Source code(zip)
  • 1.8.4(Mar 11, 2019)

    • #1451: Automatic direction detection for grids
    • #659: Better cross-browser compatibility for delay option
    • Fixed text selection in fallback on MacOS Safari
    • #1458: Fixed auto-scrolling in MacOS Safari
    • Added compensation for Chrome's adjustment of scroll position if swapped element is out of viewport
    • Added pullMode to event object
    • #1457: Improved detection of empty sortables
    • #1462: Fixed setting of ghostClass, as well as animating items only after clones are shown
    Source code(tar.gz)
    Source code(zip)
  • 1.8.3(Feb 11, 2019)

  • 1.8.2(Feb 10, 2019)

    • #1431: Dragging in iframe fix
    • #1012: Firefox drag and drop opening tab issue fix
    • #1434: Fixed target detection
    • Fixed direction detection for floating elements
    • Changed "is ghost last" check to no longer be fixed along axis
    • #1436: Safari fix
    • Allowed empty Sortable detection while dragging for touch devices
    Source code(tar.gz)
    Source code(zip)
  • 1.8.1(Jan 16, 2019)

    • Pull/Put options that are functions can now properly return arrays and have them evaluated as such
    • Reverted back to old method of preventing scroll on mobile while dragging
    Source code(tar.gz)
    Source code(zip)
  • 1.8.0(Jan 15, 2019)

    • (#869, #592, #1358, #1119, #1378, etc): Dragover revamp, added options direction, swapThreshold, invertSwap, and invertedSwapThreshold. Read more. Resolved many of the issues where sorting is "not realistic". Grid-style sorting should work as well.
    • #1373: Autoscroll revamp, added option bubbleScroll, and better cross-browser compatibility
    • #1303: dragoverBubble for fallback
    • Bubbling of dragover event will only be stopped when element is inserted into a sortable if dragoverBubble=false
    • Automatic detection for pointer event support
    • #1389: Touch delay fix on mobile
    • #1382: Firefox event path fix
    • Cloning fixes
    • Pull/Put function fixes
    • #1352: Saving on both Sortables if dragged from one to another
      • get and set don't both need to be defined to work properly
    • #1276 : Native Drag and Drop ghost fix
    • Firefox: prevent selection when dragging
    • (#1409, #1323, #1095, #1204, #1087): Added onChange event
    • Changed when dragstart and dragstarted are fired in fallback to match native HTML
    • Made pointer events mutually exclusive with mouse and touch events, to prevent duplicate event firing
    • #1151: Added easing option for animation easing
    • #1184: Click event no longer fired on drop when using fallback
    • #1404: Fixed ghost element dimensions
    • (#1123, #1423): Ghost element is relative to containing block (prevents unwanted ghost element offset when using CSS translate)
    • #1301: Ghost element adheres to CSS scaling
    • (#1093, #1236, #1054, #1214): Added removeCloneOnHide option
    • #1321: Much better support for nested sortables
    • #1305: Made it easier to add items to empty sortables with emptyInsertThreshold option
    • #1416: Solidified pull/put behavior. Pull/Put are false by default when dealing with different groups, but true by default when dealing with the same group. They can be overridden in both cases.
    • #1079: The ghostClass that is applied is the target sortable's ghostClass, not that of the source sortable
    • Many bug fixes
    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Oct 13, 2015)

  • 1.3.0(Sep 22, 2015)

    • Improved stability and performance on touch devices
    • Added a new option chosenClass
    • And so on: #558, #547, #542, #537, #532, #516, #500, #489, #488, #447, #475, #459, ##422, #411, #356
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Apr 14, 2015)

  • 1.1.1(Feb 20, 2015)

  • 1.1.0(Feb 13, 2015)

    • [x] #34: Support IE9
    • [x] #217: React component
    • [x] #269: CDN
    • [x] #267: Angular: ng-sortable fails when no ng-repeat is found
    • [x] #245: Deep copy object to avoid unwanted referencing (angualar)
    • [x] #271: Autoscroll container with height: 100%
    • [x] #256: No scroll when dragging between two lists and no window scroll
    • [x] #243: fix index calculation to skip templates
    • [x] #254: Allow text to be dropped into sortable INPUT fields
    • [x] #238: fixed disabled option
    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Dec 22, 2014)

Owner
SortableJS
A JavaScript library for reorderable drag-and-drop lists in modern browsers and touch devices
SortableJS
Drag and drop library for two-dimensional, resizable and responsive lists

DEPRECATED This project is no longer maintained, please consider using react-grid-layout instead. GridList Drag and drop library for a two-dimensional

Hootsuite 3.6k Dec 14, 2022
Pressure is a JavaScript library for handling both Force Touch and 3D Touch on the web

Pressure is a JavaScript library for handling both Force Touch and 3D Touch on the web, bundled under one library with a simple API that makes working with them painless.

Stuart Yamartino 2.9k Dec 29, 2022
Super tiny size multi-touch gestures library for the web.    You can touch this →

Preview You can touch this → http://alloyteam.github.io/AlloyFinger/ Install You can install it via npm: npm install alloyfinger Usage var af = new Al

腾讯 AlloyTeam 3.3k Dec 12, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Javascript client for Sanity. Works in node.js and modern browsers (older browsers needs a Promise polyfill).

@sanity/client Javascript client for Sanity. Works in node.js and modern browsers (older browsers needs a Promise polyfill). Requirements Sanity Clien

Sanity 23 Nov 29, 2022
Digispark Overmaster : free IDE TOOL allows to create and edit Digispark Scripts by the drag and drop technique,with cool GUI and easy to use it

Digispark_Overmaster Digispark Overmaster : free IDE TOOL allows to create and edit Digispark Scripts by the drag and drop technique,with cool GUI and

Yehia Elborma 5 Nov 14, 2022
DoMe is a ToDo App. you can add, delete and reorder elements of the todo list using drag and drop. You can also toggle between dark&light mode

DO ME Todo App Live Preview : DO ME Built With : - ReactJS - TailwindCSS Make sure you have: - Git - Nodejs version 14 or higher (we recommend using

Medjahdi Islem 5 Nov 18, 2022
An interactive app that allows adding, editing and removing tasks of a to-do list. Drag-and-drop featured added. Webpack was used to bundle all the Js modules in to one main Js file.

To-do List A to-do list app This app let you to set your own to-do list. Built With HTML CSS JavaScript WebPack Jest Live Page Page Link Getting Start

Kenny Salazar 7 May 5, 2022
Fancytree - JavaScript tree view / tree grid plugin with support for keyboard, inline editing, filtering, checkboxes, drag'n'drop, and lazy loading

Fancytree Fancytree (sequel of DynaTree 1.x) is a JavaScript tree view / tree grid plugin with support for keyboard, inline editing, filtering, checkb

Martin Wendt 2.6k Jan 9, 2023
A Drag-and-Drop library for all JavaScript frameworks implementing an enhanced transformation mechanism to manipulate DOM elements

JavaScript Project to Manipulate DOM Elements DFlex A Drag-and-Drop library for all JavaScript frameworks implementing an enhanced transformation mech

DFlex 1.5k Jan 8, 2023
Drag and drop Argo Workflows tool.

Visual Argo Workflows Live demo The goal of this project is to make it easier for everyone on a team to construct and run their own workflows. Workflo

Artem Golub 38 Dec 22, 2022
Allow moving/copying/and creation embeds for blocks with drag-n-drop just like Logseq or Roam

Demo Features Drag-n-drop for list items in the same pane and between different panes 3 modes: move block, copy block, embed block Automatic reference

null 92 Dec 26, 2022
Drag-and-drop editor for Docassemble interviews

GraphDoc Introduction GraphDoc is a web-application that has been developed on behalf of the Maastricht Law & Tech Lab, which is part of Maastricht Un

Maastricht Law & Tech Lab 16 Dec 28, 2022
Nested Sort is a JavaScript library which helps you to sort a nested list of items via drag and drop.

Nested Sort Nested Sort is a vanilla JavaScript library, without any dependencies, which helps you to sort a nested list of items via drag and drop. U

Hesam Bahrami 40 Dec 7, 2022
🔖 A drag-and-drop form builder for Bootstrap 4.

Bootstrap v4 Form Builder A drag-and-drop form builder for Bootstrap 4. ❓ Get Help There are few ways to get help: Please post questions on Stack Over

Bloggify 107 Dec 22, 2022
jQuery based scrolling Bar, for PC and Smartphones (touch events). It is modern slim, easy to integrate, easy to use. Tested on Firefox/Chrome/Maxthon/iPhone/Android. Very light <7ko min.js and <1Ko min.css.

Nice-Scrollbar Responsive jQuery based scrolling Bar, for PC and Smartphones (touch events). It is modern slim, easy to integrate, easy to use. Tested

Renan LAVAREC 2 Jan 18, 2022
Polyfill to remove click delays on browsers with touch UIs

FastClick FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a click event on mobile

FT Labs 18.8k Jan 2, 2023