Upon a successful request, the form updates the table and resets the values.
    Block::make([
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['table-updated-main-table','form-reset-main-form'])
]),
TableBuilder::make()
    ->fields([
        ID::make(),
        Text::make('Title'),
        Textarea::make('Body'),
    ])
    ->creatable()
    ->items(Post::query()->paginate())
    ->name('main-table')
    ->async()
    
    Block::make([
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['table-updated-main-table','form-reset-main-form'])
]),
 
TableBuilder::make()
    ->fields([
        ID::make(),
        Text::make('Title'),
        Textarea::make('Body'),
    ])
    ->creatable()
    ->items(Post::query()->paginate())
    ->name('main-table')
    ->async()
Block::make([
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['table-updated-main-table','form-reset-main-form'])
]),
TableBuilder::make()
    ->fields([
        ID::make(),
        Text::make('Title'),
        Textarea::make('Body'),
    ])
    ->creatable()
    ->items(Post::query()->paginate())
    ->name('main-table')
    ->async()
Block::make([
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['table-updated-main-table','form-reset-main-form'])
]),
 
TableBuilder::make()
    ->fields([
        ID::make(),
        Text::make('Title'),
        Textarea::make('Body'),
    ])
    ->creatable()
    ->items(Post::query()->paginate())
    ->name('main-table')
    ->async()
Block::make([
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['table-updated-main-table','form-reset-main-form'])
]),
TableBuilder::make()
    ->fields([
        ID::make(),
        Text::make('Title'),
        Textarea::make('Body'),
    ])
    ->creatable()
    ->items(Post::query()->paginate())
    ->name('main-table')
    ->async()
 
Let's also look at how to add your own events
    <div x-data=""
     @my-event.window="alert()"
>
</div>
    
    <div x-data=""
     @my-event.window="alert()"
>
</div>
<div x-data=""
     @my-event.window="alert()"
>
</div>
<div x-data=""
     @my-event.window="alert()"
>
</div>
<div x-data=""
     @my-event.window="alert()"
>
</div>
 
    <div x-data="my"
     @my-event.window="asyncRequest"
>
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("my", () => ({
            init() {
            },
            asyncRequest() {
                this.$event.preventDefault()
                                            }
        }))
    })
</script>
    
    <div x-data="my"
     @my-event.window="asyncRequest"
>
</div>
 
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("my", () => ({
            init() {
 
            },
            asyncRequest() {
                this.$event.preventDefault()
 
                // this.$el
                // this.$root
            }
        }))
    })
</script>
<div x-data="my"
     @my-event.window="asyncRequest"
>
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("my", () => ({
            init() {
            },
            asyncRequest() {
                this.$event.preventDefault()
                // this.$el
                // this.$root
            }
        }))
    })
</script>
<div x-data="my"
     @my-event.window="asyncRequest"
>
</div>
 
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("my", () => ({
            init() {
 
            },
            asyncRequest() {
                this.$event.preventDefault()
 
                // this.$el
                // this.$root
            }
        }))
    })
</script>
<div x-data="my"
     @my-event.window="asyncRequest"
>
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("my", () => ({
            init() {
            },
            asyncRequest() {
                this.$event.preventDefault()
                // this.$el
                // this.$root
            }
        }))
    })
</script>
 
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['my-event'])
    
    FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['my-event'])
FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['my-event'])
FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['my-event'])
FormBuilder::make(route('form-table.store'))
    ->fields([
        Text::make('Title')
    ])
    ->name('main-form')
    ->async(asyncEvents: ['my-event'])
 
We also recommend that you familiarize yourself with AlpineJs and use the full power of this js framework.
You can use its reactivity, let's see how to conveniently create a component.
    <div x-data="myComponent">
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("myComponent", () => ({
            init() {
            },
        }))
    })
</script>
    
    <div x-data="myComponent">
</div>
 
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("myComponent", () => ({
            init() {
 
            },
        }))
    })
</script>
<div x-data="myComponent">
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("myComponent", () => ({
            init() {
            },
        }))
    })
</script>
<div x-data="myComponent">
</div>
 
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("myComponent", () => ({
            init() {
 
            },
        }))
    })
</script>
<div x-data="myComponent">
</div>
<script>
    document.addEventListener("alpine:init", () => {
        Alpine.data("myComponent", () => ({
            init() {
            },
        }))
    })
</script>
 
Let's add one compiled using Vite build.
    public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
    
    public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
 
Let's add custom buttons to the index table.
    public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
    
    public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
public function indexButtons(): array
{
    $resource = new CommentResource();
    return [
        ActionButton::make('Custom button', static fn ($data): string => to_page(
            page: $resource->formPage(),
            resource: $resource,
            params: ['resourceItem' => $data->getKey()]
        ))
    ];
}
 
An example of implementing the HasOne relationship through the Template field.
    use MoonShine\Fields\Template;
public function fields(): array
{
    return [
        Template::make('Comment')
          ->changeFill(fn (Article $data) => $data->comment)
          ->changePreview(fn($data) => $data?->id ?? '-')
          ->fields((new CommentResource())->getFormFields())
          ->changeRender(function (?Comment $data, Template $field) {
              $fields = $field->preparedFields();
              $fields->fill($data?->toArray() ?? [], $data ?? new Comment());
              return Components::make($fields);
          })
          ->onAfterApply(function (Article $item, array $value) {
              $item->comment()->updateOrCreate([
                  'id' => $value['id']
              ], $value);
              return $item;
          })
    ];
}
    
    use MoonShine\Fields\Template;
 
//...
 
