ActionButton

Наследует MoonShineComponent * имеет те же возможности

# Основы

Когда Вам необходимо добавить кнопку с определенным действием, на помощь приходят ActionButton. В MoonShine они уже используются - в формах, таблицах, на страницах.

ActionButton::make(
Closure|string $label,
Closure|string|null $url = null,
mixed $item = null
)
  • label - текст кнопки,
  • url - url ссылки у кнопки,
  • item - опциональные данные кнопки, доступные в замыканиях.
use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Button title',
url: 'https://moonshine-laravel.com',
)
];
}

Также доступен helper, который можно применить в blade:

<div>
{!! actionBtn('Click me', 'https://moonshine-laravel.com') !!}
</div>
Example

# Blank

Метод blank() позволяет открывать url в новом окне.

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: fn() => 'Click me',
url: 'https://moonshine-laravel.com',
)
->blank()
];
}
Example

# Icon

Метод icon() позволяет указать иконку у кнопки.

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: fn() => 'Click me',
url: 'https://moonshine-laravel.com',
)
->icon('heroicons.outline.pencil')
];
}
Example

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

# Цвет

Для ActionButton есть набор методов которые позволяют задать цвет кнопки: primary(), secondary(), warning(), success() и error().

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: fn() => 'https://moonshine-laravel.com',
)
->primary()
];
}
Primary Secondary Warning Success Error

# Значок

Метод badge() позволяет добавить значок в кнопку.

badge(Closure|string|int|float|null $value)
use MoonShine\ActionButtons\ActionButton;
 
//...
 
ActionButton::make('Button')
->badge(fn() => Comment::count())
 
//...
Button 25

# onClick

Метод onClick позволяет выполнить js код по клику:

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: 'https://moonshine-laravel.com',
)
->onClick(fn() => "alert('Example')", 'prevent')
];
}
Example
Basics

Для того, чтобы по клику на кнопку произошел вызов модального окна, воспользуйтесь методом inModal().

inModal(
Closure|string|null $title = null,
Closure|string|null $content = null,
array $buttons = [],
bool $async = false,
bool $wide = false,
bool $auto = false,
bool $closeOutside = false,
array $attributes = [],
bool $autoClose = true,
)
  • title - заголовок окна,
  • content - контент модального окна,
  • buttons - кнопки модального окна,
  • async - асинхронный режим,
  • wide - максимальная ширина модального окна,
  • auto - ширина модального окна по контенту,
  • closeOutside - закрывать модальное окно при клике вне области окна,
  • attributes - дополнительные атрибуты,
  • autoClose - автозакрытие модального окна после успешного запроса.
use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: 'https://moonshine-laravel.com',
)
->inModal(
title: fn() => 'Modal title',
content: fn() => 'Modal content',
buttons: [
ActionButton::make('Click me in modal', 'https://moonshine-laravel.com')
],
async: false
)
];
}

Вы также можете открыть модальное окно с помощью метода toggleModal, а если ActionButton находится внутри модального окна то просто openModal

use MoonShine\ActionButtons\ActionButton;
use MoonShine\Components\Modal;
 
public function components(): array
{
return [
MoonShine\Components\Modal::make(
'Title',
fn() => 'Content',
)->name('my-modal')
 
ActionButton::make(
label: 'Open modal',
url: '#',
)->toggleModal('my-modal')
];
}
Async

Если требуется подгрузить контент в модальное окно асинхронно, то переключите параметр async в true.

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: to_page('action_button', fragment: 'doc-content'),
)
->inModal(
title: fn() => 'Modal title',
async: true
)
];
}

О Fragment можно узнать в разделе "Components"

# Confirm

Метод withConfirm() позволяет создать кнопку с подтверждением действия.

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: 'https://moonshine-laravel.com',
)
->withConfirm(
'Confirm modal title',
'Confirm modal content',
'Confirm modal button',
)
];
}

withConfirm не работает с async режимами. Для асинхронного режима, необходимо сделать свою реализацию через Modal или inModal() .

# Offcanvas

Для того, чтобы по клику на кнопку произошел вызов offcanvas, воспользуйтесь методом inOffCanvas().

use MoonShine\ActionButtons\ActionButton;
 
public function components(): array
{
return [
ActionButton::make(
label: 'Click me',
url: 'https://moonshine-laravel.com',
)
->inOffCanvas(
fn() => 'OffCanvas title',
fn() => form()->fields([Text::make('Text')]),
isLeft: false
)
];
}

# Группы

Если Вам необходимо выстроить логику с несколькими ActionButton, при этом некоторые должны быть скрыты или отображаться в выпадающем меню, в таком случае воспользуйтесь компонентом ActionGroup

use MoonShine\ActionButtons\ActionButton;
use MoonShine\Components\ActionGroup;
 
public function components(): array
{
return [
ActionGroup::make([
ActionButton::make('Button 1', '/')->canSee(fn() => false),
ActionButton::make('Button 2', '/', $model)->canSee(fn($model) => $model->active)
])
];
}
Отображение

Вы также благодаря ActionGroup можете изменить отображение кнопок, отображать их в линию или же в выпадающем меню для экономии места.

use MoonShine\ActionButtons\ActionButton;
use MoonShine\Components\ActionGroup;
 
public function components(): array
{
return [
ActionGroup::make([
ActionButton::make('Button 1', '/')->showInLine(),
ActionButton::make('Button 2', '/')->showInDropdown()
])
];
}

# Bulk

Метод bulk() позволяет создать кнопку для массовых действий для ModelResource.

public function indexButtons(): array
{
return [
ActionButton::make('Link', '/endpoint')->bulk(),
];
}

