Awesome
Livewire Sortable
A plugin/wrapper around Shopify's sortable package. It makes implementing sortable interfaces super simple using Livewire.
Installation
CDN
<script src="https://cdn.jsdelivr.net/gh/livewire/sortable@v1.x.x/dist/livewire-sortable.js"></script>
Note: this package only supports Livewire v3. If you are using v2, use version
0.3.0
of this package.
NPM
npm install livewire-sortable --save-dev
Import the package in your bundle:
import 'livewire-sortable'
// Or.
require('livewire-sortable')
Usage
For simple layouts that only require simple sorting like a todo list, add the wire:sortable
, wire:sortable.item
, and wire:sortable.handle
attributes to your markup as follows.
<ul wire:sortable="updateTaskOrder">
@foreach ($tasks as $task)
<li wire:sortable.item="{{ $task->id }}" wire:key="task-{{ $task->id }}">
<h4 wire:sortable.handle>{{ $task->title }}</h4>
<button wire:click="removeTask({{ $task->id }})">Remove</button>
</li>
@endforeach
</ul>
For creating a nested layout with draggable groups with draggable items inside each group, similar to Trello, add the wire:sortable
, wire:sortable-group
, wire:sortable.item
, wire:sortable.handle
, wire:sortable-group.handle
, wire:sortable-group.item-group
, and wire:sortable-group.item
attributes to your markup as follows.
<div wire:sortable="updateGroupOrder" wire:sortable-group="updateTaskOrder" style="display: flex">
@foreach ($groups as $group)
<div wire:key="group-{{ $group->id }}" wire:sortable.item="{{ $group->id }}">
<div style="display: flex">
<h4 wire:sortable.handle>{{ $group->label }}</h4>
<button wire:click="removeGroup({{ $group->id }})">Remove</button>
</div>
<ul wire:sortable-group.item-group="{{ $group->id }}">
@foreach ($group->tasks()->orderBy('order')->get() as $task)
<li wire:key="task-{{ $task->id }}" wire:sortable-group.item="{{ $task->id }}">
<span wire:sortable-group.handle>{{ $task->title }}</span>
<button wire:click="removeTask({{ $task->id }})">Remove</button>
</li>
@endforeach
</ul>
<form wire:submit.prevent="addTask({{ $group->id }}, $event.target.title.value)">
<input type="text" name="title">
<button>Add Task</button>
</form>
</div>
@endforeach
<form wire:submit.prevent="addGroup">
<input type="text" wire:model="newGroupLabel">
<button>Add Task Group</button>
</form>
</div>
Styling
If you want to add your own styles to elements during various "draggable" states (like adding a shadow to an item while dragging), reference Shopify's Draggable/Sortable plugin's docs directly: https://github.com/Shopify/draggable/blob/58d79dc9fb5b82271c5dfec74a5c9207cfab01f5/src/Draggable/README.md#classes