public function fields(): array
{
    return [
        Template::make('Comment')
          ->changeFill(fn (Article $data) => $data->comment)
          ->changePreview(fn($data) => $data?->id ?? '-')
          ->fields((new CommentResource())->getFormFields())
          ->changeRender(function (?Comment $data, Template $field) {
              $fields = $field->preparedFields();
              $fields->fill($data?->toArray() ?? [], $data ?? new Comment());
 
              return Components::make($fields);
          })
          ->onAfterApply(function (Article $item, array $value) {
              $item->comment()->updateOrCreate([
                  'id' => $value['id']
              ], $value);
 
              return $item;
          })
    ];
}
 
//...
use MoonShine\Fields\Template;
//...
public function fields(): array
{
    return [
        Template::make('Comment')
          ->changeFill(fn (Article $data) => $data->comment)
          ->changePreview(fn($data) => $data?->id ?? '-')
          ->fields((new CommentResource())->getFormFields())
          ->changeRender(function (?Comment $data, Template $field) {
              $fields = $field->preparedFields();
              $fields->fill($data?->toArray() ?? [], $data ?? new Comment());
              return Components::make($fields);
          })
          ->onAfterApply(function (Article $item, array $value) {
              $item->comment()->updateOrCreate([
                  'id' => $value['id']
              ], $value);
              return $item;
          })
    ];
}
//...
use MoonShine\Fields\Template;
 
//...
 
public function fields(): array
{
    return [
        Template::make('Comment')
          ->changeFill(fn (Article $data) => $data->comment)
          ->changePreview(fn($data) => $data?->id ?? '-')
          ->fields((new CommentResource())->getFormFields())
          ->changeRender(function (?Comment $data, Template $field) {
              $fields = $field->preparedFields();
              $fields->fill($data?->toArray() ?? [], $data ?? new Comment());
 
              return Components::make($fields);
          })
          ->onAfterApply(function (Article $item, array $value) {
              $item->comment()->updateOrCreate([
                  'id' => $value['id']
              ], $value);
 
              return $item;
          })
    ];
}
 
//...
use MoonShine\Fields\Template;
//...
public function fields(): array
{
    return [
        Template::make('Comment')
          ->changeFill(fn (Article $data) => $data->comment)
          ->changePreview(fn($data) => $data?->id ?? '-')
          ->fields((new CommentResource())->getFormFields())
          ->changeRender(function (?Comment $data, Template $field) {
              $fields = $field->preparedFields();
              $fields->fill($data?->toArray() ?? [], $data ?? new Comment());
              return Components::make($fields);
          })
          ->onAfterApply(function (Article $item, array $value) {
              $item->comment()->updateOrCreate([
                  'id' => $value['id']
              ], $value);
              return $item;
          })
    ];
}
//...
 
You can change page breadcrumbs directly from the resource.
    namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    protected function onBoot(): void
    {
        $this->formPage()
            ->setBreadcrumbs([
                '#' => $this->title()
            ]);
    }
    }
    
    namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
    //...
 
    protected function onBoot(): void
    {
        $this->formPage()
            ->setBreadcrumbs([
                '#' => $this->title()
            ]);
    }
 
    //...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    //...
    protected function onBoot(): void
    {
        $this->formPage()
            ->setBreadcrumbs([
                '#' => $this->title()
            ]);
    }
    //...
}
namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
    //...
 
    protected function onBoot(): void
    {
        $this->formPage()
            ->setBreadcrumbs([
                '#' => $this->title()
            ]);
    }
 
    //...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    //...
    protected function onBoot(): void
    {
        $this->formPage()
            ->setBreadcrumbs([
                '#' => $this->title()
            ]);
    }
    //...
}
 
Let's change the display of elements on the index page through the CardsBuilder component.
    class MoonShineUserIndexPage extends IndexPage
{
    public function listComponentName(): string
    {
        return 'index-cards';
    }
    public function listEventName(): string
    {
        return 'cards-updated';
    }
    protected function itemsComponent(iterable $items, Fields $fields): MoonShineRenderable
    {
        return CardsBuilder::make($items, $fields)
            ->cast($this->getResource()->getModelCast())
            ->name($this->listComponentName())
            ->async()
            ->overlay()
            ->title('email')
            ->subtitle('name')
            ->url(fn ($user) => $this->getResource()->formPageUrl($user))
            ->thumbnail(fn ($user) => asset($user->avatar))
            ->buttons($this->getResource()->getIndexItemButtons());
    }
}
    
    class MoonShineUserIndexPage extends IndexPage
{
    public function listComponentName(): string
    {
        return 'index-cards';
    }
 
    public function listEventName(): string
    {
        return 'cards-updated';
    }
 
    protected function itemsComponent(iterable $items, Fields $fields): MoonShineRenderable
    {
        return CardsBuilder::make($items, $fields)
            ->cast($this->getResource()->getModelCast())
            ->name($this->listComponentName())
            ->async()
            ->overlay()
            ->title('email')
            ->subtitle('name')
            ->url(fn ($user) => $this->getResource()->formPageUrl($user))
            ->thumbnail(fn ($user) => asset($user->avatar))
            ->buttons($this->getResource()->getIndexItemButtons());
    }
}
class MoonShineUserIndexPage extends IndexPage
{
    public function listComponentName(): string
    {
        return 'index-cards';
    }
    public function listEventName(): string
    {
        return 'cards-updated';
    }
    protected function itemsComponent(iterable $items, Fields $fields): MoonShineRenderable
    {
        return CardsBuilder::make($items, $fields)
            ->cast($this->getResource()->getModelCast())
            ->name($this->listComponentName())
            ->async()
            ->overlay()
            ->title('email')
            ->subtitle('name')
            ->url(fn ($user) => $this->getResource()->formPageUrl($user))
            ->thumbnail(fn ($user) => asset($user->avatar))
            ->buttons($this->getResource()->getIndexItemButtons());
    }
}
class MoonShineUserIndexPage extends IndexPage
{
    public function listComponentName(): string
    {
        return 'index-cards';
    }
 
