From af2f97e56e74c1a945a37ed72a6ff92c9d1af8b0 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 18 Jun 2024 15:36:13 -0300 Subject: [PATCH] fix: avisar antes de salir si hubo cambios en el formulario --- .../controllers/unsaved_changes_controller.js | 45 +++++++++++++++++++ app/views/posts/_form.haml | 2 +- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 app/javascript/controllers/unsaved_changes_controller.js diff --git a/app/javascript/controllers/unsaved_changes_controller.js b/app/javascript/controllers/unsaved_changes_controller.js new file mode 100644 index 00000000..04b80f56 --- /dev/null +++ b/app/javascript/controllers/unsaved_changes_controller.js @@ -0,0 +1,45 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + connect() { + this.originalFormData = new FormData(this.element); + this.originalFormDataSerialized = this.serializeFormData(this.originalFormData); + this.submitting = false; + } + + submit(event) { + this.submitting = true; + } + + unsaved(event) { + if (this.submitting) return; + if (!this.hasChanged()) return; + + this.submitting = false; + + event.preventDefault(); + + event.returnValue = true; + } + + unsavedTurbolinks(event) { + if (this.submitting) return; + if (!this.hasChanged()) return; + + this.submitting = false; + + if (window.confirm(this.element.dataset.unsavedChangesConfirmValue)) return; + + event.preventDefault(); + } + + serializeFormData(formData) { + formData.delete("authenticity_token"); + + return (new URLSearchParams(formData)).toString();; + } + + hasChanged() { + return (this.originalFormDataSerialized !== this.serializeFormData(new FormData(this.element))); + } +} diff --git a/app/views/posts/_form.haml b/app/views/posts/_form.haml index 8c006274..8a86d203 100644 --- a/app/views/posts/_form.haml +++ b/app/views/posts/_form.haml @@ -33,7 +33,7 @@ - dir = t("locales.#{@locale}.dir") -# Comienza el formulario -= form_tag url, method: method, class: "form post #{extra_class}", multipart: true do += form_tag url, method: method, class: "form post #{extra_class}", multipart: true, data: { controller: 'unsaved-changes', action: 'unsaved-changes#submit beforeunload@window->unsaved-changes#unsaved turbolinks:before-visit@window->unsaved-changes#unsavedTurbolinks', 'unsaved-changes-confirm-value': t('.confirm') } do -# Botones de guardado = render 'posts/submit', site: site, post: post diff --git a/config/locales/en.yml b/config/locales/en.yml index 457b7927..94a6968a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -814,6 +814,7 @@ en: destroy: Delete confirm_destroy: Are you sure? form: + confirm: "You have unsaved changes and changing pages may lose them, continue anyway?" errors: title: There are some errors on the form help: Please, verify that all values are correct. diff --git a/config/locales/es.yml b/config/locales/es.yml index d149dee8..fcaa6658 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -822,6 +822,7 @@ es: destroy: Borrar confirm_destroy: ¿Estás segure? form: + confirm: "Tenés cambios sin guardar y cambiar de página podría perderlos, ¿querés continuar de todas formas?" errors: title: Hay errores en el formulario help: Por favor, verifica que todos los valores sean correctos.