Advanced

TableBuilder

Основы

Поля и декорации в MoonShine используются внутри таблиц в режиме preview.
За таблицы отвечает TableBuilder.
С помощью TableBuilder отображаются таблицы и заполняются данными.
Вы также можете использовать TableBuilder на своих собственных страницах или даже вне MoonShine.

TableBuilder::make(
Fields|array $fields = [],
Paginator|iterable $items = [],
?Paginator $paginator = null
)
TableBuilder::make(
Fields|array $fields = [],
Paginator|iterable $items = [],
?Paginator $paginator = null
)

-$fields - поля, -$items - значения полей, -$paginator - объект пагинатора.

use MoonShine\Components\TableBuilder;
 
TableBuilder::make(
[Text::make('Text')],
[['text' => 'Value']]
)
use MoonShine\Components\TableBuilder;
 
TableBuilder::make(
[Text::make('Text')],
[['text' => 'Value']]
)

То же самое через методы:

TableBuilder::make()
->fields([Text::make('Text')])
->items([[ 'text' => 'Value' ]])
TableBuilder::make()
->fields([Text::make('Text')])
->items([[ 'text' => 'Value' ]])

Также доступен хелпер table():

{!!
table()
->fields([Text::make('Text')])
->items([['text' => 'Value']])
!!}
{!!
table()
->fields([Text::make('Text')])
->items([['text' => 'Value']])
!!}

Поля

Метод fields() позволяет указать список полей для построения таблицы:

TableBuilder::make()
->fields([
Text::make('Text'),
])
TableBuilder::make()
->fields([
Text::make('Text'),
])

Элементы

Метод items() используется для заполнения таблицы данными:

TableBuilder::make()
->fields([Text::make('Text')])
->items([[ 'text' => 'Value' ]])
TableBuilder::make()
->fields([Text::make('Text')])
->items([[ 'text' => 'Value' ]])

Соответствие данных с полями осуществляется через значение column полей!

Пагинатор

Метод paginator() для работы таблицы с пагинацией:

$paginator = Article::paginate();
 
TableBuilder::make()
->fields([Text::make('Text')])
->items($paginator->items())
->paginator($paginator)
$paginator = Article::paginate();
 
TableBuilder::make()
->fields([Text::make('Text')])
->items($paginator->items())
->paginator($paginator)

Или напрямую передать пагинатор:

TableBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])
TableBuilder::make(
items: Article::paginate()
)
->fields([Text::make('Text')])

TableBuilder работает с массивами элементов;

если у вас нет массивов, необходимо привести пагинатор к массивам:

$paginator = Article::paginate();
 
TableBuilder::make()
->fields([Text::make('Text')])
->items($paginator->through(fn($item) => $item->toArray()))
->paginator($paginator)
$paginator = Article::paginate();
 
TableBuilder::make()
->fields([Text::make('Text')])
->items($paginator->through(fn($item) => $item->toArray()))
->paginator($paginator)

Или вы можете использовать метод cast() вместо этого.

Приведение типов

Метод cast() используется для приведения значений таблицы к определенному типу.
Поскольку по умолчанию поля работают с примитивными типами:

use MoonShine\TypeCasts\ModelCast;
 
TableBuilder::make(items: User::paginate())
->fields([Text::make('Email')])
->cast(ModelCast::make(User::class))
use MoonShine\TypeCasts\ModelCast;
 
TableBuilder::make(items: User::paginate())
->fields([Text::make('Email')])
->cast(ModelCast::make(User::class))

В этом примере мы приводим данные к формату модели User с помощью ModelCast.

Для более подробной информации обратитесь к разделу TypeCasts.

Кнопки

Чтобы добавить новые кнопки на основе ActionButton, используйте метод buttons().
Кнопки будут добавлены для каждой строки, а при включенном режиме bulk() они будут отображаться в подвале для массовых действий:

TableBuilder::make(items: Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->cast(ModelCast::make(Article::class))
->buttons([
ActionButton::make('Delete', route('name.delete')),
ActionButton::make('Edit', route('name.edit'))->showInDropdown(),
ActionButton::make('Go to home', route('home'))->blank()->canSee(fn($data) => $data->active),
ActionButton::make('Mass Delete', route('name.mass_delete'))->bulk()
])
TableBuilder::make(items: Article::paginate())
->fields([ID::make(), Switcher::make('Active')])
->cast(ModelCast::make(Article::class))
->buttons([
ActionButton::make('Delete', route('name.delete')),
ActionButton::make('Edit', route('name.edit'))->showInDropdown(),
ActionButton::make('Go to home', route('home'))->blank()->canSee(fn($data) => $data->active),
ActionButton::make('Mass Delete', route('name.mass_delete'))->bulk()
])

Асинхронный режим

Если вам нужно получать данные из таблицы асинхронно (во время пагинации, сортировки), то используйте метод async():

async(
?string $asyncUrl = null,
string|array|null $asyncEvents = null,
?string $asyncCallback = null
)
async(
?string $asyncUrl = null,
string|array|null $asyncEvents = null,
?string $asyncCallback = null
)

-asyncUrl - url запроса, -asyncEvents - события, вызываемые после успешного запроса, -asyncCallback - js функция обратного вызова после получения ответа.

TableBuilder::make()
->async('/async_url')
TableBuilder::make()
->async('/async_url')

После успешного запроса вы можете поднять события, добавив параметр asyncEvents.

TableBuilder::make()
->name('crud')
->async(asyncEvents: ['table-updated-crud', 'form-reset-main-form'])
TableBuilder::make()
->name('crud')
->async(asyncEvents: ['table-updated-crud', 'form-reset-main-form'])

MoonShine уже имеет набор готовых событий:

  • table-updated-{name} - обновление асинхронной таблицы по ее имени,
  • form-reset-{name} - сброс значений формы по ее имени,
  • fragment-updated-{name} - обновление blade-фрагмента по его имени.

Метод async() должен идти после метода name()!

Атрибуты

Вы можете установить любые html-атрибуты для таблицы с помощью метода customAttributes():

TableBuilder::make()
->customAttributes(['class' => 'custom-table'])
TableBuilder::make()
->customAttributes(['class' => 'custom-table'])

Вы можете установить любые html-атрибуты для строк и ячеек таблицы:

TableBuilder::make()
->trAttributes(function(
mixed $data,
int $row,
ComponentAttributeBag $attributes
): ComponentAttributeBag {
return $attributes->merge(['class' => 'bgc-green']);
})
TableBuilder::make()
->trAttributes(function(
mixed $data,
int $row,
ComponentAttributeBag $attributes
): ComponentAttributeBag {
return $attributes->merge(['class' => 'bgc-green']);
})
TableBuilder::make()
->tdAttributes(
function(
mixed $data,
int $row,
int $cell,
ComponentAttributeBag $attributes
): ComponentAttributeBag {
return $attributes->merge(['class' => 'bgc-red']);
}
)
TableBuilder::make()
->tdAttributes(
function(
mixed $data,
int $row,
int $cell,
ComponentAttributeBag $attributes
): ComponentAttributeBag {
return $attributes->merge(['class' => 'bgc-red']);
}
)

Отсутствующие элементы

По умолчанию, если в таблице нет данных, она будет пустой, но вы можете отобразить сообщение "Записей пока нет".
Для этого используйте метод withNotFound():

TableBuilder::make()
->withNotFound()
TableBuilder::make()
->withNotFound()

Упрощенный стиль

По умолчанию таблица стилизована как MoonShine,
но с помощью метода simple() вы можете отобразить таблицу в упрощенном стиле:

TableBuilder::make()
->simple()
TableBuilder::make()
->simple()

Липкая шапка

Метод sticky() позволяет зафиксировать шапку при прокрутке таблицы с большим количеством элементов.

TableBuilder::make()
->sticky()
TableBuilder::make()
->sticky()

Предпросмотр

Метод preview() отключает отображение кнопок и сортировок для таблицы:

TableBuilder::make()
->preview()
TableBuilder::make()
->preview()

Вертикальный режим

С помощью метода vertical() вы можете отобразить таблицу в вертикальном режиме:

TableBuilder::make()
->vertical()
TableBuilder::make()
->vertical()

Добавление записей

С помощью метода creatable() вы можете создать кнопку "Добавить" для генерации новых записей в таблице:

creatable(
bool $reindex = true,
?int $limit = null,
?string $label = null,
?string $icon = null,
array $attributes = [],
?ActionButton $button = null
)
creatable(
bool $reindex = true,
?int $limit = null,
?string $label = null,
?string $icon = null,
array $attributes = [],
?ActionButton $button = null
)

-$reindex - режим редактирования с динамическим именем, -$limit - количество записей, которые можно добавить, -$label - название кнопки, -$icon - иконка кнопки, -$attributes - дополнительные атрибуты, -$button - пользовательская кнопка добавления.

TableBuilder::make()
->creatable(
icon: 'heroicons.outline.pencil',
attributes: ['class' => 'my-class']
)
->fields([
Text::make('Title'),
Text::make('Text')
])->items([
['title' => 'Value 1', 'text' => 'Value 2'],
['title' => '', 'text' => '']
])
TableBuilder::make()
->creatable(
icon: 'heroicons.outline.pencil',
attributes: ['class' => 'my-class']
)
->fields([
Text::make('Title'),
Text::make('Text')
])->items([
['title' => 'Value 1', 'text' => 'Value 2'],
['title' => '', 'text' => '']
])

В режиме добавления последний элемент должен быть пустым (скелет новой записи)!

Если таблица содержит поля в режиме редактирования с динамическим именем, то необходимо добавить метод или параметр reindex:

TableBuilder::make()
->creatable(reindex: true)
TableBuilder::make()
->creatable(reindex: true)

или

TableBuilder::make()
->creatable()
->reindex()
TableBuilder::make()
->creatable()
->reindex()

limit

Если вы хотите ограничить количество записей, которые можно добавить, необходимо указать параметр limit:

TableBuilder::make()
->creatable(limit: 6)
TableBuilder::make()
->creatable(limit: 6)

Пользовательская кнопка добавления

TableBuilder::make()
->creatable(
button: ActionButton::make('Foo', '#')
)
TableBuilder::make()
->creatable(
button: ActionButton::make('Foo', '#')
)

Редактируемые

По умолчанию поля в таблице отображаются в режиме preview,
но если вы хотите отобразить их как редактируемые элементы формы,
то необходимо использовать метод editable():

TableBuilder::make()
->editable()
TableBuilder::make()
->editable()

Сортируемые

Для сортировки строк в таблице используйте метод sortable():

TableBuilder::make()
->sortable(
url: '/update_indexes_endpoint',
key: 'id',
group: 'nested'
)
TableBuilder::make()
->sortable(
url: '/update_indexes_endpoint',
key: 'id',
group: 'nested'
)

-$url - обработчик url, -$key - ключ элемента, -$group - группировка.

TableBuilder::make()
->sortable(
url: '/update_indexes_endpoint',
key: 'id',
group: 'nested'
)
TableBuilder::make()
->sortable(
url: '/update_indexes_endpoint',
key: 'id',
group: 'nested'
)

Отображение колонок

Вы можете позволить пользователям решать, какие колонки отображать в таблице, сохраняя выбор.
Для этого необходимо установить параметр ресурса $columnSelection.

columnSelection(string $uniqueId = '')
columnSelection(string $uniqueId = '')

-$uniqueId - уникальный Id таблицы для сохранения выбора отображаемых колонок.

TableBuilder::make()
->fields([
Text::make('Title'),
Text::make('Text')
])
->columnSelection('unique-id')
TableBuilder::make()
->fields([
Text::make('Title'),
Text::make('Text')
])
->columnSelection('unique-id')

Если вам нужно исключить поля из выбора, используйте метод columnSelection().

public function columnSelection(bool $active = true)
public function columnSelection(bool $active = true)
TableBuilder::make()
->fields([
Text::make('Title')
->columnSelection(false),
Text::make('Text')
])
->columnSelection('unique-id')
TableBuilder::make()
->fields([
Text::make('Title')
->columnSelection(false),
Text::make('Text')
])
->columnSelection('unique-id')