# Основы
Поле BelongsToMany предназначено для работы с одноименным отношением в Laravel и включает в себя все базовые методы.
Для создания данного поля используется статический метод make()
.
BelongsToMany::make( Closure|string $label, ?string $relationName = null, Closure|string|null $formatted = null, ?ModelResource $resource = null)
$label
- лейбл, заголовок поля,$relationName
- название отношения,$formatted
- замыкание или поле в связанной таблице для отображения значений,$resource
- ресурс модели на которую ссылается отношение.
Наличие ресурса модели, на которую ссылается отношение, обязательно!
Ресурс также необходимо
зарегистрировать
в сервис провайдере MoonShineServiceProvider в методе
menu()
или resources()
. Иначе, будет 404 ошибка.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', 'categories', resource: new CategoryResource()) ];} //...
Если не указать $relationName
,
то название отношения будет определено автоматически на основе $label
.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ];} //...
Можно не указывать $resource
, если ресурс модели соответствует названию отношения.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', 'categories') ];} //...
По умолчанию для отображения значения используется поле в связанной таблице,
которое задано свойством $column
в ресурсе модели.
Аргумент $formatted
позволяет это переопределить.
namespace App\MoonShine\Resources; use MoonShine\Resources\ModelResource; class CategoryResource extends ModelResource{ //... public string $column = 'title'; //...}
Если необходимо задать более сложное значение для отображения,
то аргументу $formatted
можно передать callback функцию.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make( 'Categories', 'categories', fn($item) => "$item->id. $item->title" ) ];} //...
# Заголовок столбца
По умолчанию в качестве заголовка столбца таблицы используется свойство
$title
ресурса модели отношения.
Метод columnLabel()
позволяет переопределить заголовок.
columnLabel(string $label)
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->columnLabel('Title') ];} //...
# Pivot
Метод fields()
используется для реализации pivot полей у отношения BelongsToMany.
fields(Fields|Closure|array $fields)
use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Text; //... public function fields(): array{ return [ BelongsToMany::make('Contacts', resource: new ContactResource()) ->fields([ Text::make('Contact', 'text'), ]) ];} //...
У отношения необходимо указать какие pivot поля используются в промежуточной таблице!
Подробнее в официальной документации
Laravel
.
# Создание объекта отношения
Метод creatable()
позволяет создавать новый объект отношения через модальное окно.
creatable( Closure|bool|null $condition = null, ?ActionButton $button = null,)
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->creatable() ];} //...
Кастомизировать кнопку создания можно передав методу параметр button.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->creatable( button: ActionButton::make('Custom button', '') ) ];} //...
# Select
Поле BelongsToMany можно отобразить в виде выпадающего списка,
для этого необходимо воспользоваться методом selectMode()
.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->selectMode() ];} //...
# Опции
Все опции choices доступны для изменения через data attributes:
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Countries', resource: new CountryResource()) ->selectMode() ->customAttributes([ 'data-max-item-count' => 2 ]) ];} //...
За более подробной информацией обратитесь к Choices .
# Placeholder
Метод placeholder()
позволяет задать у поля атрибут placeholder.
placeholder(string $value)
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Countries', 'countries') ->nullable() ->placeholder('Countries') ];} //...
Метод placeholder()
используется только,
если поле отображается в виде выпадающего списка selectMode()
!
# Tree
Метод tree()
позволять отобразить значения в виде дерева с чекбоксами,
например для категорий, которые имеют вложенность.
Методу необходимо передать столбец в базе данных по которому будет строиться дерево.
tree(string $parentColumn)
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->tree('parent_id') ];} //...
# Preview
По умолчанию в preview поле будет отображаться в виде таблицы.
Для того чтобы изменить отображение в preview можно воспользоваться следующими методами.
Метод onlyCount()
позволяет отобразить в preview только количество выбранных значений.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->onlyCount() ];} //...
Метод inLine()
позволяет отобразить значения поля в виде строки.
inLine(string $separator = '', Closure|bool $badge = false, ?Closure $link = null)
Методу можно передать необязательные параметры:
separator
- разделитель между элементами;badge
- замыкание или булево значение, отвечающее за отображение элемента в виде badge;$link
- замыкание которое должно вернуть url ссылки или компонент.
При передаче булевого значения true в параметр badge
будет использоваться цвет Primary
. Для изменения цвета, отображаемого badge
, используйте замыкание и возвращайте компонент Badge::make()
.
use MoonShine\Components\Link;use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->inLine( separator: ' ', badge: fn($model, $value) => Badge::make($value, 'color'), link: fn(Category $category, $value, $field) => Link::make( (new CategoryResource())->detailPageUrl($category), $value ) ) ];} //...
# Только ссылка
Метод onlyLink()
позволят отобразить отношение в виде ссылки с количеством элементов.
onlyLink(?string $linkRelation = null, Closure|bool|null $condition = null)
Методу можно передать необязательные параметры:
linkRelation
- ссылка на отношение;-
condition
- замыкание или булево значение, отвечающее за отображение отношения как ссылки.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->onlyLink() ];} //...
Параметр linkRelation
позволяет создать ссылку на отношение с привязкой родительского ресурса.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->onlyLink('category') ];} //...
Параметр condition
через замыкание позволят изменять способ отображения в зависимости от условий.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->onlyLink(condition: function (int $count, Field $field): bool { return $count > 10; }) ];} //...
# Запрос для значений
Методом valuesQuery()
позволяет изменить запрос на получение значений.
valuesQuery(Closure $callback)
use Illuminate\Contracts\Database\Eloquent\Builder; use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', 'categories', resource: new CategoryResource()) ->valuesQuery(fn(Builder $query, Field $field) => $query->where('active', true)) ];} //...
# Асинхронный поиск
Для реализации асинхронного поиска значений воспользуйтесь методом asyncSearch()
.
asyncSearch( string $asyncSearchColumn = null, int $asyncSearchCount = 15, ?Closure $asyncSearchQuery = null, ?Closure $asyncSearchValueCallback = null, ?string $associatedWith = null, ?string $url = null, bool $replaceQuery = false,)
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Countries', 'countries', resource: new CountryResource()) ->asyncSearch() ];} //...
Поиск будет осуществляться по полю отношения ресурса column
. По умолчанию column=id
.
В метод asyncSearch()
можно передавать параметры:
$asyncSearchColumn
- поле по которому происходит поиск;$asyncSearchCount
- количество элементов в выдаче;$asyncSearchQuery
- callback-функция для фильтрации значений;$asyncSearchValueCallback
- callback-функция для кастомизации вывода;$associatedWith
- поле с которым необходимо установить связь;$url
- url для обработки асинхронного запроса,$replaceQuery
- заменить запрос.
use Illuminate\Contracts\Database\Eloquent\Builder; use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Countries', 'countries', resource: new CountryResource()) ->asyncSearch( 'title', 10, asyncSearchQuery: function (Builder $query, Request $request, Field $field) { return $query->where('id', '!=', 2); }, asyncSearchValueCallback: function ($country, Field $field) { return $country->id . ' | ' . $country->title; }, 'https://moonshine-laravel.com/async' ) ];} //...
При построении запроса в asyncSearchQuery()
можно использовать текущие значения формы.
Для этого необходимо передать Request
в callback-функции.
use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Http\Request; use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select; //... public function fields(): array{ return [ Select::make('Country', 'country_id'), BelongsToMany::make('Cities', 'cities', resource: new CityResource()) ->asyncSearch( 'title', asyncSearchQuery: function (Builder $query, Request $request, Field $field): Builder { return $query->where('country_id', $request->get('country_id')); } ) ];} //...
При построении запроса в asyncSearchQuery()
исходное состояние builder сохраняется.
Если вам требуется заменить на свой builder, то воспользуйтесь флагом replaceQuery
.
use Illuminate\Contracts\Database\Eloquent\Builder; use Illuminate\Http\Request; use MoonShine\Fields\Relationships\BelongsToMany;use MoonShine\Fields\Select; //... public function fields(): array{ return [ Select::make('Country', 'country_id'), BelongsToMany::make('Cities', 'cities', resource: new CityResource()) ->asyncSearch( 'title', asyncSearchQuery: function (Builder $query, Request $request, Field $field): Builder { return $query->where('country_id', $request->get('country_id')); }, replaceQuery: true ) ];} //...
Запросы необходимо кастомизировать через метод asyncSearch()
.
Не используйте valuesQuery()
!
# Связанные поля
Для связывания значений селектов между полями можно воспользоваться методом associatedWith()
.
associatedWith(string $column, ?Closure $asyncSearchQuery = null)
$column
- поле с которым устанавливается связь;$asyncSearchQuery
- callback-функция для фильтрации значений.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Cities', 'cities', resource: new CityResource()) ->associatedWith('country_id') ];} //...
Для более сложной настройки можно использовать asyncSearch()
.
# Значения с изображением
Метод withImage()
позволяет добавить изображение к значению.
withImage( string $column, string $disk = 'public', string $dir = '')
$column
- поле с изображением;$disk
- диск файловой системы;$dir
- директория относительно корня диска.
use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make(Countries, resource: new CountryResource()) ->withImage('thumb', 'public', 'countries')->selectMode() ];} //...
# Кнопки
Метод buttons()
позволяет добавить дополнительные кнопки к полю BelongsToMany.
buttons(array $buttons)
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->buttons([ ActionButton::make('Check all', '') ->onClick(fn() => 'checkAll', 'prevent'), ActionButton::make('Uncheck all', '') ->onClick(fn() => 'uncheckAll', 'prevent') ]) ];} //...
Метод withCheckAll()
позволяет добавить кнопки checkAll/uncheckAll к полю BelongsToMany
аналогично предыдущему примеру.
use MoonShine\ActionButtons\ActionButton;use MoonShine\Fields\Relationships\BelongsToMany; //... public function fields(): array{ return [ BelongsToMany::make('Categories', resource: new CategoryResource()) ->withCheckAll() ];} //...