Forms

Tailwind CSS Drag and Drop (Sortable)

Drag and Drop is a reorderable list component built on top of Sortable.js . Use data-kt-sortable on a list container to enable drag-and-drop reordering. Supports single lists, handle-only dragging, shared lists (move items between lists), and nested sortables.

Default

To add a basic reorderable list, use the data-kt-sortable attribute on the list container (e.g. a <ul> or <div> ). Items will be draggable and reorderable when the page loads.
  • Newsletter
  • Downloads
  • Team Account

Handle

Restrict dragging to a handle element by setting data-kt-sortable-handle to a CSS selector (e.g. .kt-sortable-handle ). Only dragging from the handle will reorder items.
  • Newsletter
  • Downloads
  • Team Account

Shared Lists

Use the same data-kt-sortable-group value on two or more list containers to allow moving items between lists. Items can be dragged from one list and dropped into another.
  • Newsletter
  • Downloads
  • Team Account
  • Questions
  • Settings
  • Activity

Nested

Nested sortables use a separate sortable list container for each level. Give every container the same group (e.g. nested ) so items can be dragged between parent and child lists. For nested lists, fallbackOnBody: true and swapThreshold: 0.65 are recommended for smoother drag behavior.
Item 1.1
Item 2.1
Item 2.2
Item 3.1
Item 3.2
Item 3.3
Item 2.3
Item 2.4
Item 1.2
Item 2.5
Item 2.6
Item 1.3
Item 1.4
Item 1.5

Methods

The following methods are available on the KTSortable component.
Method Description
KTSortable.init() Initializes all elements on the page that have the data-kt-sortable attribute (and are not disabled with data-kt-sortable="false" ). Called automatically when the page loads.
KTSortable.getInstance(element) Returns the KTSortable instance for the given DOM element (or selector). Returns null if no instance exists.
new KTSortable(element, options) Creates a KTSortable instance for the given DOM element with optional options object. Use for programmatic initialization.
dispose() Destroys the Sortable.js instance, removes event listeners, and cleans up the DOM element reference. Call on an instance obtained via getInstance() .
getSortable() Returns the underlying Sortable.js instance for advanced usage and direct API access.
getElement() Returns the DOM element associated with this KTSortable instance.

Options

Configuration options can be set via data attributes (e.g. data-kt-sortable-animation ) or passed to the constructor. Options are passed through to Sortable.js where applicable.
Option Type Default Description
animation number 150 Animation duration in milliseconds when sorting.
handle string CSS selector for the drag handle. If set, only the handle element starts a drag.
group string | object Group name (string) or options object to allow dragging between multiple lists. Use the same value on each list to share items.
dragClass string 'rounded-none!' CSS class applied to the dragged element.
ghostClass string CSS class applied to the placeholder (ghost) element.
chosenClass string CSS class applied to the chosen (selected) item.
lazy boolean false If true, the sortable is not created in the constructor; you must call init or create the instance later.
fallbackOnBody boolean false Append the drag clone to document.body. Recommended for nested sortables to avoid scroll/overflow issues.
swapThreshold number 1 Percentage of the target that must be overlapped to trigger a swap (0–1). Lower values (e.g. 0.65) make reordering in nested lists more responsive.

Events

KTSortable dispatches the following DOM events on the sortable element. Listen with element.addEventListener('kt.sortable.update', handler) .
Event Description
kt.sortable.init Fired when a KTSortable instance is created. Detail: { element } .
kt.sortable.start Fired when dragging starts. Detail: { item, from, oldIndex } .
kt.sortable.end Fired when dragging ends. Detail: { item, from, to, oldIndex, newIndex } .
kt.sortable.update Fired when the list order has changed (item dropped in new position). Detail: { item, from, to, oldIndex, newIndex } .

Data Attribute Initialization

Place these attributes on the list container element (e.g. <ul> or <div> ). Attribute names use the data-kt-sortable-* prefix; the part after the prefix is the option name in camelCase (e.g. data-kt-sortable-animation animation ).
Data Attribute Type Default Description
data-kt-sortable boolean true Enables auto-initialization of the sortable on this element. Set to false to exclude from init.
data-kt-sortable-animation number 150 Animation duration in milliseconds when sorting.
data-kt-sortable-handle string CSS selector for the drag handle. Only this element starts a drag.
data-kt-sortable-group string Group name. Use the same value on multiple lists to allow moving items between them.
data-kt-sortable-drag-class string 'rounded-none!' CSS class applied to the element while dragging.
data-kt-sortable-ghost-class string CSS class applied to the placeholder (ghost) element.
data-kt-sortable-chosen-class string CSS class applied to the selected item.
data-kt-sortable-lazy boolean false If true, the sortable is not created automatically; initialize programmatically with new KTSortable(element) .

JavaScript Initialization

By default, KTSortable.init() is called on page load and initializes every element with data-kt-sortable . To create an instance manually or pass options, use the constructor.
Programmatic initialization with options:
				
					const element = document.querySelector("#my-list");
const sortable = new KTSortable(element, {
  animation: 200,
  handle: ".drag-handle",
  group: "shared"
});

// Later: get instance or dispose
const instance = KTSortable.getInstance(element);
instance.dispose();

				
			
Re-initialize after dynamic content: Call KTSortable.createInstances() or KTSortable.init() to pick up new elements with data-kt-sortable . Ensure previous instances are disposed if the same nodes are re-used.