I'm trying to make a list that you can sort by dragging.
The frontend part works (javascript only), but as soon as I uncomment component.call('reorder', orderIds); to save the order to the database, it doesn't work anymore. (component.call('reorder', orderIds); is located in the javascript file) I have tried everything I could but I can't get it to work. (examples down below)
I followed this tutorial: https://laravel-livewire.com/screencasts/s8-dragging-list . But he is changing the order of an array but I want to change the order in the database.
Here is my example on codepen to show what I want to achieve: https://codepen.io/MrDexterK/pen/OJpRBWP
Maybe the js is clashing with livewire?
Also look at the console in the following examples
Working example (js only):
https://gyazo.com/9a770e2597143db04e042b670a92b1d3
Not working example (with function uncommented):
https://gyazo.com/17d86a821fc3f686a089c28483a60853
Does anyone know a solution?
Thanks!
The JavaScript
<script>
let root = document.querySelector('[drag-root]');
root.querySelectorAll('[drag-item]').forEach(el => {
el.addEventListener('dragstart', e => {
e.target.setAttribute('dragging', true);
});
el.addEventListener('drop', e => {
e.target.classList.remove('bg-yellow-100');
// get the dragging element
let draggingEl = root.querySelector('[dragging]');
// insert it before the drop target
e.target.before(draggingEl);
let component = Livewire.find(
e.target.closest('[wire\\:id]').getAttribute('wire:id')
)
let orderIds = Array.from(root.querySelectorAll('[drag-item]'))
.map(itemEl => itemEl.getAttribute('drag-item'))
console.log('reorder called with: ' + orderIds);
// when component.call is called it breaks after a few tries
component.call('reorder', orderIds);
});
el.addEventListener('dragenter', e => {
// e.target.classList.add('bg-yellow-100');
e.preventDefault();
});
el.addEventListener('dragover', e => {
e.preventDefault();
});
el.addEventListener('dragleave', e => {
// e.target.classList.remove('bg-yellow-100');
});
el.addEventListener('dragend', e => {
e.target.removeAttribute('dragging');
});
});
</script>
The component containing the function that is called
public function reorder($orderedIds)
{
$order = 1;
foreach ($orderedIds as $orderedId) {
$question = Question::find($orderedId);
$question->order = $order;
$question->save();
$order++;
}
}
Blade file with the draggable items
<ul drag-root class="overflow-hidden text-indigo-100 font-mono mt-5 w-1/2 flex-inline">
@foreach($questions as $question)
<a href="{{ route('admin.questions.edit', ['question' => $question->id]) }}">
<li drag-item="{{ $question->id }}" draggable="true" class="w-full rounded px-4 pt-1.5 h-10 mt-1 border-2 border-indigo-500 bg-indigo-800 hover:bg-indigo-700 cursor-move">
{{ $question->title }}
</li>
</a>
@endforeach
</ul>