Основы
Поля и компоненты в FormBuilder
используются внутри форм, которые обрабатываются FormBuilder
.
Благодаря FormBuilder
поля отображаются и заполняются данными.
FormBuilder
используется на странице редактирования, а также для полей отношений, таких как HasOne
.
Вы также можете использовать FormBuilder
на своих собственных страницах, в модальных окнах или даже за пределами MoonShine.
make( string $action = '', FormMethod $method = FormMethod::POST, FieldsContract|iterable $fields = [], mixed $values = [],)
action
- обработчик,method
- тип запроса,fields
- поля и компоненты,values
- значения полей.
FormBuilder::make( action:'/crud/update', method: FormMethod::POST, fields: [ Hidden::make('_method')->setValue('put') Text::make('Text') ], values: ['text' => 'Value']) // or FormBuilder::make() ->action('/crud/update') ->method(FormMethod::POST) ->fields([ Hidden::make('_method')->setValue('put') Text::make('Text') ]) ->fill(['text' => 'Value'])
<x-moonshine::formname="crud-form":errors="$errors"precognitive> <x-moonshine::form.input name="title" placeholder="Title" value="" /> <x-slot:buttons> <x-moonshine::form.button type="reset">Cancel</x-moonshine::form.button> <x-moonshine::form.button class="btn-primary">Submit</x-moonshine::form.button> </x-slot:buttons></x-moonshine::form>
Основные методы
Поля
Метод fields()
для объявления полей формы и компонентов:
fields(FieldsContract|Closure|iterable $fields)
FormBuilder::make('/crud/update') ->fields([ Heading::make('Title'), Text::make('Text'), ])
Имя формы
Метод name()
позволяет установить уникальное имя для формы, через которое можно вызывать события.
FormBuilder::make('/crud/update') ->name('main-form')
Заполнение полей
Метод fill()
для заполнения полей значениями:
fill(mixed $values = [])
FormBuilder::make('/crud/update') ->fields([ Heading::make('Title'), Text::make('Text'), ]) ->fill(['text' => 'value'])
Приведение типов
Метод cast()
для приведения значений формы к определенному типу.
Поскольку по умолчанию поля работают с примитивными типами.
cast(DataCasterContract $cast)
use MoonShine\Laravel\TypeCasts\ModelCaster; FormBuilder::make('/crud/update') ->fields([ Heading::make('Title'), Text::make('Text'), ]) ->values( ['text' => 'value'], ) ->cast(new ModelCaster(User::class))
В этом примере мы приводим данные к формату модели User
, используя ModelCaster
.
Для более подробной информации обратитесь к разделу TypeCasts.
Заполнение и приведение к типу
Метод fillCast()
позволяет привести данные к определенному типу и сразу заполнить их значениями.
fillCast( mixed $values, DataCasterContract $cast)
use MoonShine\TypeCasts\ModelCaster; FormBuilder::make('/crud/update') ->fields([ Heading::make('Title'), Text::make('Text'), ]) ->fillCast( ['text' => 'value'], new ModelCaster(User::class) )
или
use MoonShine\TypeCasts\ModelCaster; FormBuilder::make('/crud/update') ->fields([ Heading::make('Title'), Text::make('Text'), ]) ->fillCast( User::query()->first(), new ModelCaster(User::class) )
Кнопки
Кнопки формы можно модифицировать и добавлять.
Для настройки кнопки "submit" используйте метод submit()
.
submit( string $label, array $attributes = [])
label
- название кнопки,attributes
- дополнительные атрибуты.
FormBuilder::make('/crud/update') ->submit( label: 'Click me', attributes: ['class' => 'btn-primary'] )
Метод hideSubmit()
позволяет скрыть кнопку "submit".
FormBuilder::make('/crud/update') ->hideSubmit()
Для добавления новых кнопок на основе ActionButton
используйте метод buttons()
.
buttons(iterable $buttons = [])
FormBuilder::make('/crud/update') ->buttons([ ActionButton::make('Delete', route('name.delete')) ])
Настройка атрибутов
Вы можете установить любые html атрибуты для формы с помощью метода customAttributes()
.
FormBuilder::make() ->customAttributes(['class' => 'custom-form'])
Асинхронный режим
Если необходимо отправить форму асинхронно, используйте метод async()
.
async( Closure|string|null $url = null, string|array|null $events = null, ?AsyncCallback $callback = null,)
url
- url запроса (по умолчанию запрос отправляется по url action),events
- события, поднимаемые после успешного запроса,callback
- js callback функция после получения ответа.
FormBuilder::make('/crud/update') ->async()
После успешного запроса можно вызвать события, добавив параметр events
.
FormBuilder::make('/crud/update') ->name('main-form') ->async(events: [ AlpineJs::event(JsEvent::TABLE_UPDATED, 'crud-table'), AlpineJs::event(JsEvent::FORM_RESET, 'main-form'), ])
Список событий для FormBuilder
:
JsEvent::FORM_SUBMIT
- submit формы,JsEvent::FORM_RESET
- сброс значений формы по её имени,
Метод async()
должен идти после метода name()
!
Вызов методов
asyncMethod()
позволяет указать имя метода в ресурсе и вызвать его асинхронно при отправке FormBuilder
без необходимости создания дополнительных контроллеров.
FormBuilder::make() ->asyncMethod('updateSomething')
// С уведомлениемpublic function updateSomething(MoonShineRequest $request): MoonShineJsonResponse{ // $request->getResource(); // $request->getResource()->getItem(); // $request->getPage(); return MoonShineJsonResponse::make()->toast('My message', ToastType::SUCCESS);} // Редиректpublic function updateSomething(MoonShineRequest $request): MoonShineJsonResponse{ return MoonShineJsonResponse::make()->redirect('/');} // Редиректpublic function updateSomething(MoonShineRequest $request): RedirectResponse{ return back();} // Исключениеpublic function updateSomething(MoonShineRequest $request): void{ throw new \Exception('My message');}
Реактивность
По умолчанию полям внутри формы доступна реактивность, но если форма находится вне ресурса, тогда реактивность будет недоступна, так как форма не знает куда отправлять запросы. В случае использования формы вне ресурсов вы можете указать реактивный URL самостоятельно.
FormBuilder::make() ->reactiveUrl( fn(FormBuilder $form) => $form->getCore()->getRouter()->getEndpoints()->reactive($page, $resource, $extra) )
Значения полей
Если вы используете собственный controller обработчик, asyncMethod
или обработчик ответа,
то с помощью MoonShineJsonResponse
у вас есть возможность заменить значения полей формы по селектору.
public function formAction(): MoonShineJsonResponse{ return MoonShineJsonResponse::make() ->fieldsValues([ '.title' => 'Hello', ]);} protected function components(): iterable{ return [ FormBuilder::make() ->asyncMethod('formAction') ->fields([ Text::make('Title')->class('title'), ]), ];}
Селекторы
Также вы можете заменить HTML области по селекторам через метод asyncSelector
.
public function formAction(): MoonShineJsonResponse{ return MoonShineJsonResponse::make()->html([ '.some-class1' => time(), '.some-class2' => time(), ]);} protected function components(): iterable{ return [ FormBuilder::make() ->asyncMethod('formAction') ->asyncSelector(['.some-class1','.some-class2']) ->fields([ Div::make([])->class('some-class1'), Div::make([])->class('some-class2'), ]), ];}
Валидация
Отображение ошибок валидации
По умолчанию ошибки валидации отображаются в верхней части формы.
Метод errorsAbove(bool $enable = true)
используется для управления отображением ошибок валидации в верхней части формы.
Он позволяет включить или отключить эту функцию.
FormBuilder::make('/crud/update') ->errorsAbove(false)
Прекогнитивная валидация
Если необходимо сначала выполнить прекогнитивную валидацию, вам нужен метод precognitive()
.
FormBuilder::make('/crud/update') ->precognitive()
Несколько форм одновременно
Если у вас есть несколько форм на одной странице и они не в режиме "async", то вам также необходимо указать наименование для errorBag
в FormRequest
или в Controller
.
Наименование errorBag
должно совпадать с наименованием соответствующей формы.
Подробнее о наименовании errorBag.
FormBuilder::make(route('multiple-forms.one')) ->name('formOne'), FormBuilder::make(route('multiple-forms.two')) ->name('formTwo'), FormBuilder::make(route('multiple-forms.three')) ->name('formThree') class FormOneFormRequest extends FormRequest{ protected $errorBag = 'formOne'; // ...} class FormTwoFormRequest extends FormRequest{ protected $errorBag = 'formTwo'; // ...} class FormThreeFormRequest extends FormRequest{ protected $errorBag = 'formThree'; // ...}
Применение
Метод 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);
Отправка событий
Для отправки javascript событий можно использовать метод dispatchEvent()
.
dispatchEvent(array|string $events)
FormBuilder::make() ->dispatchEvent( AlpineJs::event(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')
Пример вызова события на странице формы
protected function formButtons(): ListOf{ return parent::formButtons() ->add( ActionButton::make('Save') ->dispatchEvent(AlpineJs::event(JsEvent::FORM_SUBMIT, $this->uriKey())) );}
Для получения дополнительной информации о js событиях обратитесь к разделу Events.