Advanced

FormBuilder

Основы

Поля и декорации в FormBuilder используются внутри форм, которые обрабатываются FormBuilder. Благодаря FormBuilder поля отображаются и заполняются данными. Вы также можете использовать FormBuilder на своих собственных страницах или даже за пределами MoonShine.

make(
string $action = '',
string $method = 'POST',
Fields|array $fields = [],
array $values = []
)
  • action - обработчик
  • method - тип запроса,
  • fields - поля и декорации.
  • values - значения полей.
FormBuilder::make(
action:'/crud/update',
method: 'PUT',
fields: [
Text::make('Text')
],
values: ['text' => 'Value']
)

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

FormBuilder::make()
->action('/crud/update')
->method('PUT')
->fields([
Text::make('Text')
])
->fill(['text' => 'Value'])

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

{!! form(request()->url(), 'GET')
->fields([
Text::make('Text')
])
->fill(['text' => 'Value'])
!!}

Поля

Метод fields() для объявления полей формы и декораций:

fields(Fields|Closure|array $fields)
FormBuilder::make('/crud/update', 'PUT')
->fields([
Heading::make('Title'),
Text::make('Text'),
])

Заполнение полей

Метод fill() для заполнения полей значениями:

fill(mixed $values = [])
FormBuilder::make('/crud/update', 'PUT')
->fields([
Heading::make('Title'),
Text::make('Text'),
])
->fill(['text' => 'value'])

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

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

cast(MoonShineDataCast $cast)
use MoonShine\TypeCasts\ModelCast;
 
FormBuilder::make('/crud/update', 'PUT')
->fields([
Heading::make('Title'),
Text::make('Text'),
])
->fillCast(
['text' => 'value'],
ModelCast::make(User::class)
)

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

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

FillCast

Метод fillCast() позволяет привести данные к определенному типу и сразу заполнить их значениями:

fillCast(mixed $values, MoonShineDataCast $cast)
use MoonShine\TypeCasts\ModelCast;
 
FormBuilder::make('/crud/update', 'PUT')
->fields([
Heading::make('Title'),
Text::make('Text'),
])
->fillCast(
['text' => 'value'],
ModelCast::make(User::class)
)

или

use MoonShine\TypeCasts\ModelCast;
 
FormBuilder::make('/crud/update', 'PUT')
->fields([
Heading::make('Title'),
Text::make('Text'),
])
->fillCast(
User::query()->first(),
ModelCast::make(User::class)
)

Кнопки

Кнопки формы можно модифицировать и добавлять.

Для настройки кнопки "submit" используйте метод submit().

submit(string $label, array $attributes = [])
  • label - название кнопки,
  • attributes - дополнительные атрибуты
FormBuilder::make('/crud/update', 'PUT')
->submit(label: 'Нажми меня', attributes: ['class' => 'btn-primary'])

Метод hideSubmit() позволяет скрыть кнопку "submit".

FormBuilder::make('/crud/update', 'PUT')
->hideSubmit()

Для добавления новых кнопок на основе ActionButton используйте метод buttons()

buttons(array $buttons = [])
FormBuilder::make('/crud/update', 'PUT')
->buttons([
ActionButton::make('Удалить', route('name.delete'))
])

Атрибуты

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

FormBuilder::make()
->customAttributes(['class' => 'custom-form'])

Имя формы

Метод name() позволяет установить уникальное имя для формы, через которое можно вызывать события.

FormBuilder::make('/crud/update', 'PUT')
->name('main-form')

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

Если необходимо отправить форму асинхронно, используйте метод async().

async(
?string $asyncUrl = null,
string|array|null $asyncEvents = null,
?string $asyncCallback = null
)
  • asyncUrl - url запроса (по умолчанию запрос отправляется по url action),
  • asyncEvents - события, поднимаемые после успешного запроса,
  • asyncCallback - js callback функция после получения ответа.