    public function listEventName(): string
    {
        return 'cards-updated';
    }
 
    protected function itemsComponent(iterable $items, Fields $fields): MoonShineRenderable
    {
        return CardsBuilder::make($items, $fields)
            ->cast($this->getResource()->getModelCast())
            ->name($this->listComponentName())
            ->async()
            ->overlay()
            ->title('email')
            ->subtitle('name')
            ->url(fn ($user) => $this->getResource()->formPageUrl($user))
            ->thumbnail(fn ($user) => asset($user->avatar))
            ->buttons($this->getResource()->getIndexItemButtons());
    }
}
class MoonShineUserIndexPage extends IndexPage
{
    public function listComponentName(): string
    {
        return 'index-cards';
    }
    public function listEventName(): string
    {
        return 'cards-updated';
    }
    protected function itemsComponent(iterable $items, Fields $fields): MoonShineRenderable
    {
        return CardsBuilder::make($items, $fields)
            ->cast($this->getResource()->getModelCast())
            ->name($this->listComponentName())
            ->async()
            ->overlay()
            ->title('email')
            ->subtitle('name')
            ->url(fn ($user) => $this->getResource()->formPageUrl($user))
            ->thumbnail(fn ($user) => asset($user->avatar))
            ->buttons($this->getResource()->getIndexItemButtons());
    }
}
 
Let's create a sorting for the CardsBuilder component:
    Select::make('Sorts')->options([
    'created_at' => 'Date',
    'id' => 'ID',
])
    ->onChangeMethod('reSort', events: ['cards-updated-cards'])
    ->setValue(session('sort_column') ?: 'created_at'),
CardsBuilder::make(
    items: Article::query()->with('author')
        ->when(
            session('sort_column'),
            fn($q) => $q->orderBy(session('sort_column'), session('sort_direction', 'asc')),
            fn($q) => $q->latest()
        )
        ->paginate()
)
    ->name('cards')
    ->async()
    ->cast(ModelCast::make(Article::class))
    ->title('title')
    ->url(fn($data) => (new ArticleResource())->formPageUrl($data))
    ->overlay()
    ->columnSpan(4) ,
public function reSort(MoonShineRequest $request): void
{
    session()->put('sort_column', $request->get('value'));
    session()->put('sort_direction', 'ASC');
}
    
    Select::make('Sorts')->options([
    'created_at' => 'Date',
    'id' => 'ID',
])
    ->onChangeMethod('reSort', events: ['cards-updated-cards'])
    ->setValue(session('sort_column') ?: 'created_at'),
 
 
CardsBuilder::make(
    items: Article::query()->with('author')
        ->when(
            session('sort_column'),
            fn($q) => $q->orderBy(session('sort_column'), session('sort_direction', 'asc')),
            fn($q) => $q->latest()
        )
        ->paginate()
)
    ->name('cards')
    ->async()
    ->cast(ModelCast::make(Article::class))
    ->title('title')
    ->url(fn($data) => (new ArticleResource())->formPageUrl($data))
    ->overlay()
    ->columnSpan(4) ,
 
// ...
 
public function reSort(MoonShineRequest $request): void
{
    session()->put('sort_column', $request->get('value'));
    session()->put('sort_direction', 'ASC');
}
Select::make('Sorts')->options([
    'created_at' => 'Date',
    'id' => 'ID',
])
    ->onChangeMethod('reSort', events: ['cards-updated-cards'])
    ->setValue(session('sort_column') ?: 'created_at'),
CardsBuilder::make(
    items: Article::query()->with('author')
        ->when(
            session('sort_column'),
            fn($q) => $q->orderBy(session('sort_column'), session('sort_direction', 'asc')),
            fn($q) => $q->latest()
        )
        ->paginate()
)
    ->name('cards')
    ->async()
    ->cast(ModelCast::make(Article::class))
    ->title('title')
    ->url(fn($data) => (new ArticleResource())->formPageUrl($data))
    ->overlay()
    ->columnSpan(4) ,
// ...
public function reSort(MoonShineRequest $request): void
{
    session()->put('sort_column', $request->get('value'));
    session()->put('sort_direction', 'ASC');
}
Select::make('Sorts')->options([
    'created_at' => 'Date',
    'id' => 'ID',
])
    ->onChangeMethod('reSort', events: ['cards-updated-cards'])
    ->setValue(session('sort_column') ?: 'created_at'),
 
 
CardsBuilder::make(
    items: Article::query()->with('author')
        ->when(
            session('sort_column'),
            fn($q) => $q->orderBy(session('sort_column'), session('sort_direction', 'asc')),
            fn($q) => $q->latest()
        )
        ->paginate()
)
    ->name('cards')
    ->async()
    ->cast(ModelCast::make(Article::class))
    ->title('title')
    ->url(fn($data) => (new ArticleResource())->formPageUrl($data))
    ->overlay()
    ->columnSpan(4) ,
 
// ...
 
public function reSort(MoonShineRequest $request): void
{
    session()->put('sort_column', $request->get('value'));
    session()->put('sort_direction', 'ASC');
}
Select::make('Sorts')->options([
    'created_at' => 'Date',
    'id' => 'ID',
])
    ->onChangeMethod('reSort', events: ['cards-updated-cards'])
    ->setValue(session('sort_column') ?: 'created_at'),
