¿Cuál es la forma más fácil de detectar si se ha cambiado al menos un campo en un formulario HTML?

Tengo un formulario HTML con más de 20 campos. También tengo un par de enlaces en la página que alejarán al usuario del formulario … potencialmente sin haber guardado ningún cambio.

Quiero advertir (JS confirme) al usuario enHaga clic en estos enlaces si alguno de los campos del formulario ha cambiado, pero no quiero crear una gran statement de cambio que deba mantener a medida que añada nuevos campos al formulario. Sé cómo crear una larga lista de declaraciones ‘if’ en Javascript, nombrando cada uno de los campos y comprobando cada valor, pero no quiero hacer eso si puedo salirse con la suya.

¿Cuál es la forma más fácil de verificar si el usuario ha cambiado al menos uno de los valores de campo?

Enfoque

  1. serializar la forma (y todos sus valores) antes de mostrarla ( jQuery way , Prototype way )
  2. volver a serializarlo en un controlador de eventos "onbeforeunload"

Si los dos no coinciden, entonces deben haber cambiado el formulario, así que devuelve una cadena (por ejemplo, “Tienes datos no guardados”) de tu controlador onbeforeunload .

Este método permite que los campos de formulario evolucionen mientras que la lógica “confirmar si cambió” sigue siendo la misma.

Ejemplo (javascript y jquery mixtos)

 var form_clean; // serialize clean form $(function() { form_clean = $("form").serialize(); }); // compare clean and dirty form before leaving window.onbeforeunload = function (e) { var form_dirty = $("form").serialize(); if(form_clean != form_dirty) { return 'There is unsaved form data.'; } }; 

Estoy bastante seguro de que esta es una mala idea, pero quería tirarlo allí.

Los campos de formulario tienen una forma de obtener el “valor predeterminado” (es decir, el valor que tenía el campo cuando se cargó), y puede compararlo con el valor actual. Un bucle simple en todos los campos elimina la necesidad de mantenimiento si agrega campos al formulario.

Puede haber o no varios errores del navegador asociados con las propiedades del “valor predeterminado”, por lo que no confiaría en este método sin realizar pruebas exhaustivas. El siguiente código es una prueba de concepto, y no lo utilizo (yo) en ninguna aplicación real.

 function IsDirty(form) { for (var i=0; i 

Usar jQuery es muy fácil. Debería poder utilizar la misma premisa para lograr el mismo resultado en vainilla javascript también.

 var $inps = $('#myForm').find('input,select,textarea') , formAltered = false ; $inps.change(function() { formAltered = true; $inps.unbind('change'); // saves this function running every time. }); 

El único problema con esto es que si cambia un valor y luego lo vuelve a cambiar al original, seguirá informando que el formulario está alterado.

Aquí hay un trazador de líneas que puede agregar a sus formularios:

 $(':input',document.myForm).bind("change", function() { enablePrompt(true); }); // Prevent accidental navigation away 

Y luego puede hacer que la función enableUnloadPrompt () para todo su sitio:

 function enablePrompt(enabled) { window.onbeforeunload = enabled ? "Your changes are not saved!" : null; } 

Y finalmente, antes de enviar el formulario correctamente, asegúrese de:

 enablePrompt(false); 

Esto no verificará si el formulario tiene valores diferentes, solo si el usuario alguna vez cambió el formulario. Pero, es simple y fácil de usar.

Esto podría manejarse con solo una variable booleana, lo llamamos manipulación de bit sucio. Si ha observado, generalmente en páginas web, una vez que el usuario realiza alguna acción de edición en cualquiera de los campos, el formulario se considera sucio (editado) (incluso si los datos permanecen sin cambios después de la edición). Cuando el usuario intenta navegar fuera de la página, se le solicita al usuario si desea guardar los cambios.

De acuerdo con la práctica estándar, no hay verificación si después de editar algún campo si el valor realmente cambió o no. Por ejemplo: si el usuario edita y agrega ‘xyz’ a un campo de texto y luego borra ‘xyz’ esencialmente los datos del formulario siguen siendo los mismos que antes, pero el formulario todavía se considera ‘sucio’ y el usuario recibe un mensaje de advertencia cuando intenta alejarse

Entonces, si quieres implementar esto, las cosas se vuelven bastante simples. Simplemente necesitaría agregar los manejadores de eventos change () a los controles y establecer la variable booleana global algo así como “dirty” en “true” dentro de esos eventhandlers.

Una vez que el usuario quiere navegar, puede mostrar un mensaje “Puede haber cambios no guardados en la página actual. ¿Desea guardarlos?”. El usuario no se decepcionará, incluso si nota que su edición no cambió los datos iniciales.

Las respuestas dadas anteriormente implementan este mismo comportamiento. Y escribí esto porque parecía tener una idea para verificar cada campo por su valor inicial para ver si realmente se modificó después de la edición. Solo quería decirte que revisar todos los campos no es necesario en absoluto.