Директива wire:sort:handle
Директива wire:sort:handle используется совместно с директивой wire:sort
для создания интерактивных списков с возможностью сортировки перетаскиванием.
Она вешается на дочерний элемент внутри сортируемого блока и определяет,
какую именно область можно захватывать мышью для перетаскивания.
Это особенно полезно, когда нужно ограничить зону захвата только определенной
частью элемента, например, иконкой или заголовком.
Синтаксис
<div wire:sort="methodName">
<div wire:sort:handle>
Зона захвата
</div>
Контент элемента
</div>
Пример
Давайте создадим сортируемый список задач, где перетаскивание будет доступно только по иконке:
<?php
namespace AppLivewire;
use LivewireComponent;
class TaskList extends Component
{
public $tasks = [
['id' => 1, 'name' => 'Задача 1'],
['id' => 2, 'name' => 'Задача 2'],
['id' => 3, 'name' => 'Задача 3'],
['id' => 4, 'name' => 'Задача 4'],
];
public function sortTasks($orderedIds)
{
$sorted = [];
foreach ($orderedIds as $id) {
foreach ($this->tasks as $task) {
if ($task['id'] == $id) {
$sorted[] = $task;
break;
}
}
}
$this->tasks = $sorted;
}
public function render()
{
return view('livewire.task-list');
}
}
?>
<div>
<ul>
@foreach ($tasks as $task)
<li wire:sort="sortTasks" wire:key="task-{{ $task['id'] }}">
<div wire:sort:handle>
☰ <!-- иконка меню -->
</div>
<span>{{ $task['name'] }}</span>
</li>
@endforeach
</ul>
</div>
Результат выполнения кода:
<ul>
<li>
<div>☰</div>
<span>Задача 1</span>
</li>
<li>
<div>☰</div>
<span>Задача 2</span>
</li>
<li>
<div>☰</div>
<span>Задача 3</span>
</li>
<li>
<div>☰</div>
<span>Задача 4</span>
</li>
</ul>
Пример
Пример с карточками, где захват осуществляется только за заголовок:
<?php
namespace AppLivewire;
use LivewireComponent;
class NoteList extends Component
{
public $notes = [
['id' => 1, 'title' => 'Заметка 1', 'content' => 'Содержимое заметки 1'],
['id' => 2, 'title' => 'Заметка 2', 'content' => 'Содержимое заметки 2'],
['id' => 3, 'title' => 'Заметка 3', 'content' => 'Содержимое заметки 3'],
];
public function sortNotes($orderedIds)
{
$sorted = [];
foreach ($orderedIds as $id) {
foreach ($this->notes as $note) {
if ($note['id'] == $id) {
$sorted[] = $note;
break;
}
}
}
$this->notes = $sorted;
}
public function render()
{
return view('livewire.note-list');
}
}
?>
<div>
<div wire:sort="sortNotes">
@foreach ($notes as $note)
<div wire:sort:item="{{ $note['id'] }}" wire:key="note-{{ $note['id'] }}">
<div wire:sort:handle style="cursor:grab; background:#f0f0f0; padding:5px;">
{{ $note['title'] }}
</div>
<div style="padding:10px;">
{{ $note['content'] }}
</div>
</div>
@endforeach
</div>
</div>
Результат выполнения кода:
<div>
<div>
<div>
<div>Заметка 1</div>
<div>Содержимое заметки 1</div>
</div>
<div>
<div>Заметка 2</div>
<div>Содержимое заметки 2</div>
</div>
<div>
<div>Заметка 3</div>
<div>Содержимое заметки 3</div>
</div>
</div>
</div>
Пример
Пример с таблицей, где перетаскивание строк доступно только по иконке в первой колонке:
<?php
namespace AppLivewire;
use LivewireComponent;
class ProductTable extends Component
{
public $products = [
['id' => 1, 'name' => 'Product A', 'price' => 100],
['id' => 2, 'name' => 'Product B', 'price' => 200],
['id' => 3, 'name' => 'Product C', 'price' => 300],
];
public function sortProducts($orderedIds)
{
$sorted = [];
foreach ($orderedIds as $id) {
foreach ($this->products as $product) {
if ($product['id'] == $id) {
$sorted[] = $product;
break;
}
}
}
$this->products = $sorted;
}
public function render()
{
return view('livewire.product-table');
}
}
?>
<div>
<table>
<thead>
<tr>
<th></th>
<th>Название</th>
<th>Цена</th>
</tr>
</thead>
<tbody wire:sort="sortProducts">
@foreach ($products as $product)
<tr wire:sort:item="{{ $product['id'] }}" wire:key="product-{{ $product['id'] }}">
<td>
<div wire:sort:handle style="cursor:grab;">
☰
</div>
</td>
<td>{{ $product['name'] }}</td>
<td>{{ $product['price'] }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
Результат выполнения кода:
<table>
<thead>
<tr>
<th></th>
<th>Название</th>
<th>Цена</th>
</tr>
</thead>
<tbody>
<tr>
<td>☰</td>
<td>Product A</td>
<td>100</td>
</tr>
<tr>
<td>☰</td>
<td>Product B</td>
<td>200</td>
</tr>
<tr>
<td>☰</td>
<td>Product C</td>
<td>300</td>
</tr>
</tbody>
</table>
Смотрите также
-
директиву
wire:sort,
которая включает сортировку для контейнера -
директиву
wire:sort:item,
которая помечает элемент как сортируемый -
директиву
wire:sort:group,
которая группирует сортируемые элементы -
директиву
wire:sort:ignore,
которая исключает элемент из сортировки