CardsBuilder::make(
    items: Article::query()->with('author')
        ->when(
            session('sort_column'),
            fn($q) => $q->orderBy(session('sort_column'), session('sort_direction', 'asc')),
            fn($q) => $q->latest()
        )
        ->paginate()
)
    ->name('cards')
    ->async()
    ->cast(ModelCast::make(Article::class))
    ->title('title')
    ->url(fn($data) => (new ArticleResource())->formPageUrl($data))
    ->overlay()
    ->columnSpan(4) ,
// ...
public function reSort(MoonShineRequest $request): void
{
    session()->put('sort_column', $request->get('value'));
    session()->put('sort_direction', 'ASC');
}
 
Implementation via asyncMethod of the method for changing the pivot field on the index page:
    public function fields(): array
{
    return [
        Grid::make([
            Column::make([
                ID::make()->sortable(),
                Text::make('Team title')->required(),
                Number::make('Team number'),
                BelongsTo::make('Tournament', resource: new TournamentResource())
                    ->searchable(),
            ]),
            Column::make([
                BelongsToMany::make('Users', resource: new UserResource())
                    ->fields([
                        Switcher::make('Approved')
                            ->updateOnPreview(MoonShineRouter::asyncMethodClosure(
                                'updatePivot',
                                params: fn($data) => ['parent' => $data->pivot->tournamen_team_id]
                            )),
                    ])
                    ->searchable(),
            ])
        ])
    ];
}
public function updatePivot(MoonShineRequest $request): MoonShineJsonResponse
{
    $item = TournamentTeam::query()
        ->findOrFail($request->get('parent'));
    $column = (string) $request->str('field')->remove('pivot.');
    $item->users()->updateExistingPivot($request->get('resourceItem'), [
        $column => $request->get('value'),
    ]);
    return MoonShineJsonResponse::make()
        ->toast('Success');
}
    
    public function fields(): array
{
    return [
        Grid::make([
            Column::make([
                ID::make()->sortable(),
                Text::make('Team title')->required(),
                Number::make('Team number'),
                BelongsTo::make('Tournament', resource: new TournamentResource())
                    ->searchable(),
            ]),
            Column::make([
                BelongsToMany::make('Users', resource: new UserResource())
                    ->fields([
                        Switcher::make('Approved')
                            ->updateOnPreview(MoonShineRouter::asyncMethodClosure(
                                'updatePivot',
                                params: fn($data) => ['parent' => $data->pivot->tournamen_team_id]
                            )),
                    ])
                    ->searchable(),
            ])
        ])
    ];
}
 
public function updatePivot(MoonShineRequest $request): MoonShineJsonResponse
{
    $item = TournamentTeam::query()
        ->findOrFail($request->get('parent'));
 
    $column = (string) $request->str('field')->remove('pivot.');
 
    $item->users()->updateExistingPivot($request->get('resourceItem'), [
        $column => $request->get('value'),
    ]);
 
    return MoonShineJsonResponse::make()
        ->toast('Success');
}
public function fields(): array
{
    return [
        Grid::make([
            Column::make([
                ID::make()->sortable(),
                Text::make('Team title')->required(),
                Number::make('Team number'),
                BelongsTo::make('Tournament', resource: new TournamentResource())
                    ->searchable(),
            ]),
            Column::make([
                BelongsToMany::make('Users', resource: new UserResource())
                    ->fields([
                        Switcher::make('Approved')
                            ->updateOnPreview(MoonShineRouter::asyncMethodClosure(
                                'updatePivot',
                                params: fn($data) => ['parent' => $data->pivot->tournamen_team_id]
                            )),
                    ])
                    ->searchable(),
            ])
        ])
    ];
}
public function updatePivot(MoonShineRequest $request): MoonShineJsonResponse
{
    $item = TournamentTeam::query()
        ->findOrFail($request->get('parent'));
    $column = (string) $request->str('field')->remove('pivot.');
    $item->users()->updateExistingPivot($request->get('resourceItem'), [
        $column => $request->get('value'),
    ]);
    return MoonShineJsonResponse::make()
        ->toast('Success');
}
public function fields(): array
{
    return [
        Grid::make([
            Column::make([
                ID::make()->sortable(),
                Text::make('Team title')->required(),
                Number::make('Team number'),
                BelongsTo::make('Tournament', resource: new TournamentResource())
                    ->searchable(),
            ]),
            Column::make([
                BelongsToMany::make('Users', resource: new UserResource())
                    ->fields([
                        Switcher::make('Approved')
                            ->updateOnPreview(MoonShineRouter::asyncMethodClosure(
                                'updatePivot',
                                params: fn($data) => ['parent' => $data->pivot->tournamen_team_id]
                            )),
                    ])
                    ->searchable(),
            ])
        ])
    ];
}
 
public function updatePivot(MoonShineRequest $request): MoonShineJsonResponse
{
    $item = TournamentTeam::query()
        ->findOrFail($request->get('parent'));
 
    $column = (string) $request->str('field')->remove('pivot.');
 
    $item->users()->updateExistingPivot($request->get('resourceItem'), [
        $column => $request->get('value'),
    ]);
 
    return MoonShineJsonResponse::make()
        ->toast('Success');
}
public function fields(): array
{
    return [
        Grid::make([
            Column::make([
                ID::make()->sortable(),
                Text::make('Team title')->required(),
                Number::make('Team number'),
                BelongsTo::make('Tournament', resource: new TournamentResource())
                    ->searchable(),
            ]),
            Column::make([
                BelongsToMany::make('Users', resource: new UserResource())
                    ->fields([
                        Switcher::make('Approved')
                            ->updateOnPreview(MoonShineRouter::asyncMethodClosure(
                                'updatePivot',
                                params: fn($data) => ['parent' => $data->pivot->tournamen_team_id]
                            )),
                    ])
                    ->searchable(),
            ])
        ])
    ];
}
public function updatePivot(MoonShineRequest $request): MoonShineJsonResponse
{
    $item = TournamentTeam::query()
        ->findOrFail($request->get('parent'));
    $column = (string) $request->str('field')->remove('pivot.');
    $item->users()->updateExistingPivot($request->get('resourceItem'), [
        $column => $request->get('value'),
    ]);
    return MoonShineJsonResponse::make()
        ->toast('Success');
}
 
