Using a custom component in a Form

Hi - I think I've overlooked something here. I am creating a livewire-component to show an overview, which is then polled every 10 seconds. So I made a new component via php artisan make:livewire mycomponentand now I wanna use that within getFormSchema() inside a section, but it does not have the usual ::make() function, which all FilamentComponents have. Do I have to define a make-function myself or just use some Trait?
24 Replies
Patrick Boivin
Patrick Boivin17mo ago
You can wrap your Livewire component in a Filament form component. It's not ideal but easy to setup.
public static function form(Form $form): Form
{
return $form->schema([
MyComponentWrapper::make(),

// ...
public static function form(Form $form): Form
{
return $form->schema([
MyComponentWrapper::make(),

// ...
class MyComponentWrapper extends Component
{
protected string $view = 'my-component-wrapper';

// ...
}
class MyComponentWrapper extends Component
{
protected string $view = 'my-component-wrapper';

// ...
}
@livewire('my-component', [ ... ])
@livewire('my-component', [ ... ])
I think you could even use Component::make()->view( ... ) directly, if you don't need to encapsulate anything else in the form component.
awcodes
awcodes17mo ago
just use a ViewField and set ->view('my-component.blade.php') and put <livewire:my-livewire-component/> in that blade file.
Patrick Boivin
Patrick Boivin17mo ago
But the ViewField requires a $name parameter, no?
awcodes
awcodes17mo ago
Sorry, wrong class, you can use the View layout component. View::make('filament.forms.components.wizard') if you don't need schema you don't have to provide it. I don't think.
Husky110
Husky110OP17mo ago
Perfect - Thanks guys! 🙂 I tried your approach, but it ends in the Page not beeing loaded (loading keeps on scrolling there...) view:
<livewire:container-full-status />
<div wire.poll.10s>
{{ $timestamp }}
</div>
<livewire:container-full-status />
<div wire.poll.10s>
{{ $timestamp }}
</div>
Component.php:
<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ContainerFullStatus extends Component
{

public int $timeStamp;

public function mount()
{
$this->timeStamp = now()->getTimestamp();
}

public function render()
{
return view('components.m-components.sysinternals.container-full-status');
}
}
<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ContainerFullStatus extends Component
{

public int $timeStamp;

public function mount()
{
$this->timeStamp = now()->getTimestamp();
}

public function render()
{
return view('components.m-components.sysinternals.container-full-status');
}
}
And I implemented it like this:
Section::make(m__('about.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')
]),
Section::make(m__('about.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')
]),
awcodes
awcodes17mo ago
The wire poll needs to be inside your livewire components view. Not your view layout blade file.
Husky110
Husky110OP17mo ago
Okay - now I am confused... For the page-loading - the render()-function was the problem there... Basically - what I want is a reuseable Livewire-Component... Where the polling does poll the component and not the full page...
awcodes
awcodes17mo ago
Understandable, it’s hard to explain. In your form View::make() points to a blade file. That blade file has nothing in it but the <livewire> directive. That directive loads your livewire component’s blade file that has all you live wire stuff in it. So it’s two Separate files.
Husky110
Husky110OP17mo ago
Ahhhhhh - okay, I think I get what are you are saying! One second! 😁
awcodes
awcodes17mo ago
Basically you can’t load a livewire component directly in a form.
Husky110
Husky110OP17mo ago
Okay. I moved the components view-file so it looks like this:
<div>
{{ $timestamp }}
</div>
<div>
{{ $timestamp }}
</div>
But now it tells me Undefined variable $timestamp... o.O shouldn't the mount-function define it?
awcodes
awcodes17mo ago
wait. what are you trying to do exactly? is the timestamp a field on the record?
Husky110
Husky110OP17mo ago
Nope - right now it's just a variable for me to test that polling works. 🙂 Okay - one step back. Right now it looks like this: Form-Page:
Section::make(m__('aboutmyapp.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')
]),
Section::make(m__('aboutmyapp.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')
]),
components.my-components.sysinternals.container-full-status looks like this:
<livewire:container-full-status />
<livewire:container-full-status />
the ContainerFullStatus.php like this:

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ContainerFullStatus extends Component
{
public int $timeStamp;

public function mount()
{
$this->timeStamp = now()->getTimestamp();
}

public function render()
{
return view('livewire.container-full-status');
}
}

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class ContainerFullStatus extends Component
{
public int $timeStamp;

public function mount()
{
$this->timeStamp = now()->getTimestamp();
}

public function render()
{
return view('livewire.container-full-status');
}
}
And the livewire.container-full-status has this:
<div>
{{ $timestamp }}
</div>
<div>
{{ $timestamp }}
</div>
awcodes
awcodes17mo ago
try
<div>
{{ $timeStamp }}
</div>
<div>
{{ $timeStamp }}
</div>
Husky110
Husky110OP17mo ago
ah - the classic typo! thanks! 🙂 After that it works, but polling does not. Modified the component-view to
<div wire:poll>
{{ $timestamp }}
</div>
<div wire:poll>
{{ $timestamp }}
</div>
which (according to the livewire-docs) should change timestamp every 2 seconds, but it keeps beeing static. already tried the obligatory filament:upgrade...
Husky110
Husky110OP17mo ago
Livewire
Polling | Livewire
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
awcodes
awcodes17mo ago
mount only runs once when the component is initialized. you'll need to make a method to run on the interval that updates the $timeStamp property wire:poll="updateTimeStamp" something like that
Husky110
Husky110OP17mo ago
okay... kinda weird... I tried it in a view directly before that and it updated the timestamp... huh... the more you know... thank you very much! 🙂 yep - that works. Kinda weird behavior tho that it needs a function, when the docs don't explicitly require one... 🙂
awcodes
awcodes17mo ago
it's probably mentioned somewhere else in the docs. 🙂
Husky110
Husky110OP17mo ago
I thought so aswell... But before that I tried this:
Section::make(m__('about.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')->viewData(['timestamp' => now()->getTimestamp()])
]),
Section::make(m__('about.systemstatus.containerstatus.sectionheadline'))->columnSpan(2)
->schema([
View::make('components.my-components.sysinternals.container-full-status')->viewData(['timestamp' => now()->getTimestamp()])
]),
with components.my-components.sysinternals.container-full-status looking like this:
<div wire:poll="updateTimestamp">
{{ $timestamp }}
</div>
<div wire:poll="updateTimestamp">
{{ $timestamp }}
</div>
And that worked fine - so there was no need to define any function. But like I said - i wanted to poll only the component and not the whole page, so I guess that there is something going on in the background.
awcodes
awcodes17mo ago
yea, the poll on the page in Filament is changing the property, but since you took it out of the "page" context, it needs it's own method for polling
Husky110
Husky110OP17mo ago
ah okay! but I got that right, so that with the custom component and the custom function it only polls the component and not the whole page?
awcodes
awcodes17mo ago
correct
Husky110
Husky110OP17mo ago
thank you very much good sir! 🙂
Want results from more Discord servers?
Add your server