Swaz's avatar
Level 20

Livewire 4 sorting across groups?

How is it possible to detect sorting across groups if the only values we get are the $item and $position?

from the docs

use Livewire\Component;
use Livewire\Attributes\Computed;
 
new class extends Component {
    public User $user;
 
    public function sortItem($item, $position)
    {
        $item = $this->todo->items()->findOrFail($item);
 
        // Update the item's position
    }
};
<div>
    @foreach ($user->todoLists as $todo)
        <ul wire:sort="sortItem" wire:sort:group="todos">
            @foreach ($todo->items as $item)
                <li wire:sort:item="{{ $item->id }}">
                    {{ $item->title }}
                </li>
            @endforeach
        </ul>
    @endforeach
</div>
0 likes
15 replies
jlrdw's avatar

Just wondering would a regular old GROUP BY followed by ORDER BY be better. Letting the database work for you.

But are you saying they aren't being sorted correctly in livewire?

Swaz's avatar
Level 20

I'm trying to use the new wire:sort stuff in livewire 4.

https://livewire.laravel.com/docs/4.x/wire-sort

The docs say you can do sorting across groups, but it does not seem possible.

In the example I posted (and from the docs) if you move an item from one todoList to another, how would the back end know. We need to know what todoList the item moved to and wire:sort does not provide that.

klopma's avatar

Hello!

I was also encountering this issue and found this video of Caleb demonstrating wire:sort:group ( https://www.youtube.com/watch?v=A8AXghy-XzM at about 14:50).

The difference between his demonstration and my situation was that he had built out a component for the parent groups - I hadn't. He used wire:sort:group to tie them together, and moving a child triggers the sortChild logic on only the receiving parent group component, so you have the context available within that component instance to know which parent we're talking about.

I still don't see how the example in the docs is working (without something like @rihulfaakbar's solution), but hopefully this is an alternative for you @swaz?

Swaz's avatar
Level 20

Are you saying it got it working somehow, as long as whatever has wire:sort:group is a livewire component?

Swaz's avatar
Level 20

I watched the video and saw him drag & drop items to different groups. But he doesn't show how he actually saves the position of the item in the new group.

Swaz's avatar
Level 20

That time stamp is him saving the position of columns, not an item moving from one column to another.

  • It's easy to reorder columns and save position.
  • It's easy to reorder items and save position.

He still doesn't show how to save an items position that is dragged from one column into another. There doesn't seem to be a way know what column the new item was dragged into.

klopma's avatar
klopma
Best Answer
Level 3

Hi @swaz, yes, I believe so. In my context, I have a form that has sections and each section has questions. I made each section its own livewire component (see simplified version below), but wired them all up to the same wire:sort:group. When I move a question, the moveQuestion() method is only triggered on the receiving section. I have the $this->section parent info available on that component, so I can tell which section should now have the question.

Hopefully this code below feels straightforward?

<?php

use App\Models\FormSection;
use Livewire\Component;


new class extends Component
{
    public FormSection $section;

    public function moveQuestion(string $item, $position)
    {
        dd($this->section->id);

        // Insert DB reordering logic here (as we now have $item, $position, and parent ($section))
    }
};
?>

<div wire:sort="moveQuestion" wire:sort:group="questions">
    @foreach($section->questions as $question)
    <div class="m-4" wire:sort:item="{{ $question->id }}">
            {{ $question->question }}
    </div>
    @endforeach
</div> 
Swaz's avatar
Level 20

Omg, thanks so much for this!! 🙌 This works and it's super easy, I feel so dumb now.

They key is having the sortable group be its own component. Livewire has so much magic, my brain didn't think sorting would work across different components.

Swaz's avatar
Level 20

Beauty, thanks for sharing!

Please or to participate in this conversation.