The HasMany connection stores file data that needs to be saved in a directory by parent id.
    use App\Models\PostImage;
use MoonShine\Fields\ID;
use MoonShine\Fields\Image;
use MoonShine\Fields\Relationships\BelongsTo;
use MoonShine\Resources\ModelResource;
use MoonShine\Traits\Resource\ResourceWithParent;
class PostImageResource extends ModelResource
{
    use ResourceWithParent;
    public string $model = PostImage::class;
    protected function getParentResourceClassName(): string
    {
        return PostResource::class;
    }
    protected function getParentRelationName(): string
    {
        return 'post';
    }
    public function fields(): array
    {
        return [
            ID::make(),
            Image::make('Path')
                ->when(
                    $parentId = $this->getParentId(),
                    fn(Image $image) => $image->dir('post_images/'.$parentId)
                )
            ,
            BelongsTo::make('Post', 'post', resource: new PostResource())
        ];
    }
    }
    
    use App\Models\PostImage;
use MoonShine\Fields\ID;
use MoonShine\Fields\Image;
use MoonShine\Fields\Relationships\BelongsTo;
use MoonShine\Resources\ModelResource;
use MoonShine\Traits\Resource\ResourceWithParent;
 
class PostImageResource extends ModelResource
{
    use ResourceWithParent;
 
    public string $model = PostImage::class;
 
    protected function getParentResourceClassName(): string
    {
        return PostResource::class;
    }
 
    protected function getParentRelationName(): string
    {
        return 'post';
    }
 
    public function fields(): array
    {
        return [
            ID::make(),
            Image::make('Path')
                ->when(
                    $parentId = $this->getParentId(),
                    fn(Image $image) => $image->dir('post_images/'.$parentId)
                )
            ,
            BelongsTo::make('Post', 'post', resource: new PostResource())
        ];
    }
 
    //...
}
use App\Models\PostImage;
use MoonShine\Fields\ID;
use MoonShine\Fields\Image;
use MoonShine\Fields\Relationships\BelongsTo;
use MoonShine\Resources\ModelResource;
use MoonShine\Traits\Resource\ResourceWithParent;
class PostImageResource extends ModelResource
{
    use ResourceWithParent;
    public string $model = PostImage::class;
    protected function getParentResourceClassName(): string
    {
        return PostResource::class;
    }
    protected function getParentRelationName(): string
    {
        return 'post';
    }
    public function fields(): array
    {
        return [
            ID::make(),
            Image::make('Path')
                ->when(
                    $parentId = $this->getParentId(),
                    fn(Image $image) => $image->dir('post_images/'.$parentId)
                )
            ,
            BelongsTo::make('Post', 'post', resource: new PostResource())
        ];
    }
    //...
}
use App\Models\PostImage;
use MoonShine\Fields\ID;
use MoonShine\Fields\Image;
use MoonShine\Fields\Relationships\BelongsTo;
use MoonShine\Resources\ModelResource;
use MoonShine\Traits\Resource\ResourceWithParent;
 
class PostImageResource extends ModelResource
{
    use ResourceWithParent;
 
    public string $model = PostImage::class;
 
    protected function getParentResourceClassName(): string
    {
        return PostResource::class;
    }
 
    protected function getParentRelationName(): string
    {
        return 'post';
    }
 
    public function fields(): array
    {
        return [
            ID::make(),
            Image::make('Path')
                ->when(
                    $parentId = $this->getParentId(),
                    fn(Image $image) => $image->dir('post_images/'.$parentId)
                )
            ,
            BelongsTo::make('Post', 'post', resource: new PostResource())
        ];
    }
 
    //...
}
use App\Models\PostImage;
use MoonShine\Fields\ID;
use MoonShine\Fields\Image;
use MoonShine\Fields\Relationships\BelongsTo;
use MoonShine\Resources\ModelResource;
use MoonShine\Traits\Resource\ResourceWithParent;
class PostImageResource extends ModelResource
{
    use ResourceWithParent;
    public string $model = PostImage::class;
    protected function getParentResourceClassName(): string
    {
        return PostResource::class;
    }
    protected function getParentRelationName(): string
    {
        return 'post';
    }
    public function fields(): array
    {
        return [
            ID::make(),
            Image::make('Path')
                ->when(
                    $parentId = $this->getParentId(),
                    fn(Image $image) => $image->dir('post_images/'.$parentId)
                )
            ,
            BelongsTo::make('Post', 'post', resource: new PostResource())
        ];
    }
    //...
}
 
Sometimes it is necessary to display the TinyMce field in the preview with a limited number of characters. To do this, you can use the changePreview() method.
    public function fields(): array
{
    return [
        TinyMce::make('Description')
            ->changePreview(fn(string $text) => str($text)->stripTags()->limit(10))
    ];
}
}
    
    public function fields(): array
{
    return [
        TinyMce::make('Description')
            ->changePreview(fn(string $text) => str($text)->stripTags()->limit(10))
    ];
}
 
