https://github.com/andhxl/blazor-sortable
A Blazor component that wraps the SortableJS library to provide interactive, drag-and-drop list reordering functionality
https://github.com/andhxl/blazor-sortable
blazor components drag-and-drop drag-drop dragdrop dragndrop reorder sortable sortablejs ui
Last synced: about 1 month ago
JSON representation
A Blazor component that wraps the SortableJS library to provide interactive, drag-and-drop list reordering functionality
- Host: GitHub
- URL: https://github.com/andhxl/blazor-sortable
- Owner: andhxl
- License: mit
- Created: 2025-06-06T00:08:54.000Z (10 months ago)
- Default Branch: main
- Last Pushed: 2025-11-17T08:38:54.000Z (5 months ago)
- Last Synced: 2025-11-17T09:22:37.416Z (5 months ago)
- Topics: blazor, components, drag-and-drop, drag-drop, dragdrop, dragndrop, reorder, sortable, sortablejs, ui
- Language: C#
- Homepage: https://andhxl.github.io/blazor-sortable/
- Size: 35.1 MB
- Stars: 0
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# BlazorSortable

[](https://www.nuget.org/packages/BlazorSortable)
[](https://www.nuget.org/packages/BlazorSortable)
A Blazor component that wraps the [SortableJS](https://github.com/SortableJS/Sortable) library, designed for creating interactive sortable lists with drag-and-drop support. Inspired by [BlazorSortable](https://github.com/the-urlist/BlazorSortable) and represents an improved and extended implementation.
## Installation
### Via Nuget Package Manager
### Via .NET CLI
```bash
dotnet add package BlazorSortable
```
### Via PackageReference
Add to your .csproj file:
```xml
```
## Setup
1. Add the SortableJS library to:
- `wwwroot/index.html` (for Blazor WebAssembly)
- `Components/App.razor` (for Blazor Web App)
- `Pages/_Host.cshtml` (for Blazor Server)
Using one of the following methods:
a) **Via CDN:**
```html
```
b) **Locally:**
```html
```
> You can optionally include a version parameter to avoid browser caching:
> ```html
>
> ```
For local installation:
1. Download the latest version of SortableJS from [GitHub](https://github.com/SortableJS/Sortable/releases)
2. Create the folder structure in `wwwroot`: `lib/sortable/dist/js/`
3. Place the `Sortable.min.js` file in the created folder
2. (Optional) Add base styles to the same file where you added the script:
```html
```
> You can also specify the version manually to prevent browser caching:
> ```html
>
> ```
> Or automatically insert the current assembly version (works in `.razor` or `.cshtml` files).
> Add this code within the `` element, or for **Blazor WebAssembly**, place it inside the `` section of `App.razor`:
> ```razor
>
> ```
> > For this to work in **Blazor WebAssembly**, make sure you have the following line in your `Program.cs`:
> > ```csharp
> > builder.RootComponents.Add("head::after");
> > ```
3. Add services in `Program.cs`:
```csharp
using BlazorSortable;
// ...
builder.Services.AddSortable();
```
4. Add the using directive in `_Imports.razor`:
```razor
@using BlazorSortable
```
## Usage Examples
```razor
```
```razor
@person.Name
@person.Email
@person.Department
```
```razor
```
## Component Parameters
### Sortable
> **Note:** Support for MultiDrag and Swap plugins will be added in future releases.
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `TItem` | — | — | The type of items in the list |
| `Items` | `IList?` | `null` | List of items to display and sort |
| `ChildContent` | `RenderFragment?` | `null` | Template for displaying each list item. Can be a component, HTML elements, or any Razor markup |
| `KeySelector` | `Func?` | `null` | Function for generating the key used in `@key`. If not set, the item itself is used |
| `Context` | `string` | `context` | Name of the parameter used in the child content template to refer to the current item |
| `Class` | `string?` | `null` | CSS class for the container |
| `Style` | `string?` | `null` | Inline CSS styles for the container |
| `Attributes` | `IReadOnlyDictionary?` | `null` | Additional custom attributes that will be rendered by the component |
| `Id` | `string` | `Random GUID` | Unique identifier of the component. Used internally for coordination between Sortable components. Must be globally unique |
| `Group` | `string` | `Random GUID` | Name of the group for interacting with other sortable instances |
| `Pull` | `SortablePullMode?` | `null` | Mode for pulling items from the list |
| `PullGroups` | `string[]?` | `null` | **Required when `Pull="SortablePullMode.Groups"`.** Specifies the groups into which items from this list can be dragged |
| `CloneFunction` | `Func?` | `null` | **Required when `Pull="SortablePullMode.Clone"`.** A factory method used to create a clone of the dragged item |
| `PullFunction` | `Predicate>?` | `null` | **Required when `Pull="SortablePullMode.Function"`.** Function to determine if an item can be pulled to the target Sortable component. **Works only in Blazor WebAssembly** |
| `Put` | `SortablePutMode?` | `null` | Mode for adding items to the list |
| `PutGroups` | `string[]?` | `null` | **Required when `Put="SortablePutMode.Groups"`.** Specifies the groups from which items are allowed to be added |
| `PutFunction` | `Predicate>?` | `null` | **Required when `Put="SortablePutMode.Function"`.** Function to determine if an item can be put into this list. **Works only in Blazor WebAssembly** |
| `ConvertFunction` | `Func, TItem?>?` | `null` | Function to convert items from other Sortable component to the target type |
| `Sort` | `bool` | `true` | Enables or disables sorting of items within the list |
| `Delay` | `int` | `0` | 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 and drop |
| `DelayOnTouchOnly` | `bool` | `false` | 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 |
| `TouchStartThreshold` | `int` | `0` | This option sets the minimum pointer movement that must occur before the delayed sorting is cancelled. Values between `3` to `5` are good |
| `Disabled` | `bool` | `false` | Disables the Sortable component when set to true |
| `Animation` | `int` | `150` | Animation duration in milliseconds |
| `Handle` | `string?` | `null` | CSS selector for elements that can be dragged (e.g. `.my-handle`) |
| `Filter` | `string?` | `null` | CSS selector for elements that cannot be dragged (e.g. `.ignore-elements`) |
| `DraggableSelector` | `Predicate?` | `null` | Function to determine if an item can be dragged |
| `DraggableClass` | `string` | `"sortable-draggable"` | CSS class applied to items that can be dragged |
| `GhostClass` | `string` | `"sortable-ghost"` | CSS class for the placeholder during drag |
| `ChosenClass` | `string` | `"sortable-chosen"` | CSS class for the chosen element |
| `DragClass` | `string` | `"sortable-drag"` | CSS class for the dragged element |
| `SwapThreshold` | `double` | `1` | Percentage of the target that the swap zone will take up, as a float between `0` and `1` |
| `InvertSwap` | `bool` | `false` | Set to true to set the swap zone to the sides of the target, for the effect of sorting "in between" items |
| `InvertedSwapThreshold` | `double` | `1` | Percentage of the target that the inverted swap zone will take up, as a float between `0` and `1` |
| `ForceFallback` | `bool` | `true` | If set to true, the Fallback for non HTML5 Browser will be used, even if we are using an HTML5 Browser |
| `FallbackClass` | `string` | `"sortable-fallback"` | CSS class for the element in fallback mode |
| `FallbackOnBody` | `bool` | `false` | Appends the cloned DOM Element into the Document's Body |
| `FallbackTolerance` | `int` | `0` | Emulates the native drag threshold. Specify in pixels how far the mouse should move before it's considered as a drag. `3` to `5` are probably good values |
| `Scroll` | `bool` | `true` | Enables scrolling of the container during dragging |
| `OnUpdate` | `Action>?` | `null` | Raised when the order of items is changed |
| `OnAdd` | `Action>?` | `null` | Raised when an item is added to the list |
| `OnRemove` | `Action>?` | `null` | Raised when an item is removed from the list |
### SortablePullMode
| Value | Description |
|-------|-------------|
| `True` | Allows pulling items from the list |
| `False` | Prohibits pulling items from the list |
| `Groups` | Allows pulling items only from specified groups (requires `PullGroups` parameter) |
| `Clone` | Creates a clone of the item when dragging (requires `CloneFunction` parameter) |
| `Function` | Uses a custom function to determine if items can be pulled (requires `PullFunction` parameter) |
### SortablePutMode
| Value | Description |
|-------|-------------|
| `True` | Allows adding items to the list |
| `False` | Prohibits adding items to the list |
| `Groups` | Allows adding items only from specified groups (requires `PutGroups` parameter) |
| `Function` | Uses a custom function to determine if items can be added (requires `PutFunction` parameter) |
## Events
All events receive a `SortableEventArgs` parameter.
Functions like `PullFunction`, `PutFunction` and `ConvertFunction` use a `SortableTransferContext` parameter.
### SortableEventArgs
The `SortableEventArgs` class provides information about sorting operations.
| Property | Type | Description |
|----------|------|-------------|
| `Item` | `TItem` | The item participating in the operation |
| `From` | `ISortableInfo` | Source sortable component |
| `OldIndex` | `int` | The previous index of the item in the source sortable |
| `To` | `ISortableInfo` | Target sortable component |
| `NewIndex` | `int` | The new index of the item in the target sortable |
| `IsClone` | `bool` | Flag indicating whether the item is a clone |
| `Cancel` | `bool` | Gets or sets a value indicating whether the current operation should be cancelled |
### SortableTransferContext
The `SortableTransferContext` class represents the context of transferring an item between sortable components.
| Property | Type | Description |
|----------|------|-------------|
| `Item` | `TItem` | The item being transferred between sortable components |
| `From` | `ISortableInfo` | The source sortable component |
| `To` | `ISortableInfo` | The target sortable component |
### ISortableInfo
The `ISortableInfo` interface provides information about a sortable component.
| Property | Type | Description |
|----------|------|-------------|
| `Id` | `string` | Unique identifier of the component |
| `Group` | `string` | Group name for interaction with other Sortable components |
## Notes
- **Order of events when dragging between lists:**
1. `OnAdd` is triggered **first** — during this event, the item is **still present in the source list**.
2. `OnRemove` is triggered **after**.
- **Cancelling operations:**
Inside `OnUpdate`, `OnAdd` and `OnRemove` handlers you can cancel the operation by setting `args.Cancel = true`.
- **Events use `Action?` instead of `EventCallback`.**
**Reason:** `EventCallback.InvokeAsync` automatically triggers `ComponentBase.StateHasChanged` in the parent component, which causes conflicts between the DOM and the data model for this component.
- **Type mismatch / failed conversion:**
If item types don’t match or the `ConvertFunction` returns `null`, the item is **not added** to the target list and is **remains in its original position**.
- **Dragging issues on scrolled page:**
If the dragged element appears misaligned when the page is scrolled, set
```razor
ForceFallback="false"
```
**or**
```razor
FallbackOnBody="true"
```
- **Blazor Server limitation:**
`PullFunction` and `PutFunction` require synchronous JS-to-.NET calls used by Sortable.js,
which are only available in **Blazor WebAssembly**.
On Blazor Server these functions cannot work and will throw `NotSupportedException`.