Show a warning before leaving page when you have filled in a form (save/discard changes)

I have a large form where the save button is far down, sometimes people forget to press it and leave that page. Whatever they have filled in will be lost.. Is there any way to give a warning before leaving the page if there has been a field filled in.. I cannot find something in the docs
Solution:
GitHub
Wait, don't leave! · Issue #9992 · filamentphp/filament
Alert the user if they have unsaved changes in a form.
Jump to solution
50 Replies
Jordy
JordyOP2y ago
I have experimented with saving ->afterStateUpdated() but that will impact performance in live (not worth it)
Dennis Koch
Dennis Koch2y ago
I tried the same but didn’t find a proper solution. Alpine/LW tracks your dirty state but I don’t think you have access to that. Would be the ideal solution.
Jordy
JordyOP2y ago
I see.. wont waste more time on it then lol Thank you for the reply anyway :)
awcodes
awcodes2y ago
There is an option to make the footer sticky on the page too. That way the form actions would always be visible and the user wouldn’t have to scroll to the bottom of the page.
Andrew Wallo
Andrew Wallo2y ago
I guess you can always have a save action for each form section on a page right?
Jordy
JordyOP2y ago
that sucks :P I went with aw's idea for now haha
Andrew Wallo
Andrew Wallo2y ago
In my opinion I actually think that would be better design for a long form but oh well
Jordy
JordyOP2y ago
yes.. but it will likely cause users to press save... for each section
Andrew Wallo
Andrew Wallo2y ago
Do your users usually have to edit every field on a long form each time they go to it?
Jordy
JordyOP2y ago
no, but we use it for project management.. the form doubles for an information overview of the project :) when the project is created all fields are filled in
Andrew Wallo
Andrew Wallo2y ago
Alright well for your use case then sure
josef
josef2y ago
There is?
Jordy
JordyOP2y ago
I wrapped the button in a sticky div.. nothing fancy

<div class="sticky bottom-0">
<x-filament::button type="submit" form="save" icon="heroicon-o-check">
Opslaan
</x-filament::button>
</div>

<div class="sticky bottom-0">
<x-filament::button type="submit" form="save" icon="heroicon-o-check">
Opslaan
</x-filament::button>
</div>
josef
josef2y ago
I see, so you overwrote a core template to do this? Or is it form builder standalone without panel?
Jordy
JordyOP2y ago
Location shouldnt matter? forms render without a save button.. just make the button you are using sticky.. I am using the filament button to match the design
josef
josef2y ago
Well, the save button for resources in the panels get created by filament, not by me, so I'd have to adapt a core template to make it sticky I think there's a plugin to make the header sticky, but not the footer with the save and cancel buttons
Jordy
JordyOP2y ago
I am on v2.. have not used v3 yet so dunno about panels soon xd
josef
josef2y ago
v2 has resources as well, but I guess you use custom forms outside the resources. Thanks anyway, it's a nice solution for that case. Would still be great to have a 'you have unsaved changes' notice somehow 😄
Jordy
JordyOP2y ago
read up in #👹┊off-topic , Dan said a PR would be welcome.. just no clue how it would be done haha
Dennis Koch
Dennis Koch2y ago
I think sticky footer is built into v3. Don’t know the API though.
josef
josef2y ago
Only for modals, I think
awcodes
awcodes2y ago
public static bool $formActionsAreSticky = false; not sure it's in the docs that just goes on the Page (create / edit)
gon.exe
gon.exe2y ago
Hi guys. Very interesting conversation. I have the same need. Prevent users from leaving the form by displaying an alert message or something similar. This is for v3. Right?
awcodes
awcodes2y ago
yes. it was also in v2 it's scroll based though so you won't see any affect unless your page it long enough to force a scroll
Jordy
JordyOP2y ago
If you find something.. let us know 😂
gon.exe
gon.exe2y ago
So is not working for me. I added the code on my create page
awcodes
awcodes2y ago
Working in the demo. Maybe you have cached views
No description
awcodes
awcodes2y ago
you also have to scroll the page for it to show up
josef
josef2y ago
It is most certainly not but also doesnt work for me either
awcodes
awcodes2y ago
yea, i tried looking for it it's working in the demo make sure you're adding it to CreateRecord and EditRecord it doesn't work on RecordResource
josef
josef2y ago
yeah, it's on the edit page, and there's the corresponding alpine and css in the page source now But it's just not sticky 🤨
awcodes
awcodes2y ago
not sure what to tell you. lol. maybe a plugin conflict with styles. ?
gon.exe
gon.exe2y ago
I tried "php artisan optimize:clear" but it still doesn't work
class CreateContract extends CreateRecord
{

public static bool $formActionsAreSticky = false;
class CreateContract extends CreateRecord
{

public static bool $formActionsAreSticky = false;
also tried on "true" value
josef
josef2y ago
No plugins right now. Maybe something else broke. Don't know if the demo always has the latest version. Anyways, that's not really a priority right now
toeknee
toeknee2y ago
Something like this should work to prevent the redirect:
<div x-data="{ isFormFilled: false }"
x-init="window.addEventListener('beforeunload', function (e) {
if (isFormFilled) {
e.preventDefault();
e.returnValue = '';
}
});"
>
<form wire:submit.prevent="submit" x-on:input="isFormFilled = true">
<!-- Your form fields here -->
<input type="text" wire:model="name">
<button type="submit">Submit</button>
</form>
</div>
<div x-data="{ isFormFilled: false }"
x-init="window.addEventListener('beforeunload', function (e) {
if (isFormFilled) {
e.preventDefault();
e.returnValue = '';
}
});"
>
<form wire:submit.prevent="submit" x-on:input="isFormFilled = true">
<!-- Your form fields here -->
<input type="text" wire:model="name">
<button type="submit">Submit</button>
</form>
</div>
And integrate it natively with Forms ?
awcodes
awcodes2y ago
Running 3.0.16 on my local version of the demo.
No description
gon.exe
gon.exe2y ago
does not work for me: resources\views\livewire\create-purchase-order-using-purchase-requisition.blade.php
<div>
<div x-data="{ isFormFilled: false }"
x-init="window.addEventListener('beforeunload', function (e) {
if (isFormFilled) {
e.preventDefault();
e.returnValue = '';
}
});"
>