//...
}
public function fields(): array
{
    return [
        TinyMce::make('Description')
            ->changePreview(fn(string $text) => str($text)->stripTags()->limit(10))
    ];
}
//...
}
public function fields(): array
{
    return [
        TinyMce::make('Description')
            ->changePreview(fn(string $text) => str($text)->stripTags()->limit(10))
    ];
}
 
//...
}
public function fields(): array
{
    return [
        TinyMce::make('Description')
            ->changePreview(fn(string $text) => str($text)->stripTags()->limit(10))
    ];
}
//...
}
 
- To solve this problem, you need to block the onApply()method and moved the logic toonAfterApply(). This will get the parent model on the creation page. We will have access to the model and we will be able to work with its relationships.
- The onAfterApply()method stores and retrieves old and current values, also cleaning deleted files.
- After deleting the parent record, the onAfterDestroy()method deletes the downloaded files.
    use MoonShine\Fields\Image;
Image::make('Images', 'images')
    ->multiple()
    ->removable()
    ->changeFill(function (Model $data, Image $field) {
                        return DB::table('images')->pluck('file');
    })
    ->onApply(function (Model $data) {
                return $data;
    })
    ->onAfterApply(function (Model $data, false|array $values, Image $field) {
        if($values !== false) {
            foreach ($values as $value) {
                DB::table('images')->insert([
                    'file' => $field->store($value),
                ]);
            }
        }
        foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
            DB::table('images')->where('file', $removed)->delete();
            Storage::disk('public')->delete($removed);
        }
        return $data;
    })
    ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
        foreach ($values as $value) {
            Storage::disk('public')->delete($value);
        }
        return $data;
    })
    
    use MoonShine\Fields\Image;
 
//...
 
Image::make('Images', 'images')
    ->multiple()
    ->removable()
    ->changeFill(function (Model $data, Image $field) {
        // return $data->images->pluck('file');
        // or raw
        return DB::table('images')->pluck('file');
    })
    ->onApply(function (Model $data) {
        // block onApply
        return $data;
    })
    ->onAfterApply(function (Model $data, false|array $values, Image $field) {
        // $field->getRemainingValues(); values that remained in the form taking into account deletions
        // $field->toValue(); current images
        // $field->toValue()->diff($field->getRemainingValues()) deleted images
 
        if($values !== false) {
            foreach ($values as $value) {
                DB::table('images')->insert([
                    'file' => $field->store($value),
                ]);
            }
        }
 
        foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
            DB::table('images')->where('file', $removed)->delete();
            Storage::disk('public')->delete($removed);
        }
 
        // or $field->removeExcludedFiles();
 
        return $data;
    })
    ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
        foreach ($values as $value) {
            Storage::disk('public')->delete($value);
        }
 
        return $data;
    })
 
//...
use MoonShine\Fields\Image;
//...
Image::make('Images', 'images')
    ->multiple()
    ->removable()
    ->changeFill(function (Model $data, Image $field) {
        // return $data->images->pluck('file');
        // or raw
        return DB::table('images')->pluck('file');
    })
    ->onApply(function (Model $data) {
        // block onApply
        return $data;
    })
    ->onAfterApply(function (Model $data, false|array $values, Image $field) {
        // $field->getRemainingValues(); values that remained in the form taking into account deletions
        // $field->toValue(); current images
        // $field->toValue()->diff($field->getRemainingValues()) deleted images
        if($values !== false) {
            foreach ($values as $value) {
                DB::table('images')->insert([
                    'file' => $field->store($value),
                ]);
            }
        }
        foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
            DB::table('images')->where('file', $removed)->delete();
            Storage::disk('public')->delete($removed);
        }
        // or $field->removeExcludedFiles();
        return $data;
    })
    ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
        foreach ($values as $value) {
            Storage::disk('public')->delete($value);
        }
        return $data;
    })
//...
use MoonShine\Fields\Image;
 
//...
 
Image::make('Images', 'images')
    ->multiple()
    ->removable()
    ->changeFill(function (Model $data, Image $field) {
        // return $data->images->pluck('file');
        // or raw
        return DB::table('images')->pluck('file');
    })
    ->onApply(function (Model $data) {
        // block onApply
        return $data;
    })
    ->onAfterApply(function (Model $data, false|array $values, Image $field) {
        // $field->getRemainingValues(); values that remained in the form taking into account deletions
        // $field->toValue(); current images
        // $field->toValue()->diff($field->getRemainingValues()) deleted images
 
        if($values !== false) {
            foreach ($values as $value) {
                DB::table('images')->insert([
                    'file' => $field->store($value),
                ]);
            }
        }
 
        foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
            DB::table('images')->where('file', $removed)->delete();
            Storage::disk('public')->delete($removed);
        }
 
        // or $field->removeExcludedFiles();
 
        return $data;
    })
    ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
        foreach ($values as $value) {
            Storage::disk('public')->delete($value);
        }
 
        return $data;
    })
 
//...
use MoonShine\Fields\Image;
//...
Image::make('Images', 'images')
    ->multiple()
    ->removable()
    ->changeFill(function (Model $data, Image $field) {
        // return $data->images->pluck('file');
        // or raw
        return DB::table('images')->pluck('file');
    })
    ->onApply(function (Model $data) {
        // block onApply
        return $data;
    })
    ->onAfterApply(function (Model $data, false|array $values, Image $field) {
        // $field->getRemainingValues(); values that remained in the form taking into account deletions
        // $field->toValue(); current images
        // $field->toValue()->diff($field->getRemainingValues()) deleted images
        if($values !== false) {
            foreach ($values as $value) {
                DB::table('images')->insert([
                    'file' => $field->store($value),
                ]);
            }
        }
        foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
            DB::table('images')->where('file', $removed)->delete();
            Storage::disk('public')->delete($removed);
        }
        // or $field->removeExcludedFiles();
        return $data;
    })
    ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
        foreach ($values as $value) {
            Storage::disk('public')->delete($value);
        }
        return $data;
    })
