La forma en que he hecho esto es usar javascript para almacenar los valores iniciales de las entradas cuando se carga la página. Luego tengo un controlador de descarga previa que verifica si alguna de las entradas tiene un valor diferente de cuando se cargó la página. Si se modifican las entradas, solicita al usuario que confirme que quiere abandonar la página, cancelando la acción si cancelan. En mi lógica de envío, establezco un indicador que impide que la verificación de la carga previa ocurra, por lo que un envío no recibe el aviso.
Sospecho que hay un complemento jQuery para hacer esto, pero no lo he implementado desde que comencé a usar jQuery. Mi código anterior usó Prototype.
Editar: No se pudo encontrar un complemento jQuery, pero podría haberlo perdido. Aquí hay una muestra de cómo podría hacerlo. Obviamente, hay más que se puede hacer. Tenga en cuenta que no pude hacer que funcione con jQuery puro - no estoy seguro exactamente por qué, la ventana emergente aparecería dos veces.
Esto debería funcionar con todos los elementos de entrada. Sin embargo, es posible que desee cambiarlo para ignorar/manejar los botones. Solo lo ajusté para ignorar un botón de enviar (para que pueda publicar de nuevo sin la ventana emergente). Si otros tipos de botones pueden causar la descarga de una página, es posible que deba abordar eso.
var CheckOnClose = function() {
this.initialize();
}
CheckOnClose.prototype = {
submitting: false,
initialize: function() {
var that = this;
window.onbeforeunload = function() { return that.checkLeavePage(); }
},
isChanged: function() {
var changed = false;
$('input:not(:submit)').each(function() {
var iv = $(this).data('initialValue');
if ($(this).val() != iv) {
changed = true;
return false;
}
});
return changed;
},
setSubmitting: function() {
this.submitting = true;
},
checkLeavePage: function() {
if (!this.submitting && this.isChanged()) {
return 'You have some unsaved changes.';
}
}
}
var checker = new CheckOnClose();
$(document).ready(function() {
$(':input:not(:submit)').each(function() {
$(this).data('initialValue',$(this).val());
});
$(':submit').click(function() {
checker.setSubmitting();
});
});
Por supuesto, también se pueden usar jQuery/Prototype/otras bibliotecas, pero la implementación básica es tan simple como el fragmento de arriba. – synhershko