When i make a form component reactive, it crashes

DateTimePicker::make('publish_date')->required()->default(now())->reactive()->afterStateUpdated(function (\Closure $set, $state) {
$newPublishDate = \Illuminate\Support\Carbon::createfromFormat("Y-m-d H:i:s", $state);

$this->isPublished = $newPublishDate < now();
}),
DateTimePicker::make('publish_date')->required()->default(now())->reactive()->afterStateUpdated(function (\Closure $set, $state) {
$newPublishDate = \Illuminate\Support\Carbon::createfromFormat("Y-m-d H:i:s", $state);

$this->isPublished = $newPublishDate < now();
}),
When the user changes the date in the picker, it crashes, and the form stops working:
48 Replies
ericmp #2
ericmp #2OP17mo ago
toeknee
toeknee17mo ago
where have you placed that DateTimePicker?
ericmp #2
ericmp #2OP17mo ago
inside here:
protected function getFormSchema(): array
{
return [
// here
...
protected function getFormSchema(): array
{
return [
// here
...
toeknee
toeknee17mo ago
And how have you rendered the page?
ericmp #2
ericmp #2OP17mo ago
return view ('name of the view')->layout(layout::class) wdym
toeknee
toeknee17mo ago
Ok what are you using in the layout view ? i.e. do you have the primary div
ericmp #2
ericmp #2OP17mo ago
yes, all wrapped in a div ive discovered that also happens when i submit the form
public function save(): void
{
$this->notice->update($this->form->getState());

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
public function save(): void
{
$this->notice->update($this->form->getState());

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
<form
wire:submit.prevent="save"
>
{{ $this->form }}

... button type submit
<form
wire:submit.prevent="save"
>
{{ $this->form }}

... button type submit
toeknee
toeknee17mo ago
I assume this is a custom livewire component and page outside of the filament panel?
ericmp #2
ericmp #2OP17mo ago
i havent installed admin panel only forms ,, notifications & tables
toeknee
toeknee17mo ago
Ok, so you need to ensure livewire is loaded, ideally in the head before the forms and components are. Also livewire components need to be wrapped i.e.
<div>
{{ $this->form }}

<form
wire:submit.prevent="save"
>
... button type submit
</div>
<div>
{{ $this->form }}

<form
wire:submit.prevent="save"
>
... button type submit
</div>
ericmp #2
ericmp #2OP17mo ago
i said all is inside a div
toeknee
toeknee17mo ago
You said, but your code showed otherwise. If providing snippets it's not helpful as it's a guessing game wihtout all the code as clearly you have a mistake somewhere.
ericmp #2
ericmp #2OP17mo ago
in all other pages it works, livewire is loaded
toeknee
toeknee17mo ago
Livewire can work loaded last and first, but that's not the issue the issue is the componetns are being triggered possibly before livewire is loaded.
ericmp #2
ericmp #2OP17mo ago
why i clearly have a mistake? cant be a bug?
toeknee
toeknee17mo ago
So it's best to load it first. It is extremely unlikely to be a bug.
ericmp #2
ericmp #2OP17mo ago
not the first time i found bugs in filamentphp
toeknee
toeknee17mo ago
Ok, bye.
ericmp #2
ericmp #2OP17mo ago
but yeah what? lol
toeknee
toeknee17mo ago
We are here offering help for free, if you're just going to argue opposed to listening and checking/providing code as per the #❓┊help then we will focus our time on people looking for help. Your implementation sounds very standard and unlikely to be a bug.
ericmp #2
ericmp #2OP17mo ago
and that is the weird thing. i checked my code and compared it with other forms i have, and i cant understand what is going on i was just answering, not arguing opposed messages are only messages, depends on u how u read them. didnt mean to be agressive or something
toeknee
toeknee17mo ago
Have you use the datetimepicker in other views?
ericmp #2
ericmp #2OP17mo ago
yes but i think is something related when the component refreshes as i did reactive there, when changing it, it refreshed. so then crashed that is why then i said that when savig also crashes, cuz it refreshes the component if something is unclear just let me know ill try to explain it better
toeknee
toeknee17mo ago
But you are jsut using reactive to refresh correct?
ericmp #2
ericmp #2OP17mo ago
im using reactive there to get the new date and change a components variable depending on the date chosen
awcodes
awcodes17mo ago
Can we see the whole livewire component blade. Based on what you posted you form isn’t even inside the form tags. I’m thinking you are missing a tag somewhere that is breaking livewires dom diffing.
toeknee
toeknee17mo ago
This could be because you are adjusting the public properties outside of the livewire form. $this->isPublished try: $set('isPublished', true) as an example
ericmp #2
ericmp #2OP17mo ago
ill try that, but id like to change the public property of my livewire component, not to create a new field in the form 1 sec
toeknee
toeknee17mo ago
The way livewire works is it registers the properties and mounts them, when they change outside it causes all sorts of issues as they don't match up with what has been registered as I understand it. so you would tend to set it, maybe traverse outside of the form: $set('../isPublished', true)
LeandroFerreira
LeandroFerreira17mo ago
is there a mount method?
public function mount(): void
{
$this->form->fill();
}
public function mount(): void
{
$this->form->fill();
}
ericmp #2
ericmp #2OP17mo ago
yep
public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}
public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}
is an edit-only form, not create okay i removed all other stuff not related to the error. i event only need a form field to make it crash. Component:
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
view:
<div>
{{ $this->form }}
<button type="button" wire:click="submit">submit</button>
</div>
<div>
{{ $this->form }}
<button type="button" wire:click="submit">submit</button>
</div>
ericmp #2
ericmp #2OP17mo ago
when i submit:
ericmp #2
ericmp #2OP17mo ago
wdym inside the form tags? ah i understand, u mean the html tags> no, i do have them, but for the example i wrote it fast. next time ill write it fine, without the ... just did put ... to say that i skip parts, but yeah that wasnt clear sorry
awcodes
awcodes17mo ago
I understood that. But you showed {{ $this->form }} above your opening form tag. 🙂
ericmp #2
ericmp #2OP17mo ago
fack, sorry let me edit it anyways, for the new example im not using form, just button wireclick
LeandroFerreira
LeandroFerreira17mo ago
can you share the layout code?
awcodes
awcodes17mo ago
Based on what you’ve shown I’m not sure. Typically that error gets thrown due to dom diffing issue. Alpine is loosing track of the livewire component.
ericmp #2
ericmp #2OP17mo ago
too big, what do u need to know about it? if it is useful to u, in other views i have using same layout, forms & tables work just fine
awcodes
awcodes17mo ago
If you put the picker in another form that is working, does it break.?
ericmp #2
ericmp #2OP17mo ago
it doesnt the datepicker is, lets say, the way i found the error but not the error itself here
LeandroFerreira
LeandroFerreira17mo ago
if you dont want to declare all properties, you need to use
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
or
public bool $isPublished;
public string $title;
public bool $isPublished;
public string $title;
ericmp #2
ericmp #2OP17mo ago
isPublished is not a property of the model is just a boolean i created. the property would be publish_date ill try that anyways
LeandroFerreira
LeandroFerreira17mo ago
you have TextInput::make('title) but it isnt declared you should do public string $title;
ericmp #2
ericmp #2OP17mo ago
just did it. i added public string $title;. but im getting exact same error :/
LeandroFerreira
LeandroFerreira17mo ago
did you try it?
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
public $data;
protected function getFormStatePath(): string
{
return 'data';
}
because if you have a title in the form, you should do this:
$this->form->fill([
'title' => $notice->title
]);
$this->form->fill([
'title' => $notice->title
]);
if you are passing all fields, you need to declare or use $data
ericmp #2
ericmp #2OP17mo ago
i added this:
public $data;

protected function getFormStatePath(): string
{
return 'data';
}
public $data;

protected function getFormStatePath(): string
{
return 'data';
}
now works!!!! leandro, thanks!!! and thanks y'all appreciete ur time 🙏
LeandroFerreira
LeandroFerreira17mo ago
Nice.. you can do this: $this->form->fill($this->notice->toArray()); But you need to declare all properties or forget it and use $data
ericmp #2
ericmp #2OP17mo ago
final code:
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public $data;

protected function getFormStatePath(): string
{
return 'data';
}

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
class NoticesForm extends Component implements Forms\Contracts\HasForms
{
use Forms\Concerns\InteractsWithForms;

public Notice $notice;

/**
* True if the notice is published.
*/
public bool $isPublished;

public $data;

protected function getFormStatePath(): string
{
return 'data';
}

public function render()
{
return view('livewire.forms.notices-form')
->layout('mylayout');
}

public function mount(Notice $notice): void
{
$this->notice = $notice;

$this->isPublished = $this->notice->publish_date < now();

$this->form->fill($this->notice->toArray());
}

protected function getFormSchema(): array
{
return [
TextInput::make('title')->required()->maxLength(255),
];
}

protected function getFormModel(): Notice
{
return $this->notice;
}

public function submit(): void
{
$this->notice->update($this->form->getState());

$this->form->model($this->notice)->saveRelationships();

Notification::make()
->title(__('Éxito'))
->icon('heroicon-o-check')
->iconColor('success')
->send()
;
}
}
Want results from more Discord servers?
Add your server