//...
 
    
    
        
The code comments out the relation option and provides an example of natively obtaining file paths from another table.
     
 
    use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use MoonShine\Fields\Image;
Image::make('Images', 'images')
  ->multiple()
  ->removable()
  ->changeFill(function (Model $data, Image $field) {
            return DB::table('images')->pluck('file');
  })
  ->onApply(function (Model $data) {
            return $data;
  })
  ->onAfterApply(function (Model $data, false|array $values, Image $field) {
    if($values !== false) {
        foreach ($values as $value) {
            DB::table('images')->insert([
                'file' => $field->store($value),
            ]);
        }
    }
    foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
        DB::table('images')->where('file', $removed)->delete();
        Storage::disk('public')->delete($removed);
    }
    return $data;
  })
  ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
    foreach ($values as $value) {
        Storage::disk('public')->delete($value);
    }
    return $data;
  })
    
    use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use MoonShine\Fields\Image;
 
// ...
 
Image::make('Images', 'images')
  ->multiple()
  ->removable()
  ->changeFill(function (Model $data, Image $field) {
    // return $data->images->pluck('file');
    // or raw
    return DB::table('images')->pluck('file');
  })
  ->onApply(function (Model $data) {
      // block onApply
      return $data;
  })
  ->onAfterApply(function (Model $data, false|array $values, Image $field) {
    // $field->getRemainingValues(); values that remained in the form taking into account deletions
    // $field->toValue(); current images
    // $field->toValue()->diff($field->getRemainingValues()) deleted images
 
    if($values !== false) {
        foreach ($values as $value) {
            DB::table('images')->insert([
                'file' => $field->store($value),
            ]);
        }
    }
 
    foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
        DB::table('images')->where('file', $removed)->delete();
        Storage::disk('public')->delete($removed);
    }
 
    // or $field->removeExcludedFiles();
 
    return $data;
  })
  ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
    foreach ($values as $value) {
        Storage::disk('public')->delete($value);
    }
 
    return $data;
  })
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use MoonShine\Fields\Image;
// ...
Image::make('Images', 'images')
  ->multiple()
  ->removable()
  ->changeFill(function (Model $data, Image $field) {
    // return $data->images->pluck('file');
    // or raw
    return DB::table('images')->pluck('file');
  })
  ->onApply(function (Model $data) {
      // block onApply
      return $data;
  })
  ->onAfterApply(function (Model $data, false|array $values, Image $field) {
    // $field->getRemainingValues(); values that remained in the form taking into account deletions
    // $field->toValue(); current images
    // $field->toValue()->diff($field->getRemainingValues()) deleted images
    if($values !== false) {
        foreach ($values as $value) {
            DB::table('images')->insert([
                'file' => $field->store($value),
            ]);
        }
    }
    foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
        DB::table('images')->where('file', $removed)->delete();
        Storage::disk('public')->delete($removed);
    }
    // or $field->removeExcludedFiles();
    return $data;
  })
  ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
    foreach ($values as $value) {
        Storage::disk('public')->delete($value);
    }
    return $data;
  })
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use MoonShine\Fields\Image;
 
// ...
 
Image::make('Images', 'images')
  ->multiple()
  ->removable()
  ->changeFill(function (Model $data, Image $field) {
    // return $data->images->pluck('file');
    // or raw
    return DB::table('images')->pluck('file');
  })
  ->onApply(function (Model $data) {
      // block onApply
      return $data;
  })
  ->onAfterApply(function (Model $data, false|array $values, Image $field) {
    // $field->getRemainingValues(); values that remained in the form taking into account deletions
    // $field->toValue(); current images
    // $field->toValue()->diff($field->getRemainingValues()) deleted images
 
    if($values !== false) {
        foreach ($values as $value) {
            DB::table('images')->insert([
                'file' => $field->store($value),
            ]);
        }
    }
 
    foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
        DB::table('images')->where('file', $removed)->delete();
        Storage::disk('public')->delete($removed);
    }
 
    // or $field->removeExcludedFiles();
 
    return $data;
  })
  ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
    foreach ($values as $value) {
        Storage::disk('public')->delete($value);
    }
 
    return $data;
  })
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use MoonShine\Fields\Image;
// ...
Image::make('Images', 'images')
  ->multiple()
  ->removable()
  ->changeFill(function (Model $data, Image $field) {
    // return $data->images->pluck('file');
    // or raw
    return DB::table('images')->pluck('file');
  })
  ->onApply(function (Model $data) {
      // block onApply
      return $data;
  })
  ->onAfterApply(function (Model $data, false|array $values, Image $field) {
    // $field->getRemainingValues(); values that remained in the form taking into account deletions
    // $field->toValue(); current images
    // $field->toValue()->diff($field->getRemainingValues()) deleted images
    if($values !== false) {
        foreach ($values as $value) {
            DB::table('images')->insert([
                'file' => $field->store($value),
            ]);
        }
    }
    foreach ($field->toValue()->diff($field->getRemainingValues()) as $removed) {
        DB::table('images')->where('file', $removed)->delete();
        Storage::disk('public')->delete($removed);
    }
    // or $field->removeExcludedFiles();
    return $data;
  })
  ->onAfterDestroy(function (Model $data, mixed $values, Image $field) {
    foreach ($values as $value) {
        Storage::disk('public')->delete($value);
    }
    return $data;
  })
 
    namespace App\MoonShine\Resources;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    public function filters(): array
    {
        return [
            Select::make('Activity status', 'active')
                ->options([
                    '0' => 'Only NOT active',
                    '1' => 'Only active',
                ])
                ->nullable()
                ->onApply(fn(Builder $query, $value) => $query->where('active', $value)),
        ];
    }
    }
    
    namespace App\MoonShine\Resources;
 
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
    //...
 
    public function filters(): array
    {
        return [
            Select::make('Activity status', 'active')
                ->options([
                    '0' => 'Only NOT active',
                    '1' => 'Only active',
                ])
                ->nullable()
                ->onApply(fn(Builder $query, $value) => $query->where('active', $value)),
        ];
    }
 
    //...
}
namespace App\MoonShine\Resources;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    //...
    public function filters(): array
    {
        return [
            Select::make('Activity status', 'active')
                ->options([
                    '0' => 'Only NOT active',
                    '1' => 'Only active',
                ])
                ->nullable()
                ->onApply(fn(Builder $query, $value) => $query->where('active', $value)),
        ];
    }
    //...
}
namespace App\MoonShine\Resources;
 
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
    //...
 
    public function filters(): array
    {
        return [
            Select::make('Activity status', 'active')
                ->options([
                    '0' => 'Only NOT active',
                    '1' => 'Only active',
                ])
                ->nullable()
                ->onApply(fn(Builder $query, $value) => $query->where('active', $value)),
        ];
    }
 
    //...
}
namespace App\MoonShine\Resources;
use MoonShine\Resources\ModelResource;
class PostResource extends ModelResource
{
    //...
    public function filters(): array
    {
        return [
            Select::make('Activity status', 'active')
                ->options([
                    '0' => 'Only NOT active',
                    '1' => 'Only active',
                ])
                ->nullable()
                ->onApply(fn(Builder $query, $value) => $query->where('active', $value)),
        ];
    }
    //...
}
 