<form wire:submit.prevent="submit" x-on:input="isFormFilled = true">

{{ $this->form }}

<br>

<div class="filament-page-actions flex flex-wrap items-center gap-4 justify-start filament-form-actions sticky bottom-0">

<x-filament::button type="submit">
@php
echo __('Create')
@endphp
</x-filament::button>

<a
class="filament-button filament-button-size-md inline-flex items-center justify-center py-1 gap-1 font-medium rounded-lg border transition-colors outline-none focus:ring-offset-2 focus:ring-2 focus:ring-inset dark:focus:ring-offset-0 min-h-[2.25rem] px-4 text-sm text-gray-800 bg-white border-gray-300 hover:bg-gray-50 focus:ring-primary-600 focus:text-primary-600 focus:bg-primary-50 focus:border-primary-600 dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-500 dark:text-gray-200 dark:focus:text-primary-400 dark:focus:border-primary-400 dark:focus:bg-gray-800 filament-page-button-action"
href="http://127.0.0.1:8000/admin/contratos"
dusk="filament.admin.action.cancel
">

<span class="">
@php
echo __('Cancel')
@endphp
</span>

</a>

</div>

</form>

</div>
<div>
<div x-data="{ isFormFilled: false }"
x-init="window.addEventListener('beforeunload', function (e) {
if (isFormFilled) {
e.preventDefault();
e.returnValue = '';
}
});"
>

<form wire:submit.prevent="submit" x-on:input="isFormFilled = true">

{{ $this->form }}

<br>

<div class="filament-page-actions flex flex-wrap items-center gap-4 justify-start filament-form-actions sticky bottom-0">

<x-filament::button type="submit">
@php
echo __('Create')
@endphp
</x-filament::button>

<a
class="filament-button filament-button-size-md inline-flex items-center justify-center py-1 gap-1 font-medium rounded-lg border transition-colors outline-none focus:ring-offset-2 focus:ring-2 focus:ring-inset dark:focus:ring-offset-0 min-h-[2.25rem] px-4 text-sm text-gray-800 bg-white border-gray-300 hover:bg-gray-50 focus:ring-primary-600 focus:text-primary-600 focus:bg-primary-50 focus:border-primary-600 dark:bg-gray-800 dark:hover:bg-gray-700 dark:border-gray-600 dark:hover:border-gray-500 dark:text-gray-200 dark:focus:text-primary-400 dark:focus:border-primary-400 dark:focus:bg-gray-800 filament-page-button-action"
href="http://127.0.0.1:8000/admin/contratos"
dusk="filament.admin.action.cancel
">

<span class="">
@php
echo __('Cancel')
@endphp
</span>

</a>

</div>

</form>

</div>
What is the command to see that information?
toeknee
toeknee2y ago
No it wouldn't because you have doubled up the form. php artisan about
gon.exe
gon.exe2y ago
thanks
No description
gon.exe
gon.exe2y ago
Do you mean the declaration of <form> and {{ $this->form }} ?
Dennis Koch
Dennis Koch2y ago
Do forms have input events at all?
Jordy
JordyOP16mo ago
Anyone has made any progress/ideas on this? Otherwise I will give up and mark it as too much effort to implement haha Im fine if it means writing something custom with alpine I just have no clue where I would put the code with beforeunload
Saade
Saade16mo ago
hey Josef, did you find a solution for this? can't get it to work i think something got broken between versions, its not working on the demo anymore hmm actually the check to wether it should stick or not, is a bit wrong, only works on small height screens (can be simulated by opening the devtools on the bottom of the page) gonna PR a fix for it
EdmerKun
EdmerKun14mo ago
Does anyone found a solution for this? like a warning for the user before they leave?
Saade
Saade14mo ago
@Dennis is working on something i guess (please dont go bother he asking when it will be released)
Jordy
JordyOP14mo ago
awesome, cant wait
Solution
EdmerKun
EdmerKun13mo ago
GitHub
Wait, don't leave! · Issue #9992 · filamentphp/filament
Alert the user if they have unsaved changes in a form.
DrByte
DrByte13mo ago
Dude. You just copy/pasted someone else's response in another thread ... and pretended it's your own! Please get off this Discord server. Stop spamming in every thread.
No description
No description
No description
Dennis Koch
Dennis Koch13mo ago
Banned him.
Jordy
JordyOP13mo ago
☠️ legendary but yes, I think this thread is solved and I will follow the development of this issue

Did you find this page helpful?