Метод bulk(), используется только внутри ModelResource.

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

Метод async() позволяет реализовать асинхронный режим работы для ActionButton.

async(
string $method = 'GET',
?string $selector = null,
array $events = []
?string $callback = null
)
  • $method - метод асинхронного запроса;
  • $selector - selector элемента у которого будет изменяться контент;
  • $events - вызываемые события после успешного запроса;
  • $callback - js callback функция после получения ответа.
public function components(): array
{
return [
ActionButton::make(
'Click me',
'/endpoint'
)
->async()
];
}
Уведомления

Если Вам необходимо после клика отобразить уведомление или сделать редирект, то достаточно реализовать json ответ по структуре:

{message: 'Toast', messageType: 'success', redirect: '/url'}

Параметр redirect не является обязательным.

HTML контент

Если требуется по клику заменить область с html, то вы можете в ответе вернуть HTML контент или json с ключом html:

{html: 'Html content'}
public function components(): array
{
return [
ActionButton::make(
'Click me',
'/endpoint'
)
->async(selector: '#my-selector')
];
}
События

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

public function components(): array
{
return [
ActionButton::make(
'Click me',
'/endpoint'
)
->async(events: ['table-updated-index-table'])
];
}

Для работы события table-updated-index-table должен быть включен асинхронный режим .

Callback

Если необходимо обработать ответ иным способом, то необходимо реализовать функцию-обработчик и указать ее в методе async().

public function components(): array
{
return [
ActionButton::make(
'Click me',
'/endpoint'
)
->async(callback: 'myFunction')
];
}
document.addEventListener("moonshine:init", () => {
MoonShine.onCallback('myFunction', function(response, element, events, component) {
if(response.confirmed === true) {
component.$dispatch('toast', {type: 'success', text: 'Success'})
} else {
component.$dispatch('toast', {type: 'error', text: 'Error'})
}
})
})

# Вызов методов

method() позволяют указать название метода в ресурсе и асинхронно вызывать его при клике по ActionButton без необходимости создавать дополнительные контроллеры.

method(
string $method,
array|Closure $params = [],
?string $message = null,
?string $selector = null,
array $events = [],
string|AsyncCallback|null $callback = null,
?Page $page = null,
?ResourceContract $resource = null
)
  • $method - наименование метода,
  • $params - параметры для запроса,
  • $message - сообщения,
  • $selector - selector элемента у которого будет изменяться контент,
  • $events - вызываемые события после успешного запроса,
  • $callback - js callback функция после получения ответа,
  • $page - страница содержащая метод,
  • $resource - ресурс содержащий метод.
public function components(): array
{
return [
ActionButton::make('Click me')
->method('updateSomething'),
];
}
// With toast
public function updateSomething(MoonShineRequest $request)
{
// $request->getResource();
// $request->getResource()->getItem();
// $request->getPage();
 
MoonShineUI::toast('MyMessage', 'success');
 
return back();
}
 
// Exception
public function updateSomething(MoonShineRequest $request)
{
throw new \Exception('My message');
}
 
// Custom json response
public function updateSomething(MoonShineRequest $request)
{
return MoonShineJsonResponse::make()->toast('MyMessage', ToastType::SUCCESS);
}

Методы в вызываемые через ActionButton в ресурсе должны быть публичными!

Для доступа к данным из реквеста, необходимо передать их в параметрах.

Передача текущего элемента

Если в запросе присутствует resourceItem, то в ресурсе вы можете получить доступ к текущему элементу через метод getItem().

  • Когда в данных присутствует модель и кнопка создается в методе buttons() TableBuilder , CardsBuilder или FormBuilder , то она автоматически наполняется данными и в параметрах будет resourceItem.
  • Когда кнопка находится на странице формы ModelResource то можно передать id текущего элемента.
    ActionButton::make('Click me')
    ->method(
    'updateSomething',
    params: ['resourceItem' => $this->getResource()->getItemID()]
    )
  • Когда кнопка находится в индексной таблице ModelResource, то необходимо воспользоваться замыканием.
    ActionButton::make('Click me')
    ->method(
    'updateSomething',
    params: fn($item) => ['resourceItem' => $item->getKey()]
    )
Передача параметров

Метод withParams() позволяет передать с запросом значения полей, используя селекторы элементов.

ActionButton::make('Async method')
->method('updateSomething')
->withParams([
'alias' => '[data-column="title"]',
'slug' => '#slug'
]),
use MoonShine\Http\Responses\MoonShineJsonResponse;
use MoonShine\MoonShineRequest;
 
public function updateSomething(MoonShineRequest $request): MoonShineJsonResponse
{
return MoonShineJsonResponse::make()
->toast($request->get('slug', 'Error'));
}

При использовании метода withParams() запросы будут отправляться через POST.

Скачивание файла

Вызываемый метод может возвращать BinaryFileResponse, что позволяет реализовать скачивание файла.

ActionButton::make('Download')->method('download')
public function download(): BinaryFileResponse
{
// ...
 
return response()->download($file);
}

# Вызов событий

Для вызова событий javascript можно воспользоваться методом dispatchEvent().

dispatchEvent(array|string $events)
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, 'index-table')),
По умолчанию при вызове события с запросом будут отправлены все query параметры из href у ActionButton. Некоторые исключить можно через параметр exclude:
->dispatchEvent(
AlpineJs::event(JsEvent::TABLE_UPDATED, 'index-table'),
exclude: ['something']
)
Также можно полностью исключить отправку withoutPayload:
->dispatchEvent(
AlpineJs::event(JsEvent::TABLE_UPDATED, 'index-table'),
withoutPayload: true
)