Metrics with form parameters
    $startDate = request()->date('_form.start_date');
$endDate = request()->date('_form.end_date');
FormBuilder::make()
    ->dispatchEvent(AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'metrics'))
    ->fields([
        Flex::make([
            Date::make('Start date'),
            Date::make('End date'),
        ]),
    ]),
Fragment::make([
    FlexibleRender::make("$startDate - $endDate"),
    LineChartMetric::make('Orders')
        ->line([
            'Profit' => Order::query()
                ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->pluck('sum', 'date')
                ->toArray(),
        ])
        ->line([
            'Avg' => Order::query()
                ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                -> pluck('avg', 'date')
                ->toArray(),
        ], '#EC4176'),
])->name('metrics'),
    
    $startDate = request()->date('_form.start_date');
$endDate = request()->date('_form.end_date');
 
FormBuilder::make()
    ->dispatchEvent(AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'metrics'))
    ->fields([
        Flex::make([
            Date::make('Start date'),
            Date::make('End date'),
        ]),
    ]),
 
Fragment::make([
    FlexibleRender::make("$startDate - $endDate"),
 
    LineChartMetric::make('Orders')
        ->line([
            'Profit' => Order::query()
                ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->pluck('sum', 'date')
                ->toArray(),
        ])
        ->line([
            'Avg' => Order::query()
                ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                -> pluck('avg', 'date')
                ->toArray(),
        ], '#EC4176'),
])->name('metrics'),
$startDate = request()->date('_form.start_date');
$endDate = request()->date('_form.end_date');
FormBuilder::make()
    ->dispatchEvent(AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'metrics'))
    ->fields([
        Flex::make([
            Date::make('Start date'),
            Date::make('End date'),
        ]),
    ]),
Fragment::make([
    FlexibleRender::make("$startDate - $endDate"),
    LineChartMetric::make('Orders')
        ->line([
            'Profit' => Order::query()
                ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->pluck('sum', 'date')
                ->toArray(),
        ])
        ->line([
            'Avg' => Order::query()
                ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                -> pluck('avg', 'date')
                ->toArray(),
        ], '#EC4176'),
])->name('metrics'),
$startDate = request()->date('_form.start_date');
$endDate = request()->date('_form.end_date');
 
FormBuilder::make()
    ->dispatchEvent(AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'metrics'))
    ->fields([
        Flex::make([
            Date::make('Start date'),
            Date::make('End date'),
        ]),
    ]),
 
Fragment::make([
    FlexibleRender::make("$startDate - $endDate"),
 
    LineChartMetric::make('Orders')
        ->line([
            'Profit' => Order::query()
                ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->pluck('sum', 'date')
                ->toArray(),
        ])
        ->line([
            'Avg' => Order::query()
                ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                -> pluck('avg', 'date')
                ->toArray(),
        ], '#EC4176'),
])->name('metrics'),
$startDate = request()->date('_form.start_date');
$endDate = request()->date('_form.end_date');
FormBuilder::make()
    ->dispatchEvent(AlpineJs::event(JsEvent::FRAGMENT_UPDATED, 'metrics'))
    ->fields([
        Flex::make([
            Date::make('Start date'),
            Date::make('End date'),
        ]),
    ]),
Fragment::make([
    FlexibleRender::make("$startDate - $endDate"),
    LineChartMetric::make('Orders')
        ->line([
            'Profit' => Order::query()
                ->selectRaw('SUM(price) as sum, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                ->pluck('sum', 'date')
                ->toArray(),
        ])
        ->line([
            'Avg' => Order::query()
                ->selectRaw('AVG(price) as avg, DATE_FORMAT(created_at, "%d.%m.%Y") as date')
                ->whereBetween('created_at', [$startDate, $endDate])
                ->groupBy('date')
                -> pluck('avg', 'date')
                ->toArray(),
        ], '#EC4176'),
])->name('metrics'),