diff --git a/src/app/Library/CrudPanel/CrudPanel.php b/src/app/Library/CrudPanel/CrudPanel.php index cafdd704df..16530202fb 100644 --- a/src/app/Library/CrudPanel/CrudPanel.php +++ b/src/app/Library/CrudPanel/CrudPanel.php @@ -28,6 +28,7 @@ use Backpack\CRUD\app\Library\CrudPanel\Traits\Update; use Backpack\CRUD\app\Library\CrudPanel\Traits\Validation; use Backpack\CRUD\app\Library\CrudPanel\Traits\Views; +use Backpack\CRUD\app\Library\CrudPanel\Traits\WarnBeforeLeaving; use Exception; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; @@ -37,7 +38,7 @@ class CrudPanel { // load all the default CrudPanel features - use Create, Read, Search, Update, Delete, Errors, Reorder, Access, Columns, Fields, Query, Buttons, AutoSet, FakeFields, FakeColumns, AutoFocus, Filters, Tabs, Views, Validation, HeadingsAndTitles, Operations, SaveActions, Settings, Relationships; + use Create, Read, Search, Update, Delete, Errors, Reorder, Access, Columns, Fields, Query, Buttons, AutoSet, FakeFields, FakeColumns, AutoFocus, Filters, Tabs, Views, Validation, HeadingsAndTitles, Operations, SaveActions, Settings, Relationships, WarnBeforeLeaving; // allow developers to add their own closures to this object use Macroable; diff --git a/src/app/Library/CrudPanel/Traits/WarnBeforeLeaving.php b/src/app/Library/CrudPanel/Traits/WarnBeforeLeaving.php new file mode 100644 index 0000000000..bc3aa236aa --- /dev/null +++ b/src/app/Library/CrudPanel/Traits/WarnBeforeLeaving.php @@ -0,0 +1,27 @@ +getOperationSetting('warnBeforeLeaving') ?? config('backpack.crud.operations.'.$this->getCurrentOperation().'.warnBeforeLeaving') ?? false; + } + + /** + * Change the variable that determines if user should be warned before leaving the page. + * + * @param bool $value + * @return void + */ + public function setWarnBeforeLeaving(bool $value = true): void + { + $this->setOperationSetting('warnBeforeLeaving', $value); + } +} diff --git a/src/config/backpack/crud.php b/src/config/backpack/crud.php index fc14ff899e..8b62ddc158 100644 --- a/src/config/backpack/crud.php +++ b/src/config/backpack/crud.php @@ -93,6 +93,9 @@ // Should we show a cancel button to the user? 'showCancelButton' => true, + // Should we warn a user before leaving the page with unsaved changes? + 'warnBeforeLeaving' => false, + // Before saving the entry, how would you like the request to be stripped? // - false - ONLY save inputs that have fields (safest) // - [x, y, z] - save ALL inputs, EXCEPT the ones given in this array @@ -129,6 +132,9 @@ // Should we show a cancel button to the user? 'showCancelButton' => true, + // Should we warn a user before leaving the page with unsaved changes? + 'warnBeforeLeaving' => false, + // Before saving the entry, how would you like the request to be stripped? // - false - Save ONLY inputs that have a field (safest, default); // - [x, y, z] - Save ALL inputs, EXCEPT the ones given in this array; diff --git a/src/resources/views/crud/form_content.blade.php b/src/resources/views/crud/form_content.blade.php index 1c533a2961..230b738037 100644 --- a/src/resources/views/crud/form_content.blade.php +++ b/src/resources/views/crud/form_content.blade.php @@ -58,6 +58,25 @@ function initializeFieldsWithJavascript(container) { // trigger the javascript for all fields that have their js defined in a separate method initializeFieldsWithJavascript('form'); + // Retrieves the current form data + function getFormData() { + return new URLSearchParams(new FormData(document.querySelector("main form"))).toString(); + } + + // Prevents unloading of page if form data was changed + function preventUnload(event) { + if (initData !== getFormData()) { + // Cancel the event as stated by the standard. + event.preventDefault(); + // Older browsers supported custom message + event.returnValue = ''; + } + } + + @if($crud->getWarnBeforeLeaving()) + const initData = getFormData(); + window.addEventListener('beforeunload', preventUnload); + @endif // Save button has multiple actions: save and exit, save and edit, save and new var saveActions = $('#saveActions'), @@ -83,6 +102,7 @@ function initializeFieldsWithJavascript(container) { // prevent duplicate entries on double-clicking the submit form crudForm.submit(function (event) { + window.removeEventListener('beforeunload', preventUnload); $("button[type=submit]").prop('disabled', true); });