To enable drag and drop sorting and save the new sort order into the database, you can use the SortableJS library along with Livewire. Here's how you can implement it:
- Install SortableJS and Livewire using npm:
npm install sortablejs livewire
- Import SortableJS and Livewire in your JavaScript file:
import Sortable from 'sortablejs';
import { Livewire } from 'livewire';
window.Sortable = Sortable;
window.Livewire = Livewire;
- Update your Livewire component to include the necessary JavaScript and Livewire methods:
use Livewire\Component;
use App\Models\Shortcut;
class ShortcutList extends Component
{
public $search;
public $sortBy = 'sortorder';
public $sortDirection = 'asc';
protected $queryString = [
'search' => ['except' => ''],
'sortBy',
'sortDirection',
];
public function render()
{
$shortcuts = Shortcut::query()
->filter(['search' => $this->search])
->orderBy($this->sortBy, $this->sortDirection)
->get();
return view('livewire.shortcut-list', [
'shortcuts' => $shortcuts,
])->layout('layouts.master');
}
public function sortBy($field)
{
if ($this->sortBy === $field) {
$this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
} else {
$this->sortBy = $field;
$this->sortDirection = 'asc';
}
}
public function updatedShortcuts($newSortOrder)
{
foreach ($newSortOrder as $index => $shortcutId) {
Shortcut::where('id', $shortcutId)->update(['sortorder' => $index + 1]);
}
}
}
- Update your Livewire blade template to include the necessary HTML and Livewire directives:
<!-- ... -->
<table class="table table-bordered" wire:sortable="updatedShortcuts">
<thead>
<tr>
<th>Shortcut</th>
<th style="width:50px">Sort Order</th>
<th style="width:150px">Tools</th>
</tr>
</thead>
<tbody wire:sortable="updatedShortcuts">
@foreach ($shortcuts as $shortcut)
<tr wire:sortable.item="{{ $shortcut->id }}" wire:key="shortcut-{{ $shortcut->id }}">
<td>
<h5 class="card-title mb-1">{{ $shortcut->title }}</h5>
<p class="card-text"><a href="{{ $shortcut->title }}">{{ $shortcut->url }}</a></p>
</td>
<td>
<input type="text" value="{{ $shortcut->sortorder }}" style="width:50px">
</td>
<td class="text-right">
<!-- ... -->
</td>
</tr>
@endforeach
</tbody>
</table>
<!-- ... -->
- Add the necessary JavaScript code to initialize SortableJS and Livewire:
document.addEventListener('livewire:load', function () {
let shortcutsTable = document.querySelector('.table tbody');
let sortable = Sortable.create(shortcutsTable, {
handle: '.sortable-handle',
animation: 150,
onEnd: function (event) {
let newSortOrder = Array.from(shortcutsTable.children).map(function (row) {
return row.getAttribute('wire:sortable.item');
});
Livewire.emit('updatedShortcuts', newSortOrder);
}
});
});
With these changes, you should now be able to click and drag a shortcut row to set a new sort order. The Livewire updatedShortcuts method will be triggered when the sorting is finished, and it will update the sort order in the database for all the shortcuts.