FormBuilder

# Основы

Поля и декорации в MoonShine используются внутри форм, за которые отвечает 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'])

Также доступен helper:

{!! 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'),
])
->cast(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: 'Click me', 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('Delete', 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 fragment по его имени.

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

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

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

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

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

# Precognitive

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

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

# Apply

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

apply(
Closure $apply,
?Closure $default = null,
?Closure $before = null,
?Closure $after = null,
bool $throw = false,
)
  • $apply - callback функция,
  • $default - apply для поля по умолчанию,
  • $before - callback функция до apply,
  • $after - callback функция после apply,
  • $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'),
];
}
// 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);
}

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

Для вызова событий 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('Save')->dispatchEvent(AlpineJs::event(JsEvent::FORM_SUBMIT, $this->uriKey()))
];
}

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