Поле для выбора нескольких значений.
Подойдет для работы со связями ресурса, но можно выводить и любые произвольные данные.
В livewire компоненте нужно определить 2 поля:
поле со списком доступных вариантов в multiselect
поле с выбранными значениями
Multiselect без сортировки
Для примера выведем поле для выбора категорий поста.
posts
id - integer
title - string
categories
id - integer
title - string
post_category
post_id - integer
category_id - integer
Код livewire компонента:
<?php
namespace App\Http\Livewire\Admin\Posts;
use App\Models\Category;
use App\Models\Post;
use WebVovan\RockCms\Http\Livewire\ResourceComponent;
class PostItem extends ResourceComponent
{
...
// Список доступных категорий
public array $categories;
// Список выбранных категорий
public array $selectedCategories;
public function init()
{
...
// Инициализация списка доступных категорий
$this->categories = Category::all()
->map(function($category) {
return [
'id' => $category->id,
'title' => $category->title,
];
})->toArray();
// Инициализация списка выбранных категорий
$this->selectedCategories = $this->resource->categories
->pluck('id')
->toArray();
}
public function save()
{
...
// Сохранение выбранных категорий
$this->resource->categories()->sync($this->selectedCategories);
}
}
Вывод поля в шаблоне:
<x-rock-cms::fields.multiselect
:items="$categories"
:selectedItems="$selectedCategories"
itemsField="categories"
selectedItemsField="selectedCategories"
title="Категории"
/>
Опции:
items - массив с доступными вариантами
selectedItems - массив с выбранными вариантами
itemsField - название поля с доступными вариантами
selectedItemsField - название поля с выбранными вариантами
Multiselect с сортировкой
Для поддержки сортировки добавим в таблицу post_category поле order.
posts
id - integer
title - string
categories
id - integer
title - string
post_category
post_id - integer
category_id - integer
order - integer
В коде компонента подключим трейты HasSortable и HasMultiselect.
<?php
namespace App\Http\Livewire\Admin\Posts;
use App\Models\Category;
use App\Models\Post;
use WebVovan\RockCms\Http\Livewire\ResourceComponent;
use WebVovan\RockCms\Traits\Livewire\HasMultiselect;
use WebVovan\RockCms\Traits\Livewire\HasSortable;
class PostItem extends ResourceComponent
{
use HasSortable;
use HasMultiselect;
// Список доступных категорий
public array $categories;
// Список выбранных категорий
public array $selectedCategories;
public function init()
{
...
// Инициализация списка доступных категорий
$this->categories = Category::all()
->map(function($category) {
return [
'id' => $category->id,
'title' => $category->title,
];
})->toArray();
// Инициализация списка выбранных категорий
$this->selectedCategories = $this->resource->categories
->map(function ($category) {
return [
'id' => $category->id,
'title' => $category->title,
];
})->toArray();
}
public function save()
{
...
// Сохранение выбранных категорий
$this->resource->categories()->sync(
collect($this->selectedCategories)->reduce(function($acc, $item, $key) {
$acc[$item['id']] = ['order' => $key];
return $acc;
}, [])
);
}
}
Для поддержки сортировки в шаблоне вывода нужно добавить опцию sortable:
<x-rock-cms::fields.multiselect
:items="$categories"
:selectedItems="$selectedCategories"
itemsField="categories"
selectedItemsField="selectedCategories"
sortable
title="Категории"
/>
Динамический поиск
Если данных для вывода в multiselect очень много, то можно при инициализации передать ограниченный набор, а остальное искать динамически.
Динамический поиск работает только при использовании сортировки.
В компоненте дополнительно определим метод searchCategories() для поиска категорий, которые будут выводиться в списке.
<?php
namespace App\Http\Livewire\Admin\Posts;
use App\Models\Category;
use App\Models\Post;
use WebVovan\RockCms\Http\Livewire\ResourceComponent;
use WebVovan\RockCms\Traits\Livewire\HasMultiselect;
use WebVovan\RockCms\Traits\Livewire\HasSortable;
class PostItem extends ResourceComponent
{
use HasSortable;
use HasMultiselect;
// Список доступных категорий
public array $categories;
// Список выбранных категорий
public array $selectedCategories;
/**
* Поиск категорий для multiselect
*
* @param string $word
*/
public function searchCategories(string $word)
{
$this->categories = Category::where('title', 'like', '%' . $word . '%')
->limit(5)
->get()
->map(function($item) {
return [
'id' => $item->id,
'title' => $item->title,
];
})->toArray();
}
public function init()
{
...
// При инициализации в multiselect показываем только 5 последних категорий
$this->categories = Category::limit(5)
->orderByDesc('id')
->get()
->map(function($category) {
return [
'id' => $category->id,
'title' => $category->title,
];
})->toArray();
// Инициализация списка выбранных категорий
$this->selectedCategories = $this->resource->categories
->map(function ($category) {
return [
'id' => $category->id,
'title' => $category->title,
];
})->toArray();
}
public function save()
{
...
// Сохранение выбранных категорий
$this->resource->categories()->sync(
collect($this->selectedCategories)->reduce(function($acc, $item, $key) {
$acc[$item['id']] = ['order' => $key];
return $acc;
}, [])
);
}
}
При выводе поля в шаблоне в свойстве liveSearch указываем метод для динамического поиска:
<x-rock-cms::fields.multiselect
:items="$categories"
:selectedItems="$selectedCategories"
itemsField="categories"
selectedItemsField="selectedCategories"
liveSearch="searchCategories"
sortable
title="Категории"
/>