--- title: Sortable summary: Sortable lets users reorder the items of a list, a table or a grid by dragging them. It wraps SortableJS in a Tabler component and styles the dragged item. description: Make lists, table rows and cards draggable with the data-sortable attribute, SortableJS options as JSON and the Sortable component. docs-libs: [sortablejs] added-in: '1.6.0' related: [/ui/components/list-group, /ui/components/table] sass-vars: sortable --- import Example from '@components/Example.astro' import TabsPackage from '@components/TabsPackage.astro' import CodeDocs from '@components/CodeDocs.astro'; import { Code } from 'astro:components' import { site } from '@shared/lib/site.ts' ## Overview Use Sortable where the order is up to the user, such as a task list, table rows or dashboard cards. The component is part of `tabler.js`. The dragging itself comes from [SortableJS](https://sortablejs.github.io/Sortable/), which you load separately. ## Installation Install the SortableJS library: If you use a bundler, put the library on `window` before Tabler loads. The component reads `window.Sortable` and does nothing without it. Imports run before the rest of a file, so do it in a file of its own and import that one first: ```javascript // sortable-global.js import Sortable from 'sortablejs' window.Sortable = Sortable ``` ```javascript import './sortable-global.js' import '@tabler/core' ``` Or include it from a CDN, before `tabler.js`: `} /> ## Usage ### Basic list Add `data-sortable` to the parent element. Its direct children become draggable.
  • Design the landing page
  • Write the release notes
  • Review open pull requests
### Options Pass [SortableJS options](https://github.com/SortableJS/Sortable#options) as JSON in the attribute. This list animates the items as they move.
  • First
  • Second
  • Third
### Drag handle Set `handle` to a selector to start the drag only from that element. The rest of the item stays clickable. ```html ``` ### Table rows Put `data-sortable` on the `tbody` to reorder the rows of a table. ```html
First row
Second row
``` ### Drag styles Tabler styles the classes SortableJS adds while dragging: `.sortable-ghost` marks the drop position, `.sortable-chosen` the picked item and `.sortable-drag` the copy that follows the pointer. The browser draws the dragged item itself by default, and CSS cannot style that image. Turn on the `forceFallback` option and SortableJS drags an HTML copy of the item instead, which `.sortable-drag` tilts and lifts with a shadow: ```html ``` ## JavaScript Tabler wraps the plugin in a `Sortable` component that works like the Bootstrap components: it is created once per element and stored on it. On page load Tabler creates one for every element with `data-sortable`. This is the code that runs: Create the component yourself for a list added later. Options come from `data-sortable`, from the config object, or both. The object wins. ```js const list = new tabler.Sortable(document.getElementById('tasks'), { animation: 150 }); ``` Method|Description ---|--- `toArray()`|Returns the `data-id` of every item, in the current order. `sort(order, useAnimation)`|Reorders the items to match an array of ids. `dispose()`|Destroys the SortableJS instance and removes the component. The `sortable` getter returns the SortableJS instance, so everything from the [SortableJS API](https://github.com/SortableJS/Sortable#methods) is available: ```js const list = tabler.Sortable.getOrCreateInstance(document.getElementById('tasks')); list.sortable.option('disabled', true); ``` ## Accessibility - Dragging needs a pointer. SortableJS has no keyboard support, so give keyboard users another way to change the order, such as "Move up" and "Move down" buttons. - Use a drag handle when the items contain links or buttons, so a click on them does not start a drag. - Save the new order only after the drop, and tell the user when saving fails.