FormBuilder::make('/crud/update', 'PUT')
->async()

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

FormBuilder::make('/crud/update', 'PUT')
->name('main-form')
->async(asyncEvents: ['table-updated-crud', 'form-reset-main-form'])

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

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

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

Отображение ошибок валидации

По умолчанию ошибки валидации отображаются в верхней части формы.

Метод errorsAbove(bool $enable = true) используется для управления отображением ошибок валидации в верхней части формы. Он позволяет включить или отключить эту функцию.

FormBuilder::make('/crud/update', 'PUT')
->errorsAbove(false)

Прекогнитивная валидация

Если необходимо сначала выполнить прекогнитивную валидацию, вам нужен метод precognitive().

FormBuilder::make('/crud/update', 'PUT')
->precognitive()

Применение

Метод apply() в FormBuilder итерирует все поля формы и вызывает их методы apply.

apply(
Closure $apply,
?Closure $default = null,
?Closure $before = null,
?Closure $after = null,
bool $throw = false,
)
  • $apply - функция обратного вызова;
  • $default - применение для поля по умолчанию;
  • $before - функция обратного вызова перед применением;
  • $after - функция обратного вызова после применения;
  • $throw - выбрасывать исключения.

Примеры

Необходимо сохранить данные всех полей FormBuilder в контроллере:

$form->apply(fn(Model $item) => $item->save());

Более сложный вариант, с указанием событий до и после сохранения:

$form->apply(
static fn(Model $item) => $item->save(),
before: function (Model $item) {
if (! $item->exists) {
$item = $this->beforeCreating($item);
}
 
if ($item->exists) {
$item = $this->beforeUpdating($item);
}
 
return $item;
},
after: function (Model $item) {
$wasRecentlyCreated = $item->wasRecentlyCreated;
 
$item->save();
 
if ($wasRecentlyCreated) {
$item = $this->afterCreated($item);
}
 
if (! $wasRecentlyCreated) {
$item = $this->afterUpdated($item);
}
 
return $item;
},
throw: true
);

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

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

public function components(): array
{
return [
FormBuilder::make()
->asyncMethod('updateSomething'),
];
}
// С уведомлением
public function updateSomething(MoonShineRequest $request)
{
// $request->getResource();
// $request->getResource()->getItem();
// $request->getPage();
 
MoonShineUI::toast('Мое сообщение', 'success');
 
return back();
}
 
// Исключение
public function updateSomething(MoonShineRequest $request)
{
throw new \Exception('Мое сообщение');
}
 
// Пользовательский json ответ
public function updateSomething(MoonShineRequest $request)
{
return MoonShineJsonResponse::make()->toast('Мое сообщение', ToastType::SUCCESS);
}

Отправка событий

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

dispatchEvent(array|string $events)
FormBuilder::make()
->dispatchEvent(JsEvent::OFF_CANVAS_TOGGLED, 'default'),

По умолчанию при вызове события с запросом будут отправлены все данные формы. Если форма большая, то может потребоваться исключить набор полей. Исключить можно через параметр exclude:

->dispatchEvent(
AlpineJs::event(JsEvent::OFF_CANVAS_TOGGLED, 'default'),
exclude: ['text', 'description']
)

Также можно полностью исключить отправку данных через параметр withoutPayload:

->dispatchEvent(
AlpineJs::event(JsEvent::OFF_CANVAS_TOGGLED, 'default'),
withoutPayload: true
)

Событие "Submit"

Для отправки формы можно вызвать событие Submit.

AlpineJs::event(JsEvent::FORM_SUBMIT, 'componentName')

Пример вызова события на странице формы

public function formButtons(): array
{
return [
ActionButton::make('Сохранить')->dispatchEvent(AlpineJs::event(JsEvent::FORM_SUBMIT, $this->uriKey()))
];
}

Для получения дополнительной информации о помощниках AlpineJs обратитесь к